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;
357 template <
class LPtr,
class MethodPtr>
360 return _Register(_MakeDeliverer(listener, method));
363 template <
class LPtr,
class MethodPtr,
class SenderPtr>
365 Register(LPtr
const &listener, MethodPtr method, SenderPtr
const &sender) {
366 return _Register(_MakeDeliverer(listener, method, sender));
369 template <
class LPtr,
class MethodPtr>
371 Register(LPtr
const &listener, MethodPtr method,
373 return _Register(_MakeDeliverer(noticeType, listener, method, sender));
426 template <
typename SenderPtr>
427 size_t Send(SenderPtr
const &s)
const;
437 const void *senderUniqueId,
438 const std::type_info &type)
const;
463 : _list(0), _active(true), _markedForRemoval(false)
468 virtual ~_DelivererBase();
471 void _BeginDelivery(
const TfNotice ¬ice,
473 const std::type_info &senderType,
475 const std::type_info &listenerType,
476 const std::vector<TfNotice::WeakProbePtr> &probes);
479 void _EndDelivery(
const std::vector<TfNotice::WeakProbePtr> &probes);
490 const void *senderUniqueId,
491 const std::type_info &senderType,
492 const std::vector<TfNotice::WeakProbePtr> &probes) = 0;
498 bool _IsActive()
const {
502 void _MarkForRemoval() {
503 _markedForRemoval =
true;
508 bool _IsMarkedForRemoval()
const {
509 return _markedForRemoval;
512 virtual TfType GetNoticeType()
const = 0;
514 virtual bool Delivers(
TfType const ¬iceType,
517 virtual TfWeakBase const *GetSenderWeakBase()
const = 0;
519 virtual _DelivererBase *Clone()
const = 0;
523 template <
class ToNoticeType,
class FromNoticeType>
524 static inline ToNoticeType
const *
525 _CastNotice(FromNoticeType
const *from) {
529 if (!dynamic_cast<ToNoticeType const *>(from)) {
530 ToNoticeType
const *castNotice =
534 TfNotice::_VerifyFailedCast(
typeid(ToNoticeType),
538 return static_cast<ToNoticeType
const *
>(from);
543 _DelivererList *_list;
544 _DelivererList::iterator _listIter;
547 bool _markedForRemoval;
549 friend class Tf_NoticeRegistry;
552 template <
class Derived>
553 class _StandardDeliverer :
public _DelivererBase {
555 virtual ~_StandardDeliverer() {}
557 virtual TfType GetNoticeType()
const {
558 typedef typename Derived::NoticeType NoticeType;
559 TfType ret = TfType::Find<NoticeType>();
562 " undefined in the TfType system");
566 virtual bool Delivers(
TfType const ¬iceType,
568 Derived
const *derived = this->AsDerived();
569 return noticeType.
IsA(GetNoticeType()) &&
570 !derived->_sender.IsInvalid() &&
571 sender && derived->_sender.GetWeakBase() == sender;
574 virtual TfWeakBase const *GetSenderWeakBase()
const {
575 Derived
const *derived = this->AsDerived();
576 return derived->_sender ? derived->_sender.GetWeakBase() : 0;
579 virtual _DelivererBase *Clone()
const {
580 Derived
const *derived = this->AsDerived();
581 return new Derived(derived->_listener,
588 _SendToListener(
const TfNotice ¬ice,
591 const void *senderUniqueId,
592 const std::type_info &senderType,
593 const std::vector<TfNotice::WeakProbePtr> &probes)
595 Derived *derived = this->AsDerived();
596 typedef typename Derived::ListenerType ListenerType;
597 typedef typename Derived::NoticeType NoticeType;
598 ListenerType *listener = get_pointer(derived->_listener);
600 if (listener && !derived->_sender.IsInvalid()) {
601 if (ARCH_UNLIKELY(!probes.empty())) {
602 TfWeakBase const *senderWeakBase = GetSenderWeakBase(),
603 *listenerWeakBase = derived->_listener.GetWeakBase();
604 _BeginDelivery(notice, senderWeakBase,
606 senderType :
typeid(
void),
608 typeid(ListenerType), probes);
612 _InvokeListenerMethod(listener,
613 *_CastNotice<NoticeType>(¬ice),
615 senderUniqueId, senderType);
617 if (ARCH_UNLIKELY(!probes.empty()))
618 _EndDelivery(probes);
626 Derived *AsDerived() {
627 return static_cast<Derived *
>(
this);
630 Derived
const *AsDerived()
const {
631 return static_cast<Derived
const *
>(
this);
636 template <
typename LPtr,
typename SPtr,
typename Method,
typename Notice>
638 public _StandardDeliverer<_Deliverer<LPtr, SPtr, Method, Notice> >
641 typedef Notice NoticeType;
642 typedef typename LPtr::DataType ListenerType;
643 typedef Method MethodPtr;
645 _Deliverer(LPtr
const &listener,
646 MethodPtr
const &methodPtr,
647 SPtr
const &sender = SPtr(),
649 : _listener(listener)
655 void _InvokeListenerMethod(ListenerType *listener,
656 const NoticeType ¬ice,
660 const std::type_info &)
662 (listener->*_method)(notice);
670 template <
class LPtr,
class Method>
671 class _RawDeliverer :
672 public _StandardDeliverer<_RawDeliverer<LPtr, Method> >
676 typedef typename LPtr::DataType ListenerType;
677 typedef Method MethodPtr;
679 _RawDeliverer(LPtr
const &listener,
680 MethodPtr
const &methodPtr,
683 : _noticeType(noticeType),
690 virtual TfType GetNoticeType()
const {
694 void _InvokeListenerMethod(ListenerType *listener,
695 const NoticeType ¬ice,
698 const void *senderUniqueId,
699 const std::type_info &senderType)
701 (listener->*_method)(notice, noticeType,
702 const_cast<TfWeakBase *>(sender),
703 senderUniqueId, senderType);
712 template <
class LPtr,
class SPtr,
class Method,
class Notice>
713 class _DelivererWithSender :
714 public _StandardDeliverer<
715 _DelivererWithSender<LPtr, SPtr, Method, Notice>
719 typedef Notice NoticeType;
720 typedef Method MethodPtr;
721 typedef typename LPtr::DataType ListenerType;
723 typedef typename SPtr::DataType SenderType;
725 _DelivererWithSender(LPtr
const &listener,
726 MethodPtr
const &methodPtr,
729 : _listener(listener),
735 void _InvokeListenerMethod(ListenerType *listener,
736 const NoticeType ¬ice,
740 const std::type_info &)
742 SenderType *deliveredSender =
743 static_cast<SenderType *
>(
const_cast<TfWeakBase *
>(sender));
744 SPtr deliveredSPtr(deliveredSender);
745 (listener->*_method)(notice, deliveredSPtr);
756 static Key _Register(_DelivererBase*);
759 static void _VerifyFailedCast(
const std::type_info& toType,
765 const void *senderUniqueId,
766 const std::type_info & senderType)
const;
768 size_t _SendWithType(
const TfType & noticeType,
770 const void *senderUniqueId,
771 const std::type_info & senderType)
const;
773 friend class Tf_NoticeRegistry;
777 friend class Tf_PyNotice;
780 template <
typename SenderPtr>
784 const TfWeakBase *senderWeakBase = s ? s.GetWeakBase() : NULL;
785 return _Send(senderWeakBase, senderWeakBase ? s.GetUniqueIdentifier() : 0,
787 typeid(
typename SenderPtr::DataType) :
typeid(
void));
790 PXR_NAMESPACE_CLOSE_SCOPE
792 #endif // PXR_BASE_TF_NOTICE_H
Handle-object returned by TfNotice::Register().
TO TfSafeDynamic_cast(FROM *ptr)
Safely perform a dynamic cast.
The base class for objects used to notify interested parties (listeners) when events have occurred...
static void RemoveProbe(const WeakProbePtr &probe)
Remove a probe that was previously registered with InsertProbe.
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...
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 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...
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.
static void InsertProbe(const WeakProbePtr &probe)
Register a probe that will be invoked when notices are sent and delivered.
#define TF_FATAL_ERROR(fmt, args)
Issue a fatal error and end the program.
TF_API bool IsA(TfType queryType) const
Return true if this type is the same as or derived from queryType.
Blocks sending of all notices in current thread.
bool IsUnknown() const
Return true if this is the unknown type, representing a type unknown to the TfType system...
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 Send() const
Deliver the notice to interested listeners, returning the number of interested listeners.
TfType represents a dynamic runtime type.
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.
bool IsValid() const
Does this key refer to a valid notification?
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.