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"
42PXR_NAMESPACE_OPEN_SCOPE
44class 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);
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,
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;
782template <
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));
792PXR_NAMESPACE_CLOSE_SCOPE
Type independent WeakPtr holder class.
Low-level utilities for informing users of various internal and external diagnostic conditions.
Provides the ability to hold an arbitrary TfWeakPtr in a non-type-specific manner in order to observe...
Blocks sending of all notices in current thread.
Handle-object returned by TfNotice::Register().
bool IsValid() const
Does this key refer to a valid notification?
Probe interface class which may be implemented and then registered via InsertProbe to introspect abou...
virtual void EndDelivery()=0
This method is called after the notice in the corresponding BeginDelivery call has finished being pro...
virtual void EndSend()=0
This method is called after the notice in the corresponding BeginSend call has been delivered to all ...
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.
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.
The base class for objects used to notify interested parties (listeners) when events have occurred.
TF_API size_t Send() const
Deliver the notice to interested listeners, returning the number of interested listeners.
static TF_API void InsertProbe(const WeakProbePtr &probe)
Register a probe that will be invoked when notices are sent and delivered.
static TF_API void Revoke(TfNotice::Keys *keys)
Revoke interest by listeners.
static TfNotice::Key Register(LPtr const &listener, MethodPtr method)
Register a listener as being interested in a TfNotice.
static TF_API void RemoveProbe(const WeakProbePtr &probe)
Remove a probe that was previously registered with InsertProbe.
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.
static TF_API bool Revoke(TfNotice::Key &key)
Revoke interest by a listener.
std::vector< Key > Keys
A TfNotice::Key container.
TfType represents a dynamic runtime type.
TF_API bool IsA(TfType queryType) const
Return true if this type is the same as or derived from queryType.
bool IsUnknown() const
Return true if this is the unknown type, representing a type unknown to the TfType system.
Enable a concrete base class for use with TfWeakPtr.
Pointer storage with deletion detection.
Demangle C++ typenames generated by the typeid() facility.
#define TF_FATAL_ERROR(fmt, args)
Issue a fatal error and end the program.
Pointer storage with deletion detection.