24 #ifndef PXR_BASE_TF_NOTICE_H 25 #define PXR_BASE_TF_NOTICE_H 31 #include "pxr/base/tf/api.h" 34 #include "pxr/base/tf/type.h" 42 PXR_NAMESPACE_OPEN_SCOPE
44 class Tf_NoticeRegistry;
97 typedef std::list<_DelivererBase*> _DelivererList;
101 template <
class LPtr,
class L,
102 class Notice,
class SPtr,
class DeliveredSPtr>
103 static _DelivererBase *
104 _MakeDeliverer(LPtr
const &listener,
106 (
const Notice &, DeliveredSPtr
const &),
107 SPtr
const &sender) {
108 DeliveredSPtr weakSender(sender);
109 return new _DelivererWithSender<
111 void (L::*)(
const Notice &, DeliveredSPtr
const &),
113 >(listener, method, weakSender);
116 template <
class LPtr,
class L,
117 class Notice,
class SPtr,
class DeliveredSPtr>
118 static _DelivererBase *
119 _MakeDeliverer(LPtr
const &listener,
121 (
const Notice &, DeliveredSPtr
const &)
const,
122 SPtr
const &sender) {
123 DeliveredSPtr weakSender(sender);
124 return new _DelivererWithSender<
126 void (L::*)(
const Notice &, DeliveredSPtr
const &)
const,
128 >(listener, method, weakSender);
133 template <
class LPtr,
class L,
class SPtr,
class Notice>
134 static _DelivererBase *
135 _MakeDeliverer(LPtr
const &listener,
136 void (L::*method)(
const Notice &),
137 SPtr
const &sender) {
138 return new _Deliverer<
139 LPtr, SPtr, void (L::*)(
const Notice &), Notice
140 >(listener, method, sender);
143 template <
class LPtr,
class L,
class SPtr,
class Notice>
144 static _DelivererBase *
145 _MakeDeliverer(LPtr
const &listener,
146 void (L::*method)(
const Notice &)
const,
147 SPtr
const &sender) {
148 return new _Deliverer<
149 LPtr, SPtr, void (L::*)(
const Notice &)
const, Notice
150 >(listener, method, sender);
155 template <
class LPtr,
class L,
class Notice>
156 static _DelivererBase *
157 _MakeDeliverer(LPtr
const &listener,
158 void (L::*method)(
const Notice &)) {
159 return new _Deliverer<
164 template <
class LPtr,
class L,
class Notice>
165 static _DelivererBase *
166 _MakeDeliverer(LPtr
const &listener,
167 void (L::*method)(
const Notice &)
const) {
168 return new _Deliverer<
169 LPtr,
TfAnyWeakPtr, void (L::*)(
const Notice &)
const, Notice
175 template <
class LPtr,
class L>
176 static _DelivererBase *
177 _MakeDeliverer(
TfType const ¬iceType,
178 LPtr
const &listener,
182 const std::type_info&),
184 return new _RawDeliverer<LPtr,
187 const std::type_info &)>
188 (listener, method, sender, noticeType);
191 template <
class LPtr,
class L>
192 static _DelivererBase *
193 _MakeDeliverer(
TfType const ¬iceType,
194 LPtr
const &listener,
198 const std::type_info&)
const,
201 return new _RawDeliverer<LPtr,
204 const std::type_info &)
const>
205 (listener, method, sender, noticeType);
221 virtual ~
Probe() = 0;
228 const std::type_info &senderType) = 0;
240 const std::type_info &senderType,
242 const std::type_info &listenerType) = 0;
265 return _deliverer && _deliverer->_IsActive();
271 operator bool()
const {
278 _DelivererWeakPtr _deliverer;
280 friend class Tf_NoticeRegistry;
359 template <
class LPtr,
class MethodPtr>
362 return _Register(_MakeDeliverer(listener, method));
365 template <
class LPtr,
class MethodPtr,
class SenderPtr>
367 Register(LPtr
const &listener, MethodPtr method, SenderPtr
const &sender) {
368 return _Register(_MakeDeliverer(listener, method, sender));
371 template <
class LPtr,
class MethodPtr>
373 Register(LPtr
const &listener, MethodPtr method,
375 return _Register(_MakeDeliverer(noticeType, listener, method, sender));
428 template <
typename SenderPtr>
429 size_t Send(SenderPtr
const &s)
const;
439 const void *senderUniqueId,
440 const std::type_info &type)
const;
465 : _list(0), _active(true), _markedForRemoval(false)
470 virtual ~_DelivererBase();
473 void _BeginDelivery(
const TfNotice ¬ice,
475 const std::type_info &senderType,
477 const std::type_info &listenerType,
478 const std::vector<TfNotice::WeakProbePtr> &probes);
481 void _EndDelivery(
const std::vector<TfNotice::WeakProbePtr> &probes);
492 const void *senderUniqueId,
493 const std::type_info &senderType,
494 const std::vector<TfNotice::WeakProbePtr> &probes) = 0;
500 bool _IsActive()
const {
504 void _MarkForRemoval() {
505 _markedForRemoval =
true;
510 bool _IsMarkedForRemoval()
const {
511 return _markedForRemoval;
514 virtual TfType GetNoticeType()
const = 0;
516 virtual bool Delivers(
TfType const ¬iceType,
519 virtual TfWeakBase const *GetSenderWeakBase()
const = 0;
521 virtual _DelivererBase *Clone()
const = 0;
525 template <
class ToNoticeType,
class FromNoticeType>
526 static inline ToNoticeType
const *
527 _CastNotice(FromNoticeType
const *from) {
531 if (!dynamic_cast<ToNoticeType const *>(from)) {
532 ToNoticeType
const *castNotice =
533 TfSafeDynamic_cast<ToNoticeType const *>(from);
536 TfNotice::_VerifyFailedCast(
typeid(ToNoticeType),
540 return static_cast<ToNoticeType const *>(from);
545 _DelivererList *_list;
546 _DelivererList::iterator _listIter;
549 bool _markedForRemoval;
551 friend class Tf_NoticeRegistry;
554 template <
class Derived>
555 class _StandardDeliverer :
public _DelivererBase {
557 virtual ~_StandardDeliverer() {}
559 virtual TfType GetNoticeType()
const {
560 typedef typename Derived::NoticeType NoticeType;
561 TfType ret = TfType::Find<NoticeType>();
564 " undefined in the TfType system");
568 virtual bool Delivers(
TfType const ¬iceType,
570 Derived
const *derived = this->AsDerived();
571 return noticeType.
IsA(GetNoticeType()) &&
572 !derived->_sender.IsInvalid() &&
573 sender && derived->_sender.GetWeakBase() == sender;
576 virtual TfWeakBase const *GetSenderWeakBase()
const {
577 Derived
const *derived = this->AsDerived();
578 return derived->_sender ? derived->_sender.GetWeakBase() : 0;
581 virtual _DelivererBase *Clone()
const {
582 Derived
const *derived = this->AsDerived();
583 return new Derived(derived->_listener,
590 _SendToListener(
const TfNotice ¬ice,
593 const void *senderUniqueId,
594 const std::type_info &senderType,
595 const std::vector<TfNotice::WeakProbePtr> &probes)
597 Derived *derived = this->AsDerived();
598 typedef typename Derived::ListenerType ListenerType;
599 typedef typename Derived::NoticeType NoticeType;
600 ListenerType *listener = get_pointer(derived->_listener);
602 if (listener && !derived->_sender.IsInvalid()) {
603 if (ARCH_UNLIKELY(!probes.empty())) {
604 TfWeakBase const *senderWeakBase = GetSenderWeakBase(),
605 *listenerWeakBase = derived->_listener.GetWeakBase();
606 _BeginDelivery(notice, senderWeakBase,
608 senderType :
typeid(
void),
610 typeid(ListenerType), probes);
614 _InvokeListenerMethod(listener,
615 *_CastNotice<NoticeType>(¬ice),
617 senderUniqueId, senderType);
619 if (ARCH_UNLIKELY(!probes.empty()))
620 _EndDelivery(probes);
628 Derived *AsDerived() {
629 return static_cast<Derived *>(
this);
632 Derived
const *AsDerived()
const {
633 return static_cast<Derived const *>(
this);
638 template <
typename LPtr,
typename SPtr,
typename Method,
typename Notice>
640 public _StandardDeliverer<_Deliverer<LPtr, SPtr, Method, Notice> >
643 typedef Notice NoticeType;
644 typedef typename LPtr::DataType ListenerType;
645 typedef Method MethodPtr;
647 _Deliverer(LPtr
const &listener,
648 MethodPtr
const &methodPtr,
649 SPtr
const &sender = SPtr(),
651 : _listener(listener)
657 void _InvokeListenerMethod(ListenerType *listener,
658 const NoticeType ¬ice,
662 const std::type_info &)
664 (listener->*_method)(notice);
672 template <
class LPtr,
class Method>
673 class _RawDeliverer :
674 public _StandardDeliverer<_RawDeliverer<LPtr, Method> >
678 typedef typename LPtr::DataType ListenerType;
679 typedef Method MethodPtr;
681 _RawDeliverer(LPtr
const &listener,
682 MethodPtr
const &methodPtr,
685 : _noticeType(noticeType),
692 virtual TfType GetNoticeType()
const {
696 void _InvokeListenerMethod(ListenerType *listener,
697 const NoticeType ¬ice,
700 const void *senderUniqueId,
701 const std::type_info &senderType)
703 (listener->*_method)(notice, noticeType,
704 const_cast<TfWeakBase *>(sender),
705 senderUniqueId, senderType);
714 template <
class LPtr,
class SPtr,
class Method,
class Notice>
715 class _DelivererWithSender :
716 public _StandardDeliverer<
717 _DelivererWithSender<LPtr, SPtr, Method, Notice>
721 typedef Notice NoticeType;
722 typedef Method MethodPtr;
723 typedef typename LPtr::DataType ListenerType;
725 typedef typename SPtr::DataType SenderType;
727 _DelivererWithSender(LPtr
const &listener,
728 MethodPtr
const &methodPtr,
731 : _listener(listener),
737 void _InvokeListenerMethod(ListenerType *listener,
738 const NoticeType ¬ice,
742 const std::type_info &)
744 SenderType *deliveredSender =
745 static_cast<SenderType *>(const_cast<TfWeakBase *>(sender));
746 SPtr deliveredSPtr(deliveredSender);
747 (listener->*_method)(notice, deliveredSPtr);
758 static Key _Register(_DelivererBase*);
761 static void _VerifyFailedCast(
const std::type_info& toType,
767 const void *senderUniqueId,
768 const std::type_info & senderType)
const;
770 size_t _SendWithType(
const TfType & noticeType,
772 const void *senderUniqueId,
773 const std::type_info & senderType)
const;
775 friend class Tf_NoticeRegistry;
779 friend class Tf_PyNotice;
782 template <
typename SenderPtr>
786 const TfWeakBase *senderWeakBase = s ? s.GetWeakBase() : NULL;
787 return _Send(senderWeakBase, senderWeakBase ? s.GetUniqueIdentifier() : 0,
789 typeid(
typename SenderPtr::DataType) :
typeid(
void));
792 PXR_NAMESPACE_CLOSE_SCOPE
794 #endif // PXR_BASE_TF_NOTICE_H Handle-object returned by TfNotice::Register().
bool IsValid() const
Does this key refer to a valid notification?
The base class for objects used to notify interested parties (listeners) when events have occurred.
virtual void BeginDelivery(const TfNotice ¬ice, const TfWeakBase *sender, const std::type_info &senderType, const TfWeakBase *listener, const std::type_info &listenerType)=0
This method is called just before notice is delivered to a listener.
Type independent WeakPtr holder class.
Low-level utilities for informing users of various internal and external diagnostic conditions.
TF_API bool IsA(TfType queryType) const
Return true if this type is the same as or derived from queryType.
std::vector< Key > Keys
A TfNotice::Key container.
Pointer storage with deletion detection.
Demangle C++ typenames generated by the typeid() facility.
Provides the ability to hold an arbitrary TfWeakPtr in a non-type-specific manner in order to observe...
TF_API size_t Send() const
Deliver the notice to interested listeners, returning the number of interested listeners.
Probe interface class which may be implemented and then registered via InsertProbe to introspect abou...
static TF_API bool Revoke(TfNotice::Key &key)
Revoke interest by a listener.
#define TF_FATAL_ERROR(fmt, args)
Issue a fatal error and end the program.
static TF_API void RemoveProbe(const WeakProbePtr &probe)
Remove a probe that was previously registered with InsertProbe.
static TF_API void InsertProbe(const WeakProbePtr &probe)
Register a probe that will be invoked when notices are sent and delivered.
Blocks sending of all notices in current thread.
virtual void EndSend()=0
This method is called after the notice in the corresponding BeginSend call has been delivered to all ...
virtual void EndDelivery()=0
This method is called after the notice in the corresponding BeginDelivery call has finished being pro...
TF_API size_t SendWithWeakBase(const TfWeakBase *senderWeakBase, const void *senderUniqueId, const std::type_info &type) const
Variant of Send() that takes a specific sender in the form of a TfWeakBase pointer and a typeid.
TfType represents a dynamic runtime type.
bool IsUnknown() const
Return true if this is the unknown type, representing a type unknown to the TfType system.
virtual void BeginSend(const TfNotice ¬ice, const TfWeakBase *sender, const std::type_info &senderType)=0
This method is called just before notice is sent to any listeners.
static TfNotice::Key Register(LPtr const &listener, MethodPtr method)
Register a listener as being interested in a TfNotice.
Enable a concrete base class for use with TfWeakPtr.