aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/llcommon/llevent.cpp
diff options
context:
space:
mode:
authorJacek Antonelli2008-08-15 23:44:46 -0500
committerJacek Antonelli2008-08-15 23:44:46 -0500
commit38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4 (patch)
treeadca584755d22ca041a2dbfc35d4eca01f70b32c /linden/indra/llcommon/llevent.cpp
parentREADME.txt (diff)
downloadmeta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.zip
meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.gz
meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.bz2
meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.xz
Second Life viewer sources 1.13.2.12
Diffstat (limited to 'linden/indra/llcommon/llevent.cpp')
-rw-r--r--linden/indra/llcommon/llevent.cpp304
1 files changed, 304 insertions, 0 deletions
diff --git a/linden/indra/llcommon/llevent.cpp b/linden/indra/llcommon/llevent.cpp
new file mode 100644
index 0000000..e9b6a51
--- /dev/null
+++ b/linden/indra/llcommon/llevent.cpp
@@ -0,0 +1,304 @@
1/**
2 * @file llevent.cpp
3 * @brief LLEvent and LLEventListener base classes.
4 *
5 * Copyright (c) 2006-2007, Linden Research, Inc.
6 *
7 * The source code in this file ("Source Code") is provided by Linden Lab
8 * to you under the terms of the GNU General Public License, version 2.0
9 * ("GPL"), unless you have obtained a separate licensing agreement
10 * ("Other License"), formally executed by you and Linden Lab. Terms of
11 * the GPL can be found in doc/GPL-license.txt in this distribution, or
12 * online at http://secondlife.com/developers/opensource/gplv2
13 *
14 * There are special exceptions to the terms and conditions of the GPL as
15 * it is applied to this Source Code. View the full text of the exception
16 * in the file doc/FLOSS-exception.txt in this software distribution, or
17 * online at http://secondlife.com/developers/opensource/flossexception
18 *
19 * By copying, modifying or distributing this software, you acknowledge
20 * that you have read and understood your obligations described above,
21 * and agree to abide by those obligations.
22 *
23 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
24 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
25 * COMPLETENESS OR PERFORMANCE.
26 */
27
28#include "linden_common.h"
29
30#include "llevent.h"
31
32/************************************************
33 Events
34************************************************/
35
36// virtual
37LLEvent::~LLEvent()
38{
39}
40
41// virtual
42bool LLEvent::accept(LLEventListener* listener)
43{
44 return true;
45}
46
47// virtual
48const std::string& LLEvent::desc()
49{
50 return mDesc;
51}
52
53/************************************************
54 Observables
55************************************************/
56
57LLObservable::LLObservable()
58 : mDispatcher(new LLEventDispatcher())
59{
60}
61
62// virtual
63LLObservable::~LLObservable()
64{
65 if (mDispatcher.notNull())
66 {
67 mDispatcher->disengage(this);
68 mDispatcher = NULL;
69 }
70}
71
72// virtual
73bool LLObservable::setDispatcher(LLPointer<LLEventDispatcher> dispatcher)
74{
75 if (mDispatcher.notNull())
76 {
77 mDispatcher->disengage(this);
78 mDispatcher = NULL;
79 }
80 if (dispatcher.notNull() || dispatcher->engage(this))
81 {
82 mDispatcher = dispatcher;
83 return true;
84 }
85 return false;
86}
87
88// Returns the current dispatcher pointer.
89// virtual
90LLEventDispatcher* LLObservable::getDispatcher()
91{
92 return mDispatcher;
93}
94
95// Notifies the dispatcher of an event being fired.
96void LLObservable::fireEvent(LLPointer<LLEvent> event, LLSD filter)
97{
98 if (mDispatcher.notNull())
99 {
100 mDispatcher->fireEvent(event, filter);
101 }
102}
103
104/************************************************
105 Dispatchers
106************************************************/
107
108class LLEventDispatcher::Impl
109{
110public:
111 virtual ~Impl() { }
112 virtual bool engage(LLObservable* observable) { return true; }
113 virtual void disengage(LLObservable* observable) { }
114
115 virtual void addListener(LLEventListener *listener, LLSD filter, const LLSD& userdata) = 0;
116 virtual void removeListener(LLEventListener *listener) = 0;
117 virtual std::vector<LLListenerEntry> getListeners() const = 0;
118 virtual bool fireEvent(LLPointer<LLEvent> event, LLSD filter) = 0;
119};
120
121bool LLEventDispatcher::engage(LLObservable* observable)
122{
123 return impl->engage(observable);
124}
125
126void LLEventDispatcher::disengage(LLObservable* observable)
127{
128 impl->disengage(observable);
129}
130
131void LLEventDispatcher::addListener(LLEventListener *listener, LLSD filter, const LLSD& userdata)
132{
133 impl->addListener(listener, filter, userdata);
134}
135
136void LLEventDispatcher::removeListener(LLEventListener *listener)
137{
138 impl->removeListener(listener);
139}
140
141std::vector<LLListenerEntry> LLEventDispatcher::getListeners() const
142{
143 return impl->getListeners();
144}
145
146
147bool LLEventDispatcher::fireEvent(LLPointer<LLEvent> event, LLSD filter)
148{
149 return impl->fireEvent(event, filter);
150}
151
152class LLSimpleDispatcher : public LLEventDispatcher::Impl
153{
154public:
155 LLSimpleDispatcher(LLEventDispatcher *parent) : mParent(parent) { }
156 virtual ~LLSimpleDispatcher();
157 virtual void addListener(LLEventListener* listener, LLSD filter, const LLSD& userdata);
158 virtual void removeListener(LLEventListener* listener);
159 virtual std::vector<LLListenerEntry> getListeners() const;
160 virtual bool fireEvent(LLPointer<LLEvent> event, LLSD filter);
161
162protected:
163 std::vector<LLListenerEntry> mListeners;
164 LLEventDispatcher *mParent;
165};
166
167LLSimpleDispatcher::~LLSimpleDispatcher()
168{
169 while (mListeners.size() > 0)
170 {
171 removeListener(mListeners.begin()->listener);
172 }
173}
174
175void LLSimpleDispatcher::addListener(LLEventListener* listener, LLSD filter, const LLSD& userdata)
176{
177 if (listener == NULL) return;
178 removeListener(listener);
179 LLListenerEntry new_entry;
180 new_entry.listener = listener;
181 new_entry.filter = filter;
182 new_entry.userdata = userdata;
183 mListeners.push_back(new_entry);
184 listener->handleAttach(mParent);
185}
186
187void LLSimpleDispatcher::removeListener(LLEventListener* listener)
188{
189 std::vector<LLListenerEntry>::iterator itor;
190 for (itor=mListeners.begin(); itor!=mListeners.end();)
191 {
192 if ((*itor).listener == listener)
193 {
194 mListeners.erase(itor);
195 }
196 else
197 {
198 ++itor;
199 }
200 }
201 listener->handleDetach(mParent);
202}
203
204std::vector<LLListenerEntry> LLSimpleDispatcher::getListeners() const
205{
206 std::vector<LLListenerEntry> ret;
207 std::vector<LLListenerEntry>::const_iterator itor;
208 for (itor=mListeners.begin(); itor!=mListeners.end(); ++itor)
209 {
210 ret.push_back(*itor);
211 }
212
213 return ret;
214}
215
216// virtual
217bool LLSimpleDispatcher::fireEvent(LLPointer<LLEvent> event, LLSD filter)
218{
219 std::vector<LLListenerEntry>::iterator itor;
220 LLString filter_string = filter.asString();
221 for (itor=mListeners.begin(); itor!=mListeners.end(); ++itor)
222 {
223 LLListenerEntry& entry = *itor;
224 if (filter_string == "" || entry.filter.asString() == filter_string)
225 {
226 (entry.listener)->handleEvent(event, (*itor).userdata);
227 }
228 }
229 return true;
230}
231
232LLEventDispatcher::LLEventDispatcher()
233{
234 impl = new LLSimpleDispatcher(this);
235}
236
237LLEventDispatcher::~LLEventDispatcher()
238{
239 if (impl)
240 {
241 delete impl;
242 }
243}
244
245/************************************************
246 Listeners
247************************************************/
248
249LLEventListener::~LLEventListener()
250{
251}
252
253LLSimpleListener::~LLSimpleListener()
254{
255 clearDispatchers();
256}
257
258void LLSimpleListener::clearDispatchers()
259{
260 // Remove myself from all listening dispatchers
261 std::vector<LLEventDispatcher *>::iterator itor;
262 while (mDispatchers.size() > 0)
263 {
264 itor = mDispatchers.begin();
265 LLEventDispatcher *dispatcher = *itor;
266 dispatcher->removeListener(this);
267 itor = mDispatchers.begin();
268 if (itor != mDispatchers.end() && (*itor) == dispatcher)
269 {
270 // Somehow, the dispatcher was not removed. Remove it forcibly
271 mDispatchers.erase(itor);
272 }
273 }
274}
275
276bool LLSimpleListener::handleAttach(LLEventDispatcher *dispatcher)
277{
278 // Add dispatcher if it doesn't already exist
279 std::vector<LLEventDispatcher *>::iterator itor;
280 for (itor = mDispatchers.begin(); itor != mDispatchers.end(); ++itor)
281 {
282 if ((*itor) == dispatcher) return true;
283 }
284 mDispatchers.push_back(dispatcher);
285 return true;
286}
287
288bool LLSimpleListener::handleDetach(LLEventDispatcher *dispatcher)
289{
290 // Remove dispatcher from list
291 std::vector<LLEventDispatcher *>::iterator itor;
292 for (itor = mDispatchers.begin(); itor != mDispatchers.end(); )
293 {
294 if ((*itor) == dispatcher)
295 {
296 itor = mDispatchers.erase(itor);
297 }
298 else
299 {
300 ++itor;
301 }
302 }
303 return true;
304}