00001 00031 #ifndef LL_LLTREENODE_H 00032 #define LL_LLTREENODE_H 00033 00034 #include "stdtypes.h" 00035 #include "xform.h" 00036 #include <vector> 00037 00038 template <class T> class LLTreeNode; 00039 template <class T> class LLTreeTraveler; 00040 template <class T> class LLTreeListener; 00041 00042 template <class T> 00043 class LLTreeState 00044 { 00045 public: 00046 LLTreeState(LLTreeNode<T>* node) { setNode(node); } 00047 virtual ~LLTreeState() { }; 00048 virtual bool insert(T* data) = 0; 00049 virtual bool remove(T* data) = 0; 00050 virtual void setNode(LLTreeNode<T>* node); 00051 virtual const LLTreeNode<T>* getNode() const { return mNode; } 00052 virtual LLTreeNode<T>* getNode() { return mNode; } 00053 virtual void accept(LLTreeTraveler<T>* traveler) const = 0; 00054 virtual LLTreeListener<T>* getListener(U32 index) const; 00055 private: 00056 LLTreeNode<T>* mNode; 00057 }; 00058 00059 template <class T> 00060 class LLTreeListener: public LLRefCount 00061 { 00062 public: 00063 virtual void handleInsertion(const LLTreeNode<T>* node, T* data) = 0; 00064 virtual void handleRemoval(const LLTreeNode<T>* node, T* data) = 0; 00065 virtual void handleDestruction(const LLTreeNode<T>* node) = 0; 00066 virtual void handleStateChange(const LLTreeNode<T>* node) = 0; 00067 }; 00068 00069 template <class T> 00070 class LLTreeNode 00071 { 00072 public: 00073 LLTreeNode(LLTreeState<T>* state) { setState(state); } 00074 virtual ~LLTreeNode(); 00075 LLTreeState<T>* getState() { return mState; } 00076 const LLTreeState<T>* getState() const { return mState; } 00077 00078 void setState(LLTreeState<T>* state); 00079 void insert(T* data); 00080 bool remove(T* data); 00081 void notifyRemoval(T* data); 00082 inline U32 getListenerCount() { return mListeners.size(); } 00083 inline LLTreeListener<T>* getListener(U32 index) const { return mListeners[index]; } 00084 inline void addListener(LLTreeListener<T>* listener) { mListeners.push_back(listener); } 00085 inline void removeListener(U32 index) { mListeners.erase(mListeners.begin()+index); } 00086 00087 protected: 00088 void destroyListeners() 00089 { 00090 for (U32 i = 0; i < mListeners.size(); i++) 00091 { 00092 mListeners[i]->handleDestruction(this); 00093 } 00094 mListeners.clear(); 00095 } 00096 00097 LLTreeState<T>* mState; 00098 public: 00099 std::vector<LLPointer<LLTreeListener<T> > > mListeners; 00100 }; 00101 00102 template <class T> 00103 class LLTreeTraveler 00104 { 00105 public: 00106 virtual ~LLTreeTraveler() { }; 00107 virtual void traverse(const LLTreeNode<T>* node) = 0; 00108 virtual void visit(const LLTreeState<T>* state) = 0; 00109 }; 00110 00111 template <class T> 00112 LLTreeNode<T>::~LLTreeNode() 00113 { 00114 destroyListeners(); 00115 }; 00116 00117 template <class T> 00118 void LLTreeNode<T>::insert(T* data) 00119 { 00120 if (mState->insert(data)) 00121 { 00122 for (U32 i = 0; i < mListeners.size(); i++) 00123 { 00124 mListeners[i]->handleInsertion(this, data); 00125 } 00126 } 00127 }; 00128 00129 template <class T> 00130 bool LLTreeNode<T>::remove(T* data) 00131 { 00132 if (mState->remove(data)) 00133 { 00134 return true; 00135 } 00136 return false; 00137 }; 00138 00139 template <class T> 00140 void LLTreeNode<T>::notifyRemoval(T* data) 00141 { 00142 for (U32 i = 0; i < mListeners.size(); i++) 00143 { 00144 mListeners[i]->handleRemoval(this, data); 00145 } 00146 } 00147 00148 template <class T> 00149 void LLTreeNode<T>::setState(LLTreeState<T>* state) 00150 { 00151 mState = state; 00152 if (state) 00153 { 00154 if (state->getNode() != this) 00155 { 00156 state->setNode(this); 00157 } 00158 00159 for (U32 i = 0; i < mListeners.size(); i++) 00160 { 00161 mListeners[i]->handleStateChange(this); 00162 } 00163 } 00164 }; 00165 00166 template <class T> 00167 void LLTreeState<T>::setNode(LLTreeNode<T>* node) 00168 { 00169 mNode = node; 00170 if (node && node->getState() != this) 00171 { 00172 node->setState(this); 00173 } 00174 }; 00175 00176 template <class T> 00177 LLTreeListener<T>* LLTreeState<T>::getListener(U32 index) const 00178 { 00179 return mNode->getListener(index); 00180 } 00181 00182 #endif