7#ifndef PXR_BASE_TF_NOTICE_H
8#define PXR_BASE_TF_NOTICE_H
14#include "pxr/base/tf/api.h"
17#include "pxr/base/tf/type.h"
25PXR_NAMESPACE_OPEN_SCOPE
27class Tf_NoticeRegistry;
80 typedef std::list<_DelivererBase*> _DelivererList;
84 template <
class LPtr,
class L,
85 class Notice,
class SPtr,
class DeliveredSPtr>
86 static _DelivererBase *
87 _MakeDeliverer(LPtr
const &listener,
89 (
const Notice &, DeliveredSPtr
const &),
91 DeliveredSPtr weakSender(sender);
92 return new _DelivererWithSender<
94 void (L::*)(
const Notice &, DeliveredSPtr
const &),
96 >(listener, method, weakSender);
99 template <
class LPtr,
class L,
100 class Notice,
class SPtr,
class DeliveredSPtr>
101 static _DelivererBase *
102 _MakeDeliverer(LPtr
const &listener,
104 (
const Notice &, DeliveredSPtr
const &)
const,
105 SPtr
const &sender) {
106 DeliveredSPtr weakSender(sender);
107 return new _DelivererWithSender<
109 void (L::*)(
const Notice &, DeliveredSPtr
const &)
const,
111 >(listener, method, weakSender);
116 template <
class LPtr,
class L,
class SPtr,
class Notice>
117 static _DelivererBase *
118 _MakeDeliverer(LPtr
const &listener,
119 void (L::*method)(
const Notice &),
120 SPtr
const &sender) {
121 return new _Deliverer<
122 LPtr, SPtr, void (L::*)(
const Notice &), Notice
123 >(listener, method, sender);
126 template <
class LPtr,
class L,
class SPtr,
class Notice>
127 static _DelivererBase *
128 _MakeDeliverer(LPtr
const &listener,
129 void (L::*method)(
const Notice &)
const,
130 SPtr
const &sender) {
131 return new _Deliverer<
132 LPtr, SPtr, void (L::*)(
const Notice &)
const, Notice
133 >(listener, method, sender);
138 template <
class LPtr,
class L,
class Notice>
139 static _DelivererBase *
140 _MakeDeliverer(LPtr
const &listener,
141 void (L::*method)(
const Notice &)) {
142 return new _Deliverer<
147 template <
class LPtr,
class L,
class Notice>
148 static _DelivererBase *
149 _MakeDeliverer(LPtr
const &listener,
150 void (L::*method)(
const Notice &)
const) {
151 return new _Deliverer<
152 LPtr,
TfAnyWeakPtr, void (L::*)(
const Notice &)
const, Notice
158 template <
class LPtr,
class L>
159 static _DelivererBase *
160 _MakeDeliverer(
TfType const ¬iceType,
161 LPtr
const &listener,
165 const std::type_info&),
167 return new _RawDeliverer<LPtr,
170 const std::type_info &)>
171 (listener, method, sender, noticeType);
174 template <
class LPtr,
class L>
175 static _DelivererBase *
176 _MakeDeliverer(
TfType const ¬iceType,
177 LPtr
const &listener,
181 const std::type_info&)
const,
184 return new _RawDeliverer<LPtr,
187 const std::type_info &)
const>
188 (listener, method, sender, noticeType);
211 const std::type_info &senderType) = 0;
223 const std::type_info &senderType,
225 const std::type_info &listenerType) = 0;
248 return _deliverer && _deliverer->_IsActive();
254 operator bool()
const {
261 _DelivererWeakPtr _deliverer;
263 friend class Tf_NoticeRegistry;
342 template <
class LPtr,
class MethodPtr>
345 return _Register(_MakeDeliverer(listener, method));
348 template <
class LPtr,
class MethodPtr,
class SenderPtr>
350 Register(LPtr
const &listener, MethodPtr method, SenderPtr
const &sender) {
351 return _Register(_MakeDeliverer(listener, method, sender));
354 template <
class LPtr,
class MethodPtr>
356 Register(LPtr
const &listener, MethodPtr method,
358 return _Register(_MakeDeliverer(noticeType, listener, method, sender));
411 template <
typename SenderPtr>
412 size_t Send(SenderPtr
const &s)
const;
422 const void *senderUniqueId,
423 const std::type_info &type)
const;
448 : _list(0), _active(true), _markedForRemoval(false)
453 virtual ~_DelivererBase();
456 void _BeginDelivery(
const TfNotice ¬ice,
458 const std::type_info &senderType,
460 const std::type_info &listenerType,
461 const std::vector<TfNotice::WeakProbePtr> &probes);
464 void _EndDelivery(
const std::vector<TfNotice::WeakProbePtr> &probes);
475 const void *senderUniqueId,
476 const std::type_info &senderType,
477 const std::vector<TfNotice::WeakProbePtr> &probes) = 0;
483 bool _IsActive()
const {
487 void _MarkForRemoval() {
488 _markedForRemoval =
true;
493 bool _IsMarkedForRemoval()
const {
494 return _markedForRemoval;
497 virtual TfType GetNoticeType()
const = 0;
499 virtual bool Delivers(
TfType const ¬iceType,
502 virtual TfWeakBase const *GetSenderWeakBase()
const = 0;
504 virtual _DelivererBase *Clone()
const = 0;
508 template <
class ToNoticeType,
class FromNoticeType>
509 static inline ToNoticeType
const *
510 _CastNotice(FromNoticeType
const *from) {
514 if (!
dynamic_cast<ToNoticeType
const *
>(from)) {
515 ToNoticeType
const *castNotice =
516 TfSafeDynamic_cast<ToNoticeType const *>(from);
519 TfNotice::_VerifyFailedCast(
typeid(ToNoticeType),
523 return static_cast<ToNoticeType
const *
>(from);
528 _DelivererList *_list;
529 _DelivererList::iterator _listIter;
532 bool _markedForRemoval;
534 friend class Tf_NoticeRegistry;
537 template <
class Derived>
538 class _StandardDeliverer :
public _DelivererBase {
540 virtual ~_StandardDeliverer() {}
542 virtual TfType GetNoticeType()
const {
543 typedef typename Derived::NoticeType NoticeType;
544 TfType ret = TfType::Find<NoticeType>();
547 " undefined in the TfType system");
551 virtual bool Delivers(
TfType const ¬iceType,
553 Derived
const *derived = this->AsDerived();
554 return noticeType.
IsA(GetNoticeType()) &&
555 !derived->_sender.IsInvalid() &&
556 sender && derived->_sender.GetWeakBase() == sender;
559 virtual TfWeakBase const *GetSenderWeakBase()
const {
560 Derived
const *derived = this->AsDerived();
561 return derived->_sender ? derived->_sender.GetWeakBase() : 0;
564 virtual _DelivererBase *Clone()
const {
565 Derived
const *derived = this->AsDerived();
566 return new Derived(derived->_listener,
573 _SendToListener(
const TfNotice ¬ice,
576 const void *senderUniqueId,
577 const std::type_info &senderType,
578 const std::vector<TfNotice::WeakProbePtr> &probes)
580 Derived *derived = this->AsDerived();
581 typedef typename Derived::ListenerType ListenerType;
582 typedef typename Derived::NoticeType NoticeType;
583 ListenerType *listener = get_pointer(derived->_listener);
585 if (listener && !derived->_sender.IsInvalid()) {
586 if (ARCH_UNLIKELY(!probes.empty())) {
587 TfWeakBase const *senderWeakBase = GetSenderWeakBase(),
588 *listenerWeakBase = derived->_listener.GetWeakBase();
589 _BeginDelivery(notice, senderWeakBase,
591 senderType :
typeid(
void),
593 typeid(ListenerType), probes);
597 _InvokeListenerMethod(listener,
598 *_CastNotice<NoticeType>(¬ice),
600 senderUniqueId, senderType);
602 if (ARCH_UNLIKELY(!probes.empty()))
603 _EndDelivery(probes);
611 Derived *AsDerived() {
612 return static_cast<Derived *
>(
this);
615 Derived
const *AsDerived()
const {
616 return static_cast<Derived
const *
>(
this);
621 template <
typename LPtr,
typename SPtr,
typename Method,
typename Notice>
623 public _StandardDeliverer<_Deliverer<LPtr, SPtr, Method, Notice> >
626 typedef Notice NoticeType;
627 typedef typename LPtr::DataType ListenerType;
628 typedef Method MethodPtr;
630 _Deliverer(LPtr
const &listener,
631 MethodPtr
const &methodPtr,
632 SPtr
const &sender = SPtr(),
634 : _listener(listener)
640 void _InvokeListenerMethod(ListenerType *listener,
641 const NoticeType ¬ice,
645 const std::type_info &)
647 (listener->*_method)(notice);
655 template <
class LPtr,
class Method>
656 class _RawDeliverer :
657 public _StandardDeliverer<_RawDeliverer<LPtr, Method> >
661 typedef typename LPtr::DataType ListenerType;
662 typedef Method MethodPtr;
664 _RawDeliverer(LPtr
const &listener,
665 MethodPtr
const &methodPtr,
668 : _noticeType(noticeType),
675 virtual TfType GetNoticeType()
const {
679 void _InvokeListenerMethod(ListenerType *listener,
680 const NoticeType ¬ice,
683 const void *senderUniqueId,
684 const std::type_info &senderType)
686 (listener->*_method)(notice, noticeType,
688 senderUniqueId, senderType);
697 template <
class LPtr,
class SPtr,
class Method,
class Notice>
698 class _DelivererWithSender :
699 public _StandardDeliverer<
700 _DelivererWithSender<LPtr, SPtr, Method, Notice>
704 typedef Notice NoticeType;
705 typedef Method MethodPtr;
706 typedef typename LPtr::DataType ListenerType;
708 typedef typename SPtr::DataType SenderType;
710 _DelivererWithSender(LPtr
const &listener,
711 MethodPtr
const &methodPtr,
714 : _listener(listener),
720 void _InvokeListenerMethod(ListenerType *listener,
721 const NoticeType ¬ice,
725 const std::type_info &)
727 SenderType *deliveredSender =
728 static_cast<SenderType *
>(
const_cast<TfWeakBase *
>(sender));
729 SPtr deliveredSPtr(deliveredSender);
730 (listener->*_method)(notice, deliveredSPtr);
741 static Key _Register(_DelivererBase*);
744 static void _VerifyFailedCast(
const std::type_info& toType,
750 const void *senderUniqueId,
751 const std::type_info & senderType)
const;
753 size_t _SendWithType(
const TfType & noticeType,
755 const void *senderUniqueId,
756 const std::type_info & senderType)
const;
758 friend class Tf_NoticeRegistry;
762 friend class Tf_PyNotice;
765template <
typename SenderPtr>
769 const TfWeakBase *senderWeakBase = s ? s.GetWeakBase() : NULL;
770 return _Send(senderWeakBase, senderWeakBase ? s.GetUniqueIdentifier() : 0,
772 typeid(
typename SenderPtr::DataType) :
typeid(
void));
775PXR_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.