llevent.cpp

Go to the documentation of this file.
00001 
00032 #include "linden_common.h"
00033 
00034 #include "llevent.h"
00035 
00036 /************************************************
00037     Events
00038 ************************************************/
00039 
00040 // virtual
00041 LLEvent::~LLEvent()
00042 {
00043 }
00044 
00045 // virtual
00046 bool LLEvent::accept(LLEventListener* listener)
00047 {
00048         return true;
00049 }
00050 
00051 // virtual
00052 const std::string& LLEvent::desc()
00053 {
00054         return mDesc;
00055 }
00056 
00057 /************************************************
00058     Observables
00059 ************************************************/
00060 
00061 LLObservable::LLObservable()
00062         : mDispatcher(new LLEventDispatcher())
00063 {
00064 }
00065 
00066 // virtual
00067 LLObservable::~LLObservable()
00068 {
00069         if (mDispatcher.notNull())
00070         {
00071                 mDispatcher->disengage(this);
00072                 mDispatcher = NULL;
00073         }
00074 }
00075 
00076 // virtual
00077 bool LLObservable::setDispatcher(LLPointer<LLEventDispatcher> dispatcher)
00078 {
00079         if (mDispatcher.notNull())
00080         {
00081                 mDispatcher->disengage(this);
00082                 mDispatcher = NULL;
00083         }
00084         if (dispatcher.notNull() || dispatcher->engage(this))
00085         {
00086                 mDispatcher = dispatcher;
00087                 return true;
00088         }
00089         return false;
00090 }
00091 
00092 // Returns the current dispatcher pointer.
00093 // virtual
00094 LLEventDispatcher* LLObservable::getDispatcher()
00095 {
00096         return mDispatcher;
00097 }
00098 
00099 // Notifies the dispatcher of an event being fired.
00100 void LLObservable::fireEvent(LLPointer<LLEvent> event, LLSD filter)
00101 {
00102         if (mDispatcher.notNull())
00103         {
00104                 mDispatcher->fireEvent(event, filter);
00105         }
00106 }
00107 
00108 /************************************************
00109     Dispatchers
00110 ************************************************/
00111 
00112 class LLEventDispatcher::Impl
00113 {
00114 public:
00115         virtual ~Impl()                                                                                         {                               }
00116         virtual bool engage(LLObservable* observable)                           { return true;  }
00117         virtual void disengage(LLObservable* observable)                        {                               }
00118 
00119         virtual void addListener(LLEventListener *listener, LLSD filter, const LLSD& userdata) = 0;
00120         virtual void removeListener(LLEventListener *listener) = 0;
00121         virtual std::vector<LLListenerEntry> getListeners() const = 0;
00122         virtual bool fireEvent(LLPointer<LLEvent> event, LLSD filter) = 0;
00123 };
00124 
00125 bool LLEventDispatcher::engage(LLObservable* observable)
00126 {
00127         return impl->engage(observable);
00128 }
00129 
00130 void LLEventDispatcher::disengage(LLObservable* observable)
00131 {
00132         impl->disengage(observable);
00133 }
00134 
00135 void LLEventDispatcher::addListener(LLEventListener *listener, LLSD filter, const LLSD& userdata)
00136 {
00137         impl->addListener(listener, filter, userdata);
00138 }
00139 
00140 void LLEventDispatcher::removeListener(LLEventListener *listener)
00141 {
00142         impl->removeListener(listener);
00143 }
00144 
00145 std::vector<LLListenerEntry> LLEventDispatcher::getListeners() const
00146 {
00147         return impl->getListeners();
00148 }
00149 
00150 
00151 bool LLEventDispatcher::fireEvent(LLPointer<LLEvent> event, LLSD filter)
00152 {
00153         return impl->fireEvent(event, filter);
00154 }
00155 
00156 class LLSimpleDispatcher : public LLEventDispatcher::Impl
00157 {
00158 public:
00159         LLSimpleDispatcher(LLEventDispatcher *parent) : mParent(parent) { }
00160         virtual ~LLSimpleDispatcher();
00161         virtual void addListener(LLEventListener* listener, LLSD filter, const LLSD& userdata);
00162         virtual void removeListener(LLEventListener* listener);
00163         virtual std::vector<LLListenerEntry> getListeners() const;
00164         virtual bool fireEvent(LLPointer<LLEvent> event, LLSD filter);
00165 
00166 protected:
00167         std::vector<LLListenerEntry> mListeners;
00168         LLEventDispatcher *mParent;
00169 };
00170 
00171 LLSimpleDispatcher::~LLSimpleDispatcher()
00172 {
00173         while (mListeners.size() > 0)
00174         {
00175                 removeListener(mListeners.begin()->listener);
00176         }
00177 }
00178 
00179 void LLSimpleDispatcher::addListener(LLEventListener* listener, LLSD filter, const LLSD& userdata)
00180 {
00181         if (listener == NULL) return;
00182         removeListener(listener);
00183         LLListenerEntry new_entry;
00184         new_entry.listener = listener;
00185         new_entry.filter = filter;
00186         new_entry.userdata = userdata;
00187         mListeners.push_back(new_entry);
00188         listener->handleAttach(mParent);
00189 }
00190 
00191 void LLSimpleDispatcher::removeListener(LLEventListener* listener)
00192 {
00193         std::vector<LLListenerEntry>::iterator itor = mListeners.begin();
00194         std::vector<LLListenerEntry>::iterator end = mListeners.end();
00195         for (; itor != end; ++itor)
00196         {
00197                 if ((*itor).listener == listener)
00198                 {
00199                         mListeners.erase(itor);
00200                         break;
00201                 }
00202         }
00203         listener->handleDetach(mParent);
00204 }
00205 
00206 std::vector<LLListenerEntry> LLSimpleDispatcher::getListeners() const
00207 {
00208         std::vector<LLListenerEntry> ret;
00209         std::vector<LLListenerEntry>::const_iterator itor;
00210         for (itor=mListeners.begin(); itor!=mListeners.end(); ++itor)
00211         {
00212                 ret.push_back(*itor);
00213         }
00214         
00215         return ret;
00216 }
00217 
00218 // virtual
00219 bool LLSimpleDispatcher::fireEvent(LLPointer<LLEvent> event, LLSD filter)
00220 {
00221         std::vector<LLListenerEntry>::iterator itor;
00222         LLString filter_string = filter.asString();
00223         for (itor=mListeners.begin(); itor!=mListeners.end(); ++itor)
00224         {
00225                 LLListenerEntry& entry = *itor;
00226                 if (filter_string == "" || entry.filter.asString() == filter_string)
00227                 {
00228                         (entry.listener)->handleEvent(event, (*itor).userdata);
00229                 }
00230         }
00231         return true;
00232 }
00233 
00234 LLEventDispatcher::LLEventDispatcher()
00235 {
00236         impl = new LLSimpleDispatcher(this);
00237 }
00238 
00239 LLEventDispatcher::~LLEventDispatcher()
00240 {
00241         if (impl)
00242         {
00243                 delete impl;
00244                 impl = NULL;
00245         }
00246 }
00247 
00248 /************************************************
00249     Listeners
00250 ************************************************/
00251 
00252 LLEventListener::~LLEventListener()
00253 {
00254 }
00255 
00256 LLSimpleListener::~LLSimpleListener()
00257 {
00258         clearDispatchers();
00259 }
00260 
00261 void LLSimpleListener::clearDispatchers()
00262 {
00263         // Remove myself from all listening dispatchers
00264         std::vector<LLEventDispatcher *>::iterator itor;
00265         while (mDispatchers.size() > 0)
00266         {
00267                 itor = mDispatchers.begin();
00268                 LLEventDispatcher *dispatcher = *itor;
00269                 dispatcher->removeListener(this);
00270                 itor = mDispatchers.begin();
00271                 if (itor != mDispatchers.end() && (*itor) == dispatcher)
00272                 {
00273                         // Somehow, the dispatcher was not removed. Remove it forcibly
00274                         mDispatchers.erase(itor);
00275                 }
00276         }
00277 }
00278 
00279 bool LLSimpleListener::handleAttach(LLEventDispatcher *dispatcher)
00280 {
00281         // Add dispatcher if it doesn't already exist
00282         std::vector<LLEventDispatcher *>::iterator itor;
00283         for (itor = mDispatchers.begin(); itor != mDispatchers.end(); ++itor)
00284         {
00285                 if ((*itor) == dispatcher) return true;
00286         }
00287         mDispatchers.push_back(dispatcher);
00288         return true;
00289 }
00290 
00291 bool LLSimpleListener::handleDetach(LLEventDispatcher *dispatcher)
00292 {
00293         // Remove dispatcher from list
00294         std::vector<LLEventDispatcher *>::iterator itor;
00295         for (itor = mDispatchers.begin(); itor != mDispatchers.end(); )
00296         {
00297                 if ((*itor) == dispatcher)
00298                 {
00299                         itor = mDispatchers.erase(itor);
00300                 }
00301                 else
00302                 {
00303                         ++itor;
00304                 }
00305         }
00306         return true;
00307 }

Generated on Thu Jul 1 06:08:29 2010 for Second Life Viewer by  doxygen 1.4.7