24 #ifndef PXR_BASE_TF_NOTICE_H
25 #define PXR_BASE_TF_NOTICE_H
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<
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;
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>
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;
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()) {
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);
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;
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;
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;
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;
780 template <
typename SenderPtr>
784 const TfWeakBase *senderWeakBase = s ? s.GetWeakBase() : NULL;
787 typeid(
typename SenderPtr::DataType) :
typeid(
void));
792 #endif // PXR_BASE_TF_NOTICE_H
virtual TF_API ~Probe()=0
virtual void BeginSend(const TfNotice ¬ice, const TfWeakBase *sender, const std::type_info &senderType)=0
virtual TF_API ~TfNotice()
static TfNotice::Key Register(LPtr const &listener, MethodPtr method)
friend class Tf_NoticeRegistry
static void RemoveProbe(const WeakProbePtr &probe)
Y * get_pointer(TfWeakPtrFacade< X, Y > const &p)
TF_API size_t SendWithWeakBase(const TfWeakBase *senderWeakBase, const void *senderUniqueId, const std::type_info &type) const
static TF_API bool Revoke(TfNotice::Key &key)
TfRefPtr< typename D::DataType > TfSafeDynamic_cast(const TfRefPtr< T > &ptr)
virtual void EndDelivery()=0
static TfNotice::Key Register(LPtr const &listener, MethodPtr method, const TfType ¬iceType, const TfAnyWeakPtr &sender)
friend class Tf_NoticeRegistry
virtual void BeginDelivery(const TfNotice ¬ice, const TfWeakBase *sender, const std::type_info &senderType, const TfWeakBase *listener, const std::type_info &listenerType)=0
PXR_NAMESPACE_CLOSE_SCOPE PXR_NAMESPACE_OPEN_SCOPE
#define PXR_NAMESPACE_CLOSE_SCOPE
TF_API bool IsA(TfType queryType) const
TF_API size_t Send() const
TfWeakPtr< Probe > WeakProbePtr
static void InsertProbe(const WeakProbePtr &probe)
static TfNotice::Key Register(LPtr const &listener, MethodPtr method, SenderPtr const &sender)
TF_API void const * GetUniqueIdentifier() const