PageRenderTime 32ms CodeModel.GetById 0ms RepoModel.GetById 0ms app.codeStats 0ms

/indra/llcommon/llevent.cpp

https://bitbucket.org/lindenlab/viewer-beta/
C++ | 304 lines | 215 code | 39 blank | 50 comment | 32 complexity | d7d49374ffe239722416d82fbd24e409 MD5 | raw file
Possible License(s): LGPL-2.1
  1. /**
  2. * @file llevent.cpp
  3. * @brief LLEvent and LLEventListener base classes.
  4. *
  5. * $LicenseInfo:firstyear=2006&license=viewerlgpl$
  6. * Second Life Viewer Source Code
  7. * Copyright (C) 2010, Linden Research, Inc.
  8. *
  9. * This library is free software; you can redistribute it and/or
  10. * modify it under the terms of the GNU Lesser General Public
  11. * License as published by the Free Software Foundation;
  12. * version 2.1 of the License only.
  13. *
  14. * This library is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  17. * Lesser General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU Lesser General Public
  20. * License along with this library; if not, write to the Free Software
  21. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  22. *
  23. * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
  24. * $/LicenseInfo$
  25. */
  26. #include "linden_common.h"
  27. #include "llevent.h"
  28. using namespace LLOldEvents;
  29. /************************************************
  30. Events
  31. ************************************************/
  32. // virtual
  33. LLEvent::~LLEvent()
  34. {
  35. }
  36. // virtual
  37. bool LLEvent::accept(LLEventListener* listener)
  38. {
  39. return true;
  40. }
  41. // virtual
  42. const std::string& LLEvent::desc()
  43. {
  44. return mDesc;
  45. }
  46. /************************************************
  47. Observables
  48. ************************************************/
  49. LLObservable::LLObservable()
  50. : mDispatcher(new LLEventDispatcher())
  51. {
  52. }
  53. // virtual
  54. LLObservable::~LLObservable()
  55. {
  56. if (mDispatcher.notNull())
  57. {
  58. mDispatcher->disengage(this);
  59. mDispatcher = NULL;
  60. }
  61. }
  62. // virtual
  63. bool LLObservable::setDispatcher(LLPointer<LLEventDispatcher> dispatcher)
  64. {
  65. if (mDispatcher.notNull())
  66. {
  67. mDispatcher->disengage(this);
  68. mDispatcher = NULL;
  69. }
  70. if (dispatcher.notNull() || dispatcher->engage(this))
  71. {
  72. mDispatcher = dispatcher;
  73. return true;
  74. }
  75. return false;
  76. }
  77. // Returns the current dispatcher pointer.
  78. // virtual
  79. LLEventDispatcher* LLObservable::getDispatcher()
  80. {
  81. return mDispatcher;
  82. }
  83. // Notifies the dispatcher of an event being fired.
  84. void LLObservable::fireEvent(LLPointer<LLEvent> event, LLSD filter)
  85. {
  86. if (mDispatcher.notNull())
  87. {
  88. mDispatcher->fireEvent(event, filter);
  89. }
  90. }
  91. /************************************************
  92. Dispatchers
  93. ************************************************/
  94. class LLEventDispatcher::Impl
  95. {
  96. public:
  97. virtual ~Impl() { }
  98. virtual bool engage(LLObservable* observable) { return true; }
  99. virtual void disengage(LLObservable* observable) { }
  100. virtual void addListener(LLEventListener *listener, LLSD filter, const LLSD& userdata) = 0;
  101. virtual void removeListener(LLEventListener *listener) = 0;
  102. virtual std::vector<LLListenerEntry> getListeners() const = 0;
  103. virtual bool fireEvent(LLPointer<LLEvent> event, LLSD filter) = 0;
  104. };
  105. bool LLEventDispatcher::engage(LLObservable* observable)
  106. {
  107. return impl->engage(observable);
  108. }
  109. void LLEventDispatcher::disengage(LLObservable* observable)
  110. {
  111. impl->disengage(observable);
  112. }
  113. void LLEventDispatcher::addListener(LLEventListener *listener, LLSD filter, const LLSD& userdata)
  114. {
  115. impl->addListener(listener, filter, userdata);
  116. }
  117. void LLEventDispatcher::removeListener(LLEventListener *listener)
  118. {
  119. impl->removeListener(listener);
  120. }
  121. std::vector<LLListenerEntry> LLEventDispatcher::getListeners() const
  122. {
  123. return impl->getListeners();
  124. }
  125. bool LLEventDispatcher::fireEvent(LLPointer<LLEvent> event, LLSD filter)
  126. {
  127. return impl->fireEvent(event, filter);
  128. }
  129. class LLSimpleDispatcher : public LLEventDispatcher::Impl
  130. {
  131. public:
  132. LLSimpleDispatcher(LLEventDispatcher *parent) : mParent(parent) { }
  133. virtual ~LLSimpleDispatcher();
  134. virtual void addListener(LLEventListener* listener, LLSD filter, const LLSD& userdata);
  135. virtual void removeListener(LLEventListener* listener);
  136. virtual std::vector<LLListenerEntry> getListeners() const;
  137. virtual bool fireEvent(LLPointer<LLEvent> event, LLSD filter);
  138. protected:
  139. std::vector<LLListenerEntry> mListeners;
  140. LLEventDispatcher *mParent;
  141. };
  142. LLSimpleDispatcher::~LLSimpleDispatcher()
  143. {
  144. while (mListeners.size() > 0)
  145. {
  146. removeListener(mListeners.begin()->listener);
  147. }
  148. }
  149. void LLSimpleDispatcher::addListener(LLEventListener* listener, LLSD filter, const LLSD& userdata)
  150. {
  151. if (listener == NULL) return;
  152. removeListener(listener);
  153. LLListenerEntry new_entry;
  154. new_entry.listener = listener;
  155. new_entry.filter = filter;
  156. new_entry.userdata = userdata;
  157. mListeners.push_back(new_entry);
  158. listener->handleAttach(mParent);
  159. }
  160. void LLSimpleDispatcher::removeListener(LLEventListener* listener)
  161. {
  162. std::vector<LLListenerEntry>::iterator itor = mListeners.begin();
  163. std::vector<LLListenerEntry>::iterator end = mListeners.end();
  164. for (; itor != end; ++itor)
  165. {
  166. if ((*itor).listener == listener)
  167. {
  168. mListeners.erase(itor);
  169. break;
  170. }
  171. }
  172. listener->handleDetach(mParent);
  173. }
  174. std::vector<LLListenerEntry> LLSimpleDispatcher::getListeners() const
  175. {
  176. std::vector<LLListenerEntry> ret;
  177. std::vector<LLListenerEntry>::const_iterator itor;
  178. for (itor=mListeners.begin(); itor!=mListeners.end(); ++itor)
  179. {
  180. ret.push_back(*itor);
  181. }
  182. return ret;
  183. }
  184. // virtual
  185. bool LLSimpleDispatcher::fireEvent(LLPointer<LLEvent> event, LLSD filter)
  186. {
  187. std::vector<LLListenerEntry>::iterator itor;
  188. std::string filter_string = filter.asString();
  189. for (itor=mListeners.begin(); itor!=mListeners.end(); ++itor)
  190. {
  191. LLListenerEntry& entry = *itor;
  192. if (filter_string == "" || entry.filter.asString() == filter_string)
  193. {
  194. (entry.listener)->handleEvent(event, (*itor).userdata);
  195. }
  196. }
  197. return true;
  198. }
  199. LLEventDispatcher::LLEventDispatcher()
  200. {
  201. impl = new LLSimpleDispatcher(this);
  202. }
  203. LLEventDispatcher::~LLEventDispatcher()
  204. {
  205. if (impl)
  206. {
  207. delete impl;
  208. impl = NULL;
  209. }
  210. }
  211. /************************************************
  212. Listeners
  213. ************************************************/
  214. LLEventListener::~LLEventListener()
  215. {
  216. }
  217. LLSimpleListener::~LLSimpleListener()
  218. {
  219. clearDispatchers();
  220. }
  221. void LLSimpleListener::clearDispatchers()
  222. {
  223. // Remove myself from all listening dispatchers
  224. std::vector<LLEventDispatcher *>::iterator itor;
  225. while (mDispatchers.size() > 0)
  226. {
  227. itor = mDispatchers.begin();
  228. LLEventDispatcher *dispatcher = *itor;
  229. dispatcher->removeListener(this);
  230. itor = mDispatchers.begin();
  231. if (itor != mDispatchers.end() && (*itor) == dispatcher)
  232. {
  233. // Somehow, the dispatcher was not removed. Remove it forcibly
  234. mDispatchers.erase(itor);
  235. }
  236. }
  237. }
  238. bool LLSimpleListener::handleAttach(LLEventDispatcher *dispatcher)
  239. {
  240. // Add dispatcher if it doesn't already exist
  241. std::vector<LLEventDispatcher *>::iterator itor;
  242. for (itor = mDispatchers.begin(); itor != mDispatchers.end(); ++itor)
  243. {
  244. if ((*itor) == dispatcher) return true;
  245. }
  246. mDispatchers.push_back(dispatcher);
  247. return true;
  248. }
  249. bool LLSimpleListener::handleDetach(LLEventDispatcher *dispatcher)
  250. {
  251. // Remove dispatcher from list
  252. std::vector<LLEventDispatcher *>::iterator itor;
  253. for (itor = mDispatchers.begin(); itor != mDispatchers.end(); )
  254. {
  255. if ((*itor) == dispatcher)
  256. {
  257. itor = mDispatchers.erase(itor);
  258. }
  259. else
  260. {
  261. ++itor;
  262. }
  263. }
  264. return true;
  265. }