11#pragma once
22#include < type_traits>
33
4+ #include < qtclasshelpermacros.h>
5+
46// NOLINTBEGIN
57#define DROP_EMIT (object, func ) \
68 DropEmitter (object, static_cast <void (*)(typeof (object))>([](typeof (object) o) { o->func (); }))
@@ -72,6 +74,8 @@ class DropEmitter {
7274 DECLARE_MEMBER_GET (name); \
7375 DECLARE_MEMBER_SET (name, setter)
7476
77+ #define DECLARE_MEMBER_SETONLY (class, name, setter, member, signal ) DECLARE_MEMBER(cl
78+
7579#define DECLARE_MEMBER_FULL (class, name, setter, member, signal ) \
7680 DECLARE_MEMBER (class , name, member, signal); \
7781 DECLARE_MEMBER_GETSET (name, setter)
@@ -123,6 +127,8 @@ public:
123127#define DEFINE_MEMBER_GETSET (Class, name, setter ) \
124128 DEFINE_MEMBER_GET (Class, name) \
125129 DEFINE_MEMBER_SET(Class, name, setter)
130+
131+ #define MEMBER_EMIT (name ) std::remove_reference_t <decltype (*this )>::M_##name::emitter(this )
126132// NOLINTEND
127133
128134template <typename T>
@@ -154,6 +160,12 @@ class MemberMetadata {
154160 } else {
155161 if (MemberMetadata::get (obj) == value) return DropEmitter ();
156162 obj->*member = value;
163+ return MemberMetadata::emitter (obj);
164+ }
165+ }
166+
167+ static Ret emitter (Class* obj) {
168+ if constexpr (signal != nullptr ) {
157169 return DropEmitter (obj, &MemberMetadata::emitForObject);
158170 }
159171 }
@@ -170,3 +182,32 @@ class PseudomemberMetadata {
170182 using Ref = const Type&;
171183 using Ret = std::conditional_t <hasSignal, DropEmitter, void >;
172184};
185+
186+ class GuardedEmitBlocker {
187+ public:
188+ explicit GuardedEmitBlocker (bool * var): var(var) { *this ->var = true ; }
189+ ~GuardedEmitBlocker () { *this ->var = false ; }
190+ Q_DISABLE_COPY_MOVE (GuardedEmitBlocker);
191+
192+ private:
193+ bool * var;
194+ };
195+
196+ template <auto signal>
197+ class GuardedEmitter {
198+ using Traits = MemberPointerTraits<decltype (signal)>;
199+ using Class = Traits::Class;
200+
201+ bool blocked = false ;
202+
203+ public:
204+ GuardedEmitter () = default ;
205+ ~GuardedEmitter () = default ;
206+ Q_DISABLE_COPY_MOVE (GuardedEmitter);
207+
208+ void call (Class* obj) {
209+ if (!this ->blocked ) (obj->*signal)();
210+ }
211+
212+ GuardedEmitBlocker block () { return GuardedEmitBlocker (&this ->blocked ); }
213+ };
0 commit comments