FIFE  2008.0
instancetree.cpp
1 /***************************************************************************
2  * Copyright (C) 2005-2008 by the FIFE team *
3  * http://www.fifengine.de *
4  * This file is part of FIFE. *
5  * *
6  * FIFE is free software; you can redistribute it and/or *
7  * modify it under the terms of the GNU Lesser General Public *
8  * License as published by the Free Software Foundation; either *
9  * version 2.1 of the License, or (at your option) any later version. *
10  * *
11  * This library is distributed in the hope that it will be useful, *
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
14  * Lesser General Public License for more details. *
15  * *
16  * You should have received a copy of the GNU Lesser General Public *
17  * License along with this library; if not, write to the *
18  * Free Software Foundation, Inc., *
19  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
20  ***************************************************************************/
21 
22 // Standard C++ library includes
23 
24 // 3rd party library includes
25 
26 
27 // FIFE includes
28 // These includes are split up in two parts, separated by one empty line
29 // First block: files included from the FIFE root src directory
30 // Second block: files included from the same folder
31 #include "util/base/exception.h"
32 #include "util/log/logger.h"
33 #include "model/structures/instance.h"
34 #include "util/structures/rect.h"
35 
36 #include "instancetree.h"
37 
38 
39 namespace FIFE {
40  static Logger _log(LM_STRUCTURES);
41 
42  InstanceTree::InstanceTree(): FifeClass() {
43  }
44 
45  InstanceTree::~InstanceTree() {
46  }
47 
48  void InstanceTree::addInstance(Instance* instance) {
49  ModelCoordinate coords = instance->getLocationRef().getLayerCoordinates();
50  InstanceTreeNode * node = m_tree.find_container(coords.x,coords.y,0,0);
51  InstanceList& list = node->data();
52  list.push_back(instance);
53  if( m_reverse.find(instance) != m_reverse.end() ) {
54  FL_WARN(_log, "InstanceTree::addInstance() - Duplicate Instance. Ignoring.");
55  return;
56  }
57  m_reverse[instance] = node;
58  }
59 
60  void InstanceTree::removeInstance(Instance* instance) {
61  ModelCoordinate coords = instance->getLocationRef().getLayerCoordinates();
62  InstanceTreeNode * node = m_reverse[instance];
63  if( !node ) {
64  FL_WARN(_log, "InstanceTree::removeInstance() - Instance not part of tree.");
65  return;
66  }
67  m_reverse.erase(instance);
68  InstanceList& list = node->data();
69  for(InstanceList::iterator i = list.begin(); i != list.end(); ++i) {
70  if((*i) == instance) {
71  list.erase(i);
72  return;
73  }
74  }
75  FL_WARN(_log, "InstanceTree::removeInstance() - Instance part of tree but not found in the expected tree node.");
76  }
77 
78  class InstanceListCollector {
79  public:
80  InstanceTree::InstanceList& instanceList;
81  Rect searchRect;
82  InstanceListCollector(InstanceTree::InstanceList& a_instanceList, const Rect& rect)
83  : instanceList(a_instanceList), searchRect(rect) {
84  }
85  bool visit(InstanceTree::InstanceTreeNode* node, int32_t d);
86  };
87 
88  bool InstanceListCollector::visit(InstanceTree::InstanceTreeNode* node, int32_t d) {
89  InstanceTree::InstanceList& list = node->data();
90  for(InstanceTree::InstanceList::const_iterator it(list.begin()); it != list.end(); ++it) {
91  ModelCoordinate coords = (*it)->getLocationRef().getLayerCoordinates();
92  if( searchRect.contains(Point(coords.x,coords.y)) ) {
93  instanceList.push_back(*it);
94  }
95  }
96  return true;
97  }
98 
99  void InstanceTree::findInstances(const ModelCoordinate& point, int32_t w, int32_t h, InstanceTree::InstanceList& list) {
100  InstanceTreeNode * node = m_tree.find_container(point.x, point.y, w, h);
101  Rect rect(point.x, point.y, w, h);
102  InstanceListCollector collector(list,rect);
103 
104  node->apply_visitor(collector);
105 
106  node = node->parent();
107  while( node ) {
108  for(InstanceList::const_iterator it(node->data().begin()); it != node->data().end(); ++it) {
109  ModelCoordinate coords = (*it)->getLocationRef().getLayerCoordinates();
110  if( rect.contains(Point(coords.x,coords.y)) ) {
111  list.push_back(*it);
112  }
113  }
114  node = node->parent();
115  }
116  }
117 
118 }
credit to phoku for his NodeDisplay example which the visitor code is adapted from ( he coded the qua...
Definition: soundclip.cpp:39