diff options
author | Jacek Antonelli | 2008-08-15 23:44:46 -0500 |
---|---|---|
committer | Jacek Antonelli | 2008-08-15 23:44:46 -0500 |
commit | 38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4 (patch) | |
tree | adca584755d22ca041a2dbfc35d4eca01f70b32c /linden/indra/llcommon/llevent.cpp | |
parent | README.txt (diff) | |
download | meta-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.cpp | 304 |
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 | ||
37 | LLEvent::~LLEvent() | ||
38 | { | ||
39 | } | ||
40 | |||
41 | // virtual | ||
42 | bool LLEvent::accept(LLEventListener* listener) | ||
43 | { | ||
44 | return true; | ||
45 | } | ||
46 | |||
47 | // virtual | ||
48 | const std::string& LLEvent::desc() | ||
49 | { | ||
50 | return mDesc; | ||
51 | } | ||
52 | |||
53 | /************************************************ | ||
54 | Observables | ||
55 | ************************************************/ | ||
56 | |||
57 | LLObservable::LLObservable() | ||
58 | : mDispatcher(new LLEventDispatcher()) | ||
59 | { | ||
60 | } | ||
61 | |||
62 | // virtual | ||
63 | LLObservable::~LLObservable() | ||
64 | { | ||
65 | if (mDispatcher.notNull()) | ||
66 | { | ||
67 | mDispatcher->disengage(this); | ||
68 | mDispatcher = NULL; | ||
69 | } | ||
70 | } | ||
71 | |||
72 | // virtual | ||
73 | bool 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 | ||
90 | LLEventDispatcher* LLObservable::getDispatcher() | ||
91 | { | ||
92 | return mDispatcher; | ||
93 | } | ||
94 | |||
95 | // Notifies the dispatcher of an event being fired. | ||
96 | void 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 | |||
108 | class LLEventDispatcher::Impl | ||
109 | { | ||
110 | public: | ||
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 | |||
121 | bool LLEventDispatcher::engage(LLObservable* observable) | ||
122 | { | ||
123 | return impl->engage(observable); | ||
124 | } | ||
125 | |||
126 | void LLEventDispatcher::disengage(LLObservable* observable) | ||
127 | { | ||
128 | impl->disengage(observable); | ||
129 | } | ||
130 | |||
131 | void LLEventDispatcher::addListener(LLEventListener *listener, LLSD filter, const LLSD& userdata) | ||
132 | { | ||
133 | impl->addListener(listener, filter, userdata); | ||
134 | } | ||
135 | |||
136 | void LLEventDispatcher::removeListener(LLEventListener *listener) | ||
137 | { | ||
138 | impl->removeListener(listener); | ||
139 | } | ||
140 | |||
141 | std::vector<LLListenerEntry> LLEventDispatcher::getListeners() const | ||
142 | { | ||
143 | return impl->getListeners(); | ||
144 | } | ||
145 | |||
146 | |||
147 | bool LLEventDispatcher::fireEvent(LLPointer<LLEvent> event, LLSD filter) | ||
148 | { | ||
149 | return impl->fireEvent(event, filter); | ||
150 | } | ||
151 | |||
152 | class LLSimpleDispatcher : public LLEventDispatcher::Impl | ||
153 | { | ||
154 | public: | ||
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 | |||
162 | protected: | ||
163 | std::vector<LLListenerEntry> mListeners; | ||
164 | LLEventDispatcher *mParent; | ||
165 | }; | ||
166 | |||
167 | LLSimpleDispatcher::~LLSimpleDispatcher() | ||
168 | { | ||
169 | while (mListeners.size() > 0) | ||
170 | { | ||
171 | removeListener(mListeners.begin()->listener); | ||
172 | } | ||
173 | } | ||
174 | |||
175 | void 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 | |||
187 | void 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 | |||
204 | std::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 | ||
217 | bool 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 | |||
232 | LLEventDispatcher::LLEventDispatcher() | ||
233 | { | ||
234 | impl = new LLSimpleDispatcher(this); | ||
235 | } | ||
236 | |||
237 | LLEventDispatcher::~LLEventDispatcher() | ||
238 | { | ||
239 | if (impl) | ||
240 | { | ||
241 | delete impl; | ||
242 | } | ||
243 | } | ||
244 | |||
245 | /************************************************ | ||
246 | Listeners | ||
247 | ************************************************/ | ||
248 | |||
249 | LLEventListener::~LLEventListener() | ||
250 | { | ||
251 | } | ||
252 | |||
253 | LLSimpleListener::~LLSimpleListener() | ||
254 | { | ||
255 | clearDispatchers(); | ||
256 | } | ||
257 | |||
258 | void 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 | |||
276 | bool 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 | |||
288 | bool 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 | } | ||