84 typedef std::list<_DelivererBase*> _DelivererList;
88 template <
class LPtr,
class L,
89 class Notice,
class SPtr,
class DeliveredSPtr>
90 static _DelivererBase *
91 _MakeDeliverer(LPtr
const &listener,
93 (
const Notice &, DeliveredSPtr
const &),
95 DeliveredSPtr weakSender(sender);
96 return new _DelivererWithSender<
98 void (L::*)(
const Notice &, DeliveredSPtr
const &),
100 >(listener, method, weakSender);
103 template <
class LPtr,
class L,
104 class Notice,
class SPtr,
class DeliveredSPtr>
105 static _DelivererBase *
106 _MakeDeliverer(LPtr
const &listener,
108 (
const Notice &, DeliveredSPtr
const &)
const,
109 SPtr
const &sender) {
110 DeliveredSPtr weakSender(sender);
111 return new _DelivererWithSender<
113 void (L::*)(
const Notice &, DeliveredSPtr
const &)
const,
115 >(listener, method, weakSender);
120 template <
class LPtr,
class L,
class SPtr,
class Notice>
121 static _DelivererBase *
122 _MakeDeliverer(LPtr
const &listener,
123 void (L::*method)(
const Notice &),
124 SPtr
const &sender) {
125 return new _Deliverer<
126 LPtr, SPtr, void (L::*)(
const Notice &), Notice
127 >(listener, method, sender);
130 template <
class LPtr,
class L,
class SPtr,
class Notice>
131 static _DelivererBase *
132 _MakeDeliverer(LPtr
const &listener,
133 void (L::*method)(
const Notice &)
const,
134 SPtr
const &sender) {
135 return new _Deliverer<
136 LPtr, SPtr, void (L::*)(
const Notice &)
const, Notice
137 >(listener, method, sender);
142 template <
class LPtr,
class L,
class Notice>
143 static _DelivererBase *
144 _MakeDeliverer(LPtr
const &listener,
145 void (L::*method)(
const Notice &)) {
146 return new _Deliverer<
151 template <
class LPtr,
class L,
class Notice>
152 static _DelivererBase *
153 _MakeDeliverer(LPtr
const &listener,
154 void (L::*method)(
const Notice &)
const) {
155 return new _Deliverer<
156 LPtr,
TfAnyWeakPtr, void (L::*)(
const Notice &)
const, Notice
162 template <
class LPtr,
class L>
163 static _DelivererBase *
164 _MakeDeliverer(
TfType const ¬iceType,
165 LPtr
const &listener,
169 const std::type_info&),
171 return new _RawDeliverer<LPtr,
174 const std::type_info &)>
175 (listener, method, sender, noticeType);
178 template <
class LPtr,
class L>
179 static _DelivererBase *
180 _MakeDeliverer(
TfType const ¬iceType,
181 LPtr
const &listener,
185 const std::type_info&)
const,
188 return new _RawDeliverer<LPtr,
191 const std::type_info &)
const>
192 (listener, method, sender, noticeType);
215 const std::type_info &senderType) = 0;
227 const std::type_info &senderType,
229 const std::type_info &listenerType) = 0;
252 return _deliverer && _deliverer->_IsActive();
258 operator bool()
const {
265 _DelivererWeakPtr _deliverer;
267 friend class Tf_NoticeRegistry;
346 template <
class LPtr,
class MethodPtr>
350 return _Register(_MakeDeliverer(listener, method));
353 template <
class LPtr,
class MethodPtr,
class SenderPtr>
355 Register(LPtr
const &listener, MethodPtr method, SenderPtr
const &sender) {
357 return _Register(_MakeDeliverer(listener, method, sender));
360 template <
class LPtr,
class MethodPtr>
362 Register(LPtr
const &listener, MethodPtr method,
365 return _Register(_MakeDeliverer(noticeType, listener, method, sender));
439 template <
typename SenderPtr>
440 size_t Send(SenderPtr
const &s)
const;
450 const void *senderUniqueId,
451 const std::type_info &type)
const;
476 : _list(0), _active(true), _markedForRemoval(false)
481 virtual ~_DelivererBase();
484 void _BeginDelivery(
const TfNotice ¬ice,
486 const std::type_info &senderType,
488 const std::type_info &listenerType,
489 const std::vector<TfNotice::WeakProbePtr> &probes);
492 void _EndDelivery(
const std::vector<TfNotice::WeakProbePtr> &probes);
500 _SendToListenerImpl(
const TfNotice &n,
503 const void *senderUniqueId,
504 const std::type_info &senderType,
505 const std::vector<TfNotice::WeakProbePtr> &) = 0;
511 bool _IsActive()
const {
515 void _MarkForRemoval() {
516 _markedForRemoval =
true;
521 bool _IsMarkedForRemoval()
const {
522 return _markedForRemoval;
525 virtual TfType GetNoticeType()
const = 0;
527 virtual bool Delivers(
TfType const ¬iceType,
530 virtual TfWeakBase const *GetSenderWeakBase()
const = 0;
532 virtual _DelivererBase *Clone()
const = 0;
535 bool _SendToListener(
const TfNotice &n,
538 const void *senderUniqueId,
539 const std::type_info &senderType,
540 const std::vector<TfNotice::WeakProbePtr> &probes)
543 if (_busy.fetch_add(1, std::memory_order_release) & _waitBit) {
551 _busy.fetch_add(-1, std::memory_order_release);
558 _busy.fetch_add(-1, std::memory_order_release);
562 _SendToListenerImpl(n, type,
563 s, senderUniqueId, senderType, probes);
569 void _WaitForSendsToFinish()
573 if (_busy.fetch_or(_waitBit, std::memory_order_release)) {
575 _WaitUntilNotSending();
581 template <
class ToNoticeType,
class FromNoticeType>
582 static inline ToNoticeType
const *
583 _CastNotice(FromNoticeType
const *from) {
587 if (!
dynamic_cast<ToNoticeType
const *
>(from)) {
588 ToNoticeType
const *castNotice =
592 TfNotice::_VerifyFailedCast(
typeid(ToNoticeType),
596 return static_cast<ToNoticeType
const *
>(from);
601 void _WaitUntilNotSending();
605 _DelivererList *_list;
606 _DelivererList::iterator _listIter;
609 bool _markedForRemoval;
610 std::atomic<int> _busy{0};
612 static constexpr int _waitBit = 0x80000000;
614 friend class Tf_NoticeRegistry;
617 template <
class Derived>
618 class _StandardDeliverer :
public _DelivererBase {
620 virtual ~_StandardDeliverer() {}
622 virtual TfType GetNoticeType()
const {
623 typedef typename Derived::NoticeType NoticeType;
627 " undefined in the TfType system");
631 virtual bool Delivers(
TfType const ¬iceType,
633 Derived
const *derived = this->AsDerived();
634 return noticeType.
IsA(GetNoticeType()) &&
635 !derived->_sender.IsInvalid() &&
636 sender && derived->_sender.GetWeakBase() == sender;
639 virtual TfWeakBase const *GetSenderWeakBase()
const {
640 Derived
const *derived = this->AsDerived();
641 return derived->_sender ? derived->_sender.GetWeakBase() : 0;
644 virtual _DelivererBase *Clone()
const {
645 Derived
const *derived = this->AsDerived();
646 return new Derived(derived->_listener,
653 _SendToListenerImpl(
const TfNotice ¬ice,
656 const void *senderUniqueId,
657 const std::type_info &senderType,
658 const std::vector<TfNotice::WeakProbePtr> &probes)
660 Derived *derived = this->AsDerived();
661 typedef typename Derived::ListenerType ListenerType;
662 typedef typename Derived::NoticeType NoticeType;
663 ListenerType *listener = get_pointer(derived->_listener);
665 if (listener && !derived->_sender.IsInvalid()) {
667 std::optional<TfScoped<>> endDeliveryScope;
668 if (ARCH_UNLIKELY(!probes.empty())) {
669 TfWeakBase const *senderWeakBase = GetSenderWeakBase(),
670 *listenerWeakBase = derived->_listener.GetWeakBase();
671 _BeginDelivery(notice, senderWeakBase,
673 senderType :
typeid(
void),
675 typeid(ListenerType), probes);
679 endDeliveryScope.emplace([
this, &probes]() {
680 _EndDelivery(probes);
685 _InvokeListenerMethod(listener,
686 *_CastNotice<NoticeType>(¬ice),
688 senderUniqueId, senderType);
696 Derived *AsDerived() {
697 return static_cast<Derived *
>(
this);
700 Derived
const *AsDerived()
const {
701 return static_cast<Derived
const *
>(
this);
706 template <
typename LPtr,
typename SPtr,
typename Method,
typename Notice>
708 public _StandardDeliverer<_Deliverer<LPtr, SPtr, Method, Notice> >
711 typedef Notice NoticeType;
712 typedef typename LPtr::DataType ListenerType;
713 typedef Method MethodPtr;
715 _Deliverer(LPtr
const &listener,
716 MethodPtr
const &methodPtr,
717 SPtr
const &sender = SPtr(),
719 : _listener(listener)
725 void _InvokeListenerMethod(ListenerType *listener,
726 const NoticeType ¬ice,
730 const std::type_info &)
732 (listener->*_method)(notice);
740 template <
class LPtr,
class Method>
741 class _RawDeliverer :
742 public _StandardDeliverer<_RawDeliverer<LPtr, Method> >
746 typedef typename LPtr::DataType ListenerType;
747 typedef Method MethodPtr;
749 _RawDeliverer(LPtr
const &listener,
750 MethodPtr
const &methodPtr,
753 : _noticeType(noticeType),
760 virtual TfType GetNoticeType()
const {
764 void _InvokeListenerMethod(ListenerType *listener,
765 const NoticeType ¬ice,
768 const void *senderUniqueId,
769 const std::type_info &senderType)
771 (listener->*_method)(notice, noticeType,
773 senderUniqueId, senderType);
782 template <
class LPtr,
class SPtr,
class Method,
class Notice>
783 class _DelivererWithSender :
784 public _StandardDeliverer<
785 _DelivererWithSender<LPtr, SPtr, Method, Notice>
789 typedef Notice NoticeType;
790 typedef Method MethodPtr;
791 typedef typename LPtr::DataType ListenerType;
793 typedef typename SPtr::DataType SenderType;
795 _DelivererWithSender(LPtr
const &listener,
796 MethodPtr
const &methodPtr,
799 : _listener(listener),
805 void _InvokeListenerMethod(ListenerType *listener,
806 const NoticeType ¬ice,
810 const std::type_info &)
812 SenderType *deliveredSender =
813 static_cast<SenderType *
>(
const_cast<TfWeakBase *
>(sender));
814 SPtr deliveredSPtr(deliveredSender);
815 (listener->*_method)(notice, deliveredSPtr);
826 static Key _Register(_DelivererBase*);
829 static void _VerifyFailedCast(
const std::type_info& toType,
835 const void *senderUniqueId,
836 const std::type_info & senderType)
const;
838 size_t _SendWithType(
const TfType & noticeType,
840 const void *senderUniqueId,
841 const std::type_info & senderType)
const;
843 friend class Tf_NoticeRegistry;
847 friend class Tf_PyNotice;