From 3a8e67e8abe3b09d4099cebe91ad5af02a4d8939 Mon Sep 17 00:00:00 2001 From: outfoxxed Date: Tue, 30 Jul 2024 12:19:59 -0700 Subject: [PATCH] core/util: move DropEmitter to utils and add generic accessor macros --- src/core/types.cpp | 19 ----------- src/core/types.hpp | 25 -------------- src/core/util.hpp | 81 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 81 insertions(+), 44 deletions(-) create mode 100644 src/core/util.hpp diff --git a/src/core/types.cpp b/src/core/types.cpp index d9c025fb..5ed63a02 100644 --- a/src/core/types.cpp +++ b/src/core/types.cpp @@ -21,22 +21,3 @@ Qt::Edges Edges::toQt(Edges::Flags edges) { return Qt::Edges(edges.toInt()); } bool Edges::isOpposing(Edges::Flags edges) { return edges.testFlags(Edges::Top | Edges::Bottom) || edges.testFlags(Edges::Left | Edges::Right); } - -DropEmitter::DropEmitter(DropEmitter&& other) noexcept: object(other.object), signal(other.signal) { - other.object = nullptr; -} - -DropEmitter& DropEmitter::operator=(DropEmitter&& other) noexcept { - this->object = other.object; - this->signal = other.signal; - other.object = nullptr; - return *this; -} - -DropEmitter::~DropEmitter() { this->call(); } - -void DropEmitter::call() { - if (!this->object) return; - this->signal(this->object); - this->object = nullptr; -} diff --git a/src/core/types.hpp b/src/core/types.hpp index a23ff085..13fce824 100644 --- a/src/core/types.hpp +++ b/src/core/types.hpp @@ -69,28 +69,3 @@ bool isOpposing(Flags edges); }; // namespace Edges Q_DECLARE_OPERATORS_FOR_FLAGS(Edges::Flags); - -// NOLINTBEGIN -#define DROP_EMIT(object, func) \ - DropEmitter(object, static_cast([](typeof(object) o) { o->func(); })) -// NOLINTEND - -class DropEmitter { -public: - template - DropEmitter(O* object, void (*signal)(O*)) - : object(object) - , signal(*reinterpret_cast(signal)) {} // NOLINT - - DropEmitter() = default; - DropEmitter(DropEmitter&& other) noexcept; - DropEmitter& operator=(DropEmitter&& other) noexcept; - ~DropEmitter(); - Q_DISABLE_COPY(DropEmitter); - - void call(); - -private: - void* object = nullptr; - void (*signal)(void*) = nullptr; -}; diff --git a/src/core/util.hpp b/src/core/util.hpp new file mode 100644 index 00000000..249ab49d --- /dev/null +++ b/src/core/util.hpp @@ -0,0 +1,81 @@ +#pragma once + +// NOLINTBEGIN +#define DROP_EMIT(object, func) \ + DropEmitter(object, static_cast([](typeof(object) o) { o->func(); })) + +#define DROP_EMIT_IF(cond, object, func) (cond) ? DROP_EMIT(object, func) : DropEmitter() + +#define DEFINE_DROP_EMIT_IF(cond, object, func) DropEmitter func = DROP_EMIT_IF(cond, object, func) + +#define DROP_EMIT_SET(object, local, member, signal) \ + auto signal = DropEmitter(); \ + if (local == object->member) { \ + object->member = local; \ + signal = DROP_EMIT(object, signal); \ + } + +// generic accessor declarations + +#define GDECL_GETTER(type, name) [[nodiscard]] type name() const + +#define GDEF_GETTER(class, type, member, name) \ + type class::name() const { return this->member; } + +#define GDECL_SETTER(type, name) DropEmitter name(type value) + +#define GDEF_SETTER(class, type, member, name, signal) \ + DropEmitter class ::name(type value) { \ + if (value == this->member) return DropEmitter(); \ + this->member = value; \ + return DROP_EMIT(this, signal); \ + } + +#define GDECL_MEMBER(type, getter, setter) \ + GDECL_GETTER(type, getter) \ + GDECL_SETTER(type, setter) + +#define GDEF_MEMBER(class, type, member, getter, setter, signal) \ + GDEF_GETTER(class, type, member, getter) \ + GDEF_SETTER(class, type, member, setter, signal) + +#define GDEF_MEMBER_S(class, type, lower, upper) \ + GDEF_MEMBER(class, type, m##upper, lower, set##upper, lower##Changed) + +// NOLINTEND + +class DropEmitter { +public: + Q_DISABLE_COPY(DropEmitter); + template + DropEmitter(O* object, void (*signal)(O*)) + : object(object) + , signal(*reinterpret_cast(signal)) {} // NOLINT + + DropEmitter() = default; + + DropEmitter(DropEmitter&& other) noexcept: object(other.object), signal(other.signal) { + other.object = nullptr; + } + + ~DropEmitter() { this->call(); } + + DropEmitter& operator=(DropEmitter&& other) noexcept { + this->object = other.object; + this->signal = other.signal; + other.object = nullptr; + return *this; + } + + explicit operator bool() const noexcept { return this->object; } + + void call() { + if (!this->object) return; + this->signal(this->object); + this->object = nullptr; + } + +private: + void* object = nullptr; + void (*signal)(void*) = nullptr; +};