00001 /* 00002 * PROPRIETARY INFORMATION. This software is proprietary to 00003 * Side Effects Software Inc., and is not to be reproduced, 00004 * transmitted, or disclosed in any way without written permission. 00005 * 00006 * Produced by: 00007 * Rafal Jaroszkiewicz 00008 * Side Effects 00009 * 477 Richmond Street West 00010 * Toronto, Ontario 00011 * Canada M5V 3E7 00012 * 416-504-9876 00013 * 00014 * NAME: UT_Notifier.h UT library (C++) 00015 * 00016 * COMMENTS: Notifier that invokes registered functor callbacks whenever 00017 * an event notification is triggered. 00018 * 00019 * 00020 * 00021 * HOW TO SET UP THE NOTIFIER AND THE CALLBACK: 00022 * 00023 * 1) decide what kind of event is passed from UT_NotifierImpl 00024 * to the callback method. It can be an int, an enumerated 00025 * type, or a class reference. 00026 * For example, 00027 * OP_Event & 00028 * 00029 * 2) in the observer class, write a method that handles events 00030 * For example, 00031 * void OP_SomeObserver::someHandler( OP_Event &event ) {} 00032 * 00033 * 3) in the observer class, declare the UT_NotifierList instance 00034 * For example in .h, 00035 * OP_SomeObserver 00036 * { 00037 * ... 00038 * UT_NotifierList myNotifierList; 00039 * ... 00040 * }; 00041 * 00042 * 4) in the emmitter class, instantiate the UT_NotifierImpl 00043 * with <OP_Event &> as the type, and provide the accessor to it 00044 * For example, 00045 * OP_SomeEventEmmiter 00046 * { 00047 * UT_NotifierImpl<OP_Event&> &getNotifier() 00048 * { return myNotifier; } 00049 * ... 00050 * private: 00051 * UT_NotifierImpl<OP_Event &> myNotifier; 00052 * }; 00053 * 00054 * 5) in the observer class, create a functor that contains 00055 * the callback method, and register the functor with notifier 00056 * For example, 00057 * void 00058 * OP_SomeObserver::registerCallback( OP_SomeEventEmmiter * 00059 * someEventEmitter ) 00060 * { 00061 * UT_Functor1<void, OP_Event &> 00062 * functor( this, &OP_SomeObserver::someHandler ); 00063 * 00064 * someEventEmmiter->getEventNotifier().addObserver( 00065 * myNotifierList, functor ); 00066 * } 00067 * 00068 * 6) whenever an event should be emitted, call notifiyObservers() 00069 * on the notifier 00070 * For example, 00071 * void 00072 * OP_SomeEventEmitter::someMethod() 00073 * { 00074 * ... 00075 * OP_Event event( whatever, things, it, takes ); 00076 * myNotifier.notifyObservers( event ); 00077 * ... 00078 * } 00079 * 00080 */ 00081 00082 #ifndef __UT_Notifier_h__ 00083 #define __UT_Notifier_h__ 00084 00085 #include "UT_API.h" 00086 #include "UT_RefArray.h" 00087 #include "UT_Functor.h" 00088 #include "UT_Pair.h" 00089 00090 // declare UT_NotifierList for the use in UT_NotifierImpl 00091 class UT_NotifierList; 00092 00093 // a pure virtual base class to refer to by the notifier list 00094 class UT_API UT_Notifier 00095 { 00096 public: 00097 virtual ~UT_Notifier() {}; 00098 virtual void removeObserver( UT_NotifierList & ) = 0; 00099 }; 00100 00101 // define UT_NotifierImpl that handles the distribution of the notifications 00102 template <typename EVENT_TYPE> 00103 class UT_NotifierImpl : public UT_Notifier 00104 { 00105 public: 00106 UT_NotifierImpl(); 00107 virtual ~UT_NotifierImpl(); 00108 00109 // a definition of the callback functor 00110 typedef UT_Functor1< void, EVENT_TYPE > Callback; 00111 00112 00113 // ---------------------------------------------------------------------- 00114 // adds a callback functor to this notifier 00115 // INPUTS: 00116 // list - a list of notifiers the caller expressed interest in 00117 // (which should not contain this notifier yet) 00118 // callback - a functor invoked as a notification of an event 00119 // OUTPUTS: 00120 // list - the list is updated to include this notifier. 00121 // If the list contained this notifier already, the 00122 // callback is not registered (i.e., the old callback 00123 // prevails) 00124 // ---------------------------------------------------------------------- 00125 virtual void addObserver( UT_NotifierList &list, Callback &callback); 00126 00127 // ---------------------------------------------------------------------- 00128 // removes a callback functor from this notifier 00129 // INPUTS: 00130 // list - a list of notifiers the caller expressed interest in 00131 // (which should also contain this notifier) 00132 // OUTPUTS: 00133 // list - this notifier is removed from the list. If this notifier 00134 // is not found in the list, no action is taken. 00135 // ---------------------------------------------------------------------- 00136 virtual void removeObserver( UT_NotifierList &list ); 00137 00138 // ---------------------------------------------------------------------- 00139 // checks if this notifier has an observer registered 00140 // INPUTS: 00141 // list - a list based on which we check the observer registration 00142 // RETURNS: 00143 // true if the list was used to add an observer to this notifer, and 00144 // the observer is still registered. 00145 // false if this notifier has no callback functor was registered 00146 // with the list. 00147 // ---------------------------------------------------------------------- 00148 virtual bool hasObserver( const UT_NotifierList &list ) const; 00149 00150 // ---------------------------------------------------------------------- 00151 // invokes all regisered functors using the event as argument 00152 // INPUTS: 00153 // event - an event passed to the functors 00154 // NB: 00155 // non-const because it needs to invoke a non-const functor, and if 00156 // this method is const then only const functor is returned, which in 00157 // turn tries to invoke operator() for which only non-const version 00158 // is available 00159 // ---------------------------------------------------------------------- 00160 virtual void notifyObservers( EVENT_TYPE event ); 00161 00162 00163 private: 00164 // ---------------------------------------------------------------------- 00165 // finds the index to the observer list that contains the argument 00166 // (i.e., the notifier list) 00167 // INPUTS: 00168 // list - a list based on which we check the observer registration 00169 // RETURNS: 00170 // index to the observer element containing "list" 00171 // with the list. 00172 // ---------------------------------------------------------------------- 00173 int getObserverIndex( const UT_NotifierList &list ) const; 00174 00175 // ---------------------------------------------------------------------- 00176 // removes all observers 00177 // ---------------------------------------------------------------------- 00178 void removeAllObservers(); 00179 00180 // ---------------------------------------------------------------------- 00181 // iterates through the whole list of observers and removes any entries 00182 // that have NULL as their list member of the pair (i.e., entries that are 00183 // marked for deletion) 00184 // ---------------------------------------------------------------------- 00185 void pruneObservers(); 00186 00187 private: 00188 // define a type that we are storing 00189 typedef UT_Pair< UT_NotifierList*, Callback> ObserverPair; 00190 00191 // list of registered callbacks to invoke during the distribution 00192 // of notifications. The observers is an array of pairs. The pair 00193 // contains a list pointer based on which we recognize observer, 00194 // and the callback functor which is invoked as the notification. 00195 UT_RefArray< ObserverPair > myObservers; 00196 00197 // some state flags 00198 bool myNotifyingFlag; // currently notifying observers 00199 bool myPendingRemovalFlag; // list contains observers to remove 00200 }; 00201 00202 // include the templated implementation 00203 #if defined( WIN32 ) || defined( LINUX ) || defined( MBSD ) || defined(GAMEOS) 00204 #include "UT_Notifier.C" 00205 #endif 00206 00207 #endif // __UT_Notifier_h__
1.5.9