traverselib.h
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #if !defined (INCLUDED_TRAVERSELIB_H)
00023 #define INCLUDED_TRAVERSELIB_H
00024
00025 #include "debugging/debugging.h"
00026
00027 #include "scenelib.h"
00028 #include "undolib.h"
00029 #include "container/container.h"
00030
00031 #include <list>
00032 #include <vector>
00033 #include <algorithm>
00034 #include <cassert>
00035
00036 class TraversableObserverInsertOutputIterator
00037 {
00038 protected:
00039 scene::Traversable::Observer* m_observer;
00040 public:
00041 typedef std::output_iterator_tag iterator_category;
00042 typedef void difference_type;
00043 typedef void value_type;
00044 typedef void pointer;
00045 typedef void reference;
00046
00047 TraversableObserverInsertOutputIterator (scene::Traversable::Observer* observer) :
00048 m_observer(observer)
00049 {
00050 }
00051 TraversableObserverInsertOutputIterator& operator= (const NodeReference& node)
00052 {
00053 m_observer->insert(node);
00054 return *this;
00055 }
00056 TraversableObserverInsertOutputIterator& operator= (const NodeSmartReference& node)
00057 {
00058 m_observer->insert(node);
00059 return *this;
00060 }
00061 TraversableObserverInsertOutputIterator& operator* ()
00062 {
00063 return *this;
00064 }
00065 TraversableObserverInsertOutputIterator& operator++ ()
00066 {
00067 return *this;
00068 }
00069 TraversableObserverInsertOutputIterator& operator++ (int)
00070 {
00071 return *this;
00072 }
00073 };
00074
00075 class TraversableObserverEraseOutputIterator
00076 {
00077 protected:
00078 scene::Traversable::Observer* m_observer;
00079 public:
00080 typedef std::output_iterator_tag iterator_category;
00081 typedef void difference_type;
00082 typedef void value_type;
00083 typedef void pointer;
00084 typedef void reference;
00085
00086 TraversableObserverEraseOutputIterator (scene::Traversable::Observer* observer) :
00087 m_observer(observer)
00088 {
00089 }
00090 TraversableObserverEraseOutputIterator& operator= (const NodeReference& node)
00091 {
00092 m_observer->erase(node);
00093 return *this;
00094 }
00095 TraversableObserverEraseOutputIterator& operator= (const NodeSmartReference& node)
00096 {
00097 m_observer->erase(node);
00098 return *this;
00099 }
00100 TraversableObserverEraseOutputIterator& operator* ()
00101 {
00102 return *this;
00103 }
00104 TraversableObserverEraseOutputIterator& operator++ ()
00105 {
00106 return *this;
00107 }
00108 TraversableObserverEraseOutputIterator& operator++ (int)
00109 {
00110 return *this;
00111 }
00112 };
00113 typedef UnsortedSet<NodeSmartReference> UnsortedNodeSet;
00114
00116 inline void nodeset_diff (const UnsortedNodeSet& self, const UnsortedNodeSet& other,
00117 scene::Traversable::Observer* observer)
00118 {
00119 std::vector<NodeSmartReference> sorted(self.begin(), self.end());
00120 std::vector<NodeSmartReference> other_sorted(other.begin(), other.end());
00121
00122 std::sort(sorted.begin(), sorted.end());
00123 std::sort(other_sorted.begin(), other_sorted.end());
00124
00125 std::set_difference(sorted.begin(), sorted.end(), other_sorted.begin(), other_sorted.end(),
00126 TraversableObserverEraseOutputIterator(observer));
00127 std::set_difference(other_sorted.begin(), other_sorted.end(), sorted.begin(), sorted.end(),
00128 TraversableObserverInsertOutputIterator(observer));
00129 }
00130
00132 class TraversableNodeSet: public scene::Traversable
00133 {
00134 UnsortedNodeSet m_children;
00135 UndoableObject<TraversableNodeSet> m_undo;
00136 Observer* m_observer;
00137
00138 void copy (const TraversableNodeSet& other)
00139 {
00140 m_children = other.m_children;
00141 }
00142 void notifyInsertAll ()
00143 {
00144 if (m_observer) {
00145 for (UnsortedNodeSet::iterator i = m_children.begin(); i != m_children.end(); ++i) {
00146 m_observer->insert(*i);
00147 }
00148 }
00149 }
00150 void notifyEraseAll ()
00151 {
00152 if (m_observer) {
00153 for (UnsortedNodeSet::iterator i = m_children.begin(); i != m_children.end(); ++i) {
00154 m_observer->erase(*i);
00155 }
00156 }
00157 }
00158 public:
00159 TraversableNodeSet () :
00160 m_undo(*this), m_observer(0)
00161 {
00162 }
00163 TraversableNodeSet (const TraversableNodeSet& other) :
00164 scene::Traversable(other), m_undo(*this), m_observer(0)
00165 {
00166 copy(other);
00167 notifyInsertAll();
00168 }
00169 ~TraversableNodeSet ()
00170 {
00171 notifyEraseAll();
00172 }
00173 TraversableNodeSet& operator= (const TraversableNodeSet& other)
00174 {
00175
00176 if (m_observer) {
00177 nodeset_diff(m_children, other.m_children, m_observer);
00178 }
00179 copy(other);
00180 return *this;
00181 }
00182 void swap (TraversableNodeSet& other)
00183 {
00184 std::swap(m_children, other.m_children);
00185 std::swap(m_observer, other.m_observer);
00186 }
00187
00188 void attach (Observer* observer)
00189 {
00190 ASSERT_MESSAGE(m_observer == 0, "TraversableNodeSet::attach: observer cannot be attached");
00191 m_observer = observer;
00192 notifyInsertAll();
00193 }
00194 void detach (Observer* observer)
00195 {
00196 ASSERT_MESSAGE(m_observer == observer, "TraversableNodeSet::detach: observer cannot be detached");
00197 notifyEraseAll();
00198 m_observer = 0;
00199 }
00201 void insert (scene::Node& node)
00202 {
00203 ASSERT_MESSAGE(&node != 0, "TraversableNodeSet::insert: sanity check failed");
00204 m_undo.save();
00205
00206 ASSERT_MESSAGE(m_children.find(NodeSmartReference(node)) == m_children.end(), "TraversableNodeSet::insert - element already exists");
00207
00208 m_children.insert(NodeSmartReference(node));
00209
00210 if (m_observer) {
00211 m_observer->insert(node);
00212 }
00213 }
00215 void erase (scene::Node& node)
00216 {
00217 ASSERT_MESSAGE(&node != 0, "TraversableNodeSet::erase: sanity check failed");
00218 m_undo.save();
00219
00220 ASSERT_MESSAGE(m_children.find(NodeSmartReference(node)) != m_children.end(), "TraversableNodeSet::erase - failed to find element");
00221
00222 if (m_observer) {
00223 m_observer->erase(node);
00224 }
00225
00226 m_children.erase(NodeSmartReference(node));
00227 }
00229 void traverse (const Walker& walker)
00230 {
00231 UnsortedNodeSet::iterator i = m_children.begin();
00232 while (i != m_children.end()) {
00233
00234 Node_traverseSubgraph(*i++, walker);
00235
00236
00237 }
00238 }
00240 bool empty () const
00241 {
00242 return m_children.empty();
00243 }
00244
00245 void instanceAttach (MapFile* map)
00246 {
00247 m_undo.instanceAttach(map);
00248 }
00249 void instanceDetach (MapFile* map)
00250 {
00251 m_undo.instanceDetach(map);
00252 }
00253 };
00254
00255 namespace std
00256 {
00259 inline void swap (TraversableNodeSet& self, TraversableNodeSet& other)
00260 {
00261 self.swap(other);
00262 }
00263 }
00264
00266 class TraversableNode: public scene::Traversable
00267 {
00268 public:
00269 TraversableNode () :
00270 m_node(0), m_observer(0)
00271 {
00272 }
00273
00274
00275 void attach (Observer* observer)
00276 {
00277 ASSERT_MESSAGE(m_observer == 0, "TraversableNode::attach - cannot attach observer");
00278 m_observer = observer;
00279 if (m_node != 0) {
00280 m_observer->insert(*m_node);
00281 }
00282 }
00283 void detach (Observer* observer)
00284 {
00285 ASSERT_MESSAGE(m_observer == observer, "TraversableNode::detach - cannot detach observer");
00286 if (m_node != 0) {
00287 m_observer->erase(*m_node);
00288 }
00289 m_observer = 0;
00290 }
00292 void insert (scene::Node& node)
00293 {
00294
00295 assert(m_node == 0);
00296
00297 m_node = &node;
00298 node.IncRef();
00299
00300 if (m_observer != 0) {
00301 m_observer->insert(node);
00302 }
00303 }
00304 void erase (scene::Node& node)
00305 {
00306 assert(m_node == &node);
00307
00308 if (m_observer != 0) {
00309 m_observer->erase(node);
00310 }
00311
00312 m_node = 0;
00313 node.DecRef();
00314 }
00315 void traverse (const scene::Traversable::Walker& walker)
00316 {
00317 if (m_node != 0) {
00318 Node_traverseSubgraph(*m_node, walker);
00319 }
00320 }
00321 bool empty () const
00322 {
00323 return m_node != 0;
00324 }
00325
00326 scene::Node& get ()
00327 {
00328 return *m_node;
00329 }
00330
00331 private:
00332 scene::Node* m_node;
00333 Observer* m_observer;
00334 };
00335
00336 class TraversableObserverInsert
00337 {
00338 scene::Node& node;
00339 public:
00340 TraversableObserverInsert (scene::Node& node) :
00341 node(node)
00342 {
00343 }
00344 void operator() (scene::Traversable::Observer& observer) const
00345 {
00346 observer.insert(node);
00347 }
00348 };
00349
00350 class TraversableObserverErase
00351 {
00352 scene::Node& node;
00353 public:
00354 TraversableObserverErase (scene::Node& node) :
00355 node(node)
00356 {
00357 }
00358 void operator() (scene::Traversable::Observer& observer) const
00359 {
00360 observer.erase(node);
00361 }
00362 };
00363
00364 class TraversableObserverPairRelay: public ReferencePair<scene::Traversable::Observer> ,
00365 public scene::Traversable::Observer
00366 {
00367 public:
00368 void insert (scene::Node& node)
00369 {
00370 forEach(TraversableObserverInsert(node));
00371 }
00372 void erase (scene::Node& node)
00373 {
00374 forEach(TraversableObserverErase(node));
00375 }
00376 };
00377
00378 template<typename Type>
00379 class ReferenceSet
00380 {
00381 typedef UniqueSet<Type*> Values;
00382 Values m_values;
00383 public:
00384 void attach (Type& t)
00385 {
00386 m_values.insert(&t);
00387 }
00388 void detach (Type& t)
00389 {
00390 m_values.erase(&t);
00391 }
00392 template<typename Functor>
00393 void forEach (const Functor& functor)
00394 {
00395 for (typename Values::iterator i = m_values.begin(); i != m_values.end(); ++i) {
00396 functor(*(*i));
00397 }
00398 }
00399 };
00400
00401 class TraversableObserverRelay: public ReferenceSet<scene::Traversable::Observer> , public scene::Traversable::Observer
00402 {
00403 public:
00404 TraversableObserverRelay ()
00405 {
00406 }
00407 ~TraversableObserverRelay ()
00408 {
00409 }
00410
00411 void insert (scene::Node& node)
00412 {
00413 forEach(TraversableObserverInsert(node));
00414 }
00415 void erase (scene::Node& node)
00416 {
00417 forEach(TraversableObserverErase(node));
00418 }
00419 };
00420
00421 #endif