27#define PROMEKI_OBJECT(ObjectName, ParentObjectName) \
29 static const MetaInfo &metaInfo() { \
30 static const MetaInfo __metaInfo( \
31 typeid(ObjectName).name(), \
32 &ParentObjectName::metaInfo() \
37#define PROMEKI_SIGNAL(SIGNALNAME, ...) \
38 static constexpr const char *SIGNALNAME##SignalName = PROMEKI_STRINGIFY(SIGNALNAME) "(" PROMEKI_STRINGIFY_ARGS(__VA_ARGS__) ")"; \
39 static inline SignalMeta SIGNALNAME##SignalMeta = SignalMeta(metaInfo(), SIGNALNAME##SignalName); \
40 Signal<__VA_ARGS__> SIGNALNAME##Signal = Signal<__VA_ARGS__>(this, SIGNALNAME##SignalName);
42#define PROMEKI_SLOT(SLOTNAME, ...) \
43 static constexpr const char *SLOTNAME##SlotName = PROMEKI_STRINGIFY(SLOTNAME) "(" PROMEKI_STRINGIFY_ARGS(__VA_ARGS__) ")"; \
44 static inline SlotMeta SLOTNAME##SlotMeta = SlotMeta(metaInfo(), SLOTNAME##SlotName); \
45 void SLOTNAME(__VA_ARGS__); \
46 Slot<__VA_ARGS__> SLOTNAME##Slot = Slot<__VA_ARGS__>( \
47 [this](auto&&... args) { this->SLOTNAME(std::forward<decltype(args)>(args)...); }, \
48 this, SLOTNAME##SlotName \
50 int SLOTNAME##SlotID = registerSlot(&SLOTNAME##Slot);
93 p.store(
object.p.load(std::memory_order_relaxed), std::memory_order_relaxed);
99 bool isValid()
const {
return p.load(std::memory_order_acquire) !=
nullptr; }
108 std::atomic<ObjectBase *> p{
nullptr};
170 mutable String _demangledName;
186 m._signalList +=
this;
190 const char *
name()
const {
return _name; }
211 const char *
name()
const {
return _name; }
248 aboutToDestroySignal.
emit(
this);
269 if(_parent !=
nullptr) _parent->removeChild(
this);
271 if(_parent !=
nullptr) _parent->addChild(
this);
292 _slotList += SlotItem(
337 int startTimer(
unsigned int intervalMs,
bool singleShot =
false);
375 const char *prototype;
389 mutable Mutex _pointerMapMutex;
405 void destroyChildren() {
406 for(
auto child : _childList) {
407 child->_parent =
nullptr;
420 for(
auto item : _pointerMap) {
421 item.first->p.store(
nullptr, std::memory_order_release);
427 for(
auto &
item : _cleanupList) {
428 if(!
item.object.isValid())
continue;
431 _cleanupList.
clear();
436inline void ObjectBasePtr::link() {
440 obj->_pointerMap[
this] =
this;
445inline void ObjectBasePtr::unlink() {
446 ObjectBase *
obj = p.exchange(
nullptr, std::memory_order_acq_rel);
449 auto it =
obj->_pointerMap.find(
this);
463template <
typename...
Args>
465 if(signal ==
nullptr ||
slot ==
nullptr)
return;
468 ObjectBase *signalObject = static_cast<ObjectBase *>(signal->owner());
469 ObjectBase *slotObject = static_cast<ObjectBase *>(slot->owner());
471 EventLoop *slotLoop = slotObject->_eventLoop;
472 EventLoop *currentLoop = EventLoop::current();
475 if(slotLoop == nullptr || slotLoop == currentLoop) {
476 ObjectBase *prevSender = slotObject->_signalSender;
477 slotObject->_signalSender = signalObject;
479 slotObject->_signalSender = prevSender;
482 VariantList packed = Signal<Args...>::pack(args...);
483 ObjectBasePtr senderTracker(signalObject);
484 slotLoop->postCallable(
485 [slot, slotObject, packed = std::move(packed),
486 senderTracker = std::move(senderTracker)]() {
487 ObjectBase *prevSender = slotObject->_signalSender;
488 slotObject->_signalSender =
489 senderTracker.isValid()
490 ? const_cast<ObjectBase *>(senderTracker.data())
493 slotObject->_signalSender = prevSender;
504 [signal](
ObjectBase *ptr){ signal->disconnectFromObject(ptr); }
Per-thread event loop providing event dispatch, timers, and posted callables.
Definition eventloop.h:58
Base class for the event system.
Definition event.h:29
Iterator remove(ConstIterator pos)
Removes the element at the given iterator position.
Definition list.h:402
size_t size() const noexcept
Returns the number of elements in the list.
Definition list.h:301
bool removeFirst(const T &value)
Removes the first instance of value from the list.
Definition list.h:439
void clear() noexcept
Removes all elements from the list.
Definition list.h:330
Iterator end() noexcept
Returns a mutable iterator to one past the last element.
Definition list.h:198
RAII scoped locker for Mutex.
Definition mutex.h:41
Mutual exclusion lock wrapping std::mutex.
Definition mutex.h:33
Object that holds a pointer to an ObjectBase (or derived) object. This class will register itself wit...
Definition objectbase.h:73
ObjectBasePtr & operator=(const ObjectBasePtr &object)
Copy assignment operator. Re-links to the new ObjectBase.
Definition objectbase.h:91
bool isValid() const
Returns true if the tracked pointer is not null.
Definition objectbase.h:99
~ObjectBasePtr()
Destructor. Unlinks from the tracked ObjectBase.
Definition objectbase.h:88
const ObjectBase * data() const
Returns a const pointer to the tracked ObjectBase.
Definition objectbase.h:105
ObjectBasePtr(const ObjectBasePtr &object)
Copy constructor. Tracks the same ObjectBase as the source.
Definition objectbase.h:85
ObjectBase * data()
Returns a mutable pointer to the tracked ObjectBase.
Definition objectbase.h:102
Base object for promeki.
Definition objectbase.h:129
void stopTimer(int timerId)
Stops a timer previously started with startTimer().
void moveToThread(EventLoop *loop)
Changes the EventLoop affinity of this object.
void setParent(ObjectBase *p)
Sets the parent of this object. If the object already has a parent, it will be removed as a child fro...
Definition objectbase.h:268
int startTimer(unsigned int intervalMs, bool singleShot=false)
Starts a timer on this object's EventLoop.
virtual void timerEvent(TimerEvent *e)
Called when a timer fires for this object.
EventLoop * eventLoop() const
Returns the EventLoop this object is affiliated with.
Definition objectbase.h:314
int registerSlot(Slot< Args... > *slot)
Registers a slot with this object and assigns it an ID.
Definition objectbase.h:289
static const MetaInfo & metaInfo()
Returns the MetaInfo for the ObjectBase class.
Definition objectbase.h:218
virtual ~ObjectBase()
Destructor. Emits aboutToDestroy, detaches from parent, and destroys children.
Definition objectbase.h:247
static void connect(Signal< Args... > *signal, Slot< Args... > *slot)
connects a signal and slot together. This function assumes both the signal and slot exist in a Object...
virtual void event(Event *e)
Called by EventLoop to deliver events to this object.
std::function< void(const VariantList &)> SlotVariantFunc
Function type for invoking a slot with a list of Variants.
Definition objectbase.h:232
const ObjectBaseList & childList() const
Returns a list of children of this object.
Definition objectbase.h:279
ObjectBase * signalSender()
Returns the ObjectBase that emitted the signal currently being handled.
Definition objectbase.h:347
ObjectBase(ObjectBase *p=nullptr)
Default ObjectBase constructor.
ObjectBase * parent() const
Returns the parent object, if one. nullptr if none.
Definition objectbase.h:258
void emit(Args... args) const
Emits this signal.
Definition signal.h:170
Encoding-aware string class with copy-on-write semantics.
Definition string.h:35
Event delivered when a timer fires.
Definition timerevent.h:22
ObjectBasePtr(ObjectBase *object=nullptr)
Definition objectbase.h:82
#define PROMEKI_NAMESPACE_BEGIN
Starts a promeki namespace block.
Definition namespace.h:14
#define PROMEKI_NAMESPACE_END
Ends a promeki namespace block.
Definition namespace.h:19