aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/llmath/lltreenode.h
diff options
context:
space:
mode:
Diffstat (limited to 'linden/indra/llmath/lltreenode.h')
-rw-r--r--linden/indra/llmath/lltreenode.h180
1 files changed, 180 insertions, 0 deletions
diff --git a/linden/indra/llmath/lltreenode.h b/linden/indra/llmath/lltreenode.h
new file mode 100644
index 0000000..78ff759
--- /dev/null
+++ b/linden/indra/llmath/lltreenode.h
@@ -0,0 +1,180 @@
1/**
2 * @file lltreenode.h
3 *
4 * Copyright (c) 2005-2007, Linden Research, Inc.
5 *
6 * The source code in this file ("Source Code") is provided by Linden Lab
7 * to you under the terms of the GNU General Public License, version 2.0
8 * ("GPL"), unless you have obtained a separate licensing agreement
9 * ("Other License"), formally executed by you and Linden Lab. Terms of
10 * the GPL can be found in doc/GPL-license.txt in this distribution, or
11 * online at http://secondlife.com/developers/opensource/gplv2
12 *
13 * There are special exceptions to the terms and conditions of the GPL as
14 * it is applied to this Source Code. View the full text of the exception
15 * in the file doc/FLOSS-exception.txt in this software distribution, or
16 * online at http://secondlife.com/developers/opensource/flossexception
17 *
18 * By copying, modifying or distributing this software, you acknowledge
19 * that you have read and understood your obligations described above,
20 * and agree to abide by those obligations.
21 *
22 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
23 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
24 * COMPLETENESS OR PERFORMANCE.
25 */
26
27#ifndef LL_LLTREENODE_H
28#define LL_LLTREENODE_H
29
30#include "stdtypes.h"
31#include "xform.h"
32#include <vector>
33
34template <class T> class LLTreeNode;
35template <class T> class LLTreeTraveler;
36template <class T> class LLTreeListener;
37
38template <class T>
39class LLTreeState
40{
41public:
42 LLTreeState(LLTreeNode<T>* node) { setNode(node); }
43 virtual ~LLTreeState() { };
44
45 virtual bool insert(T* data) = 0;
46 virtual bool remove(T* data) = 0;
47 virtual void setNode(LLTreeNode<T>* node);
48 virtual const LLTreeNode<T>* getNode() const { return mNode; }
49 virtual LLTreeNode<T>* getNode() { return mNode; }
50 virtual void accept(LLTreeTraveler<T>* traveler) const = 0;
51 virtual LLTreeListener<T>* getListener(U32 index) const;
52private:
53 LLTreeNode<T>* mNode;
54};
55
56template <class T>
57class LLTreeListener
58{
59public:
60 virtual ~LLTreeListener() { };
61 virtual void handleInsertion(const LLTreeNode<T>* node, T* data) = 0;
62 virtual void handleRemoval(const LLTreeNode<T>* node, T* data) = 0;
63 virtual void handleDestruction(const LLTreeNode<T>* node) = 0;
64 virtual void handleStateChange(const LLTreeNode<T>* node) = 0;
65};
66
67template <class T>
68class LLTreeNode
69{
70public:
71 LLTreeNode(LLTreeState<T>* state) { setState(state); }
72 virtual ~LLTreeNode();
73 virtual LLTreeState<T>* getState() { return mState; }
74 virtual const LLTreeState<T>* getState() const { return mState; }
75
76 virtual void setState(LLTreeState<T>* state);
77 virtual void insert(T* data);
78 virtual bool remove(T* data);
79 virtual void notifyRemoval(T* data);
80 virtual U32 getListenerCount() { return mListeners.size(); }
81 virtual LLTreeListener<T>* getListener(U32 index) const { return mListeners[index]; }
82 virtual void addListener(LLTreeListener<T>* listener) { mListeners.push_back(listener); }
83 virtual void removeListener(U32 index) { mListeners.erase(mListeners.begin()+index); }
84
85protected:
86 void destroyListeners()
87 {
88 for (U32 i = 0; i < mListeners.size(); i++)
89 {
90 mListeners[i]->handleDestruction(this);
91 }
92 mListeners.clear();
93 }
94
95 LLTreeState<T>* mState;
96public:
97 std::vector<LLTreeListener<T>*> mListeners;
98};
99
100template <class T>
101class LLTreeTraveler
102{
103public:
104 virtual ~LLTreeTraveler() { };
105 virtual void traverse(const LLTreeNode<T>* node) = 0;
106 virtual void visit(const LLTreeState<T>* state) = 0;
107};
108
109template <class T>
110LLTreeNode<T>::~LLTreeNode()
111{
112 destroyListeners();
113};
114
115template <class T>
116void LLTreeNode<T>::insert(T* data)
117{
118 if (mState->insert(data))
119 {
120 for (U32 i = 0; i < mListeners.size(); i++)
121 {
122 mListeners[i]->handleInsertion(this, data);
123 }
124 }
125};
126
127template <class T>
128bool LLTreeNode<T>::remove(T* data)
129{
130 if (mState->remove(data))
131 {
132 return true;
133 }
134 return false;
135};
136
137template <class T>
138void LLTreeNode<T>::notifyRemoval(T* data)
139{
140 for (U32 i = 0; i < mListeners.size(); i++)
141 {
142 mListeners[i]->handleRemoval(this, data);
143 }
144}
145
146template <class T>
147void LLTreeNode<T>::setState(LLTreeState<T>* state)
148{
149 mState = state;
150 if (state)
151 {
152 if (state->getNode() != this)
153 {
154 state->setNode(this);
155 }
156
157 for (U32 i = 0; i < mListeners.size(); i++)
158 {
159 mListeners[i]->handleStateChange(this);
160 }
161 }
162};
163
164template <class T>
165void LLTreeState<T>::setNode(LLTreeNode<T>* node)
166{
167 mNode = node;
168 if (node && node->getState() != this)
169 {
170 node->setState(this);
171 }
172};
173
174template <class T>
175LLTreeListener<T>* LLTreeState<T>::getListener(U32 index) const
176{
177 return mNode->getListener(index);
178}
179
180#endif