FIFE  2008.0
 All Classes Namespaces Functions Variables Enumerations Enumerator Pages
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 "model/structures/instance.h"
33 #include "util/structures/rect.h"
34 
35 #include "instancetree.h"
36 
37 
38 namespace FIFE {
39 
40  InstanceTree::InstanceTree(): FifeClass() {
41  }
42 
43  InstanceTree::~InstanceTree() {
44  }
45 
46  void InstanceTree::addInstance(Instance* instance) {
47  ModelCoordinate coords = instance->getLocationRef().getLayerCoordinates();
48  InstanceTreeNode * node = m_tree.find_container(coords.x,coords.y,0,0);
49  InstanceList& list = node->data();
50  list.push_back(instance);
51  if( m_reverse.find(instance) != m_reverse.end() )
52  throw new InconsistencyDetected("Duplicate Instance.");
53  m_reverse[instance] = node;
54  }
55 
56  void InstanceTree::removeInstance(Instance* instance) {
57  ModelCoordinate coords = instance->getLocationRef().getLayerCoordinates();
58  InstanceTreeNode * node = m_reverse[instance];
59  if( !node )
60  throw new InconsistencyDetected("Removing Ghost Instance.");
61  m_reverse.erase(instance);
62  InstanceList& list = node->data();
63  for(InstanceList::iterator i = list.begin(); i != list.end(); ++i) {
64  if((*i) == instance) {
65  list.erase(i);
66  return;
67  }
68  }
69  throw new InconsistencyDetected("Removing Ghost Instance (not in list?).");
70  }
71 
72  class InstanceListCollector {
73  public:
74  InstanceTree::InstanceList& instanceList;
75  Rect searchRect;
76  InstanceListCollector(InstanceTree::InstanceList& a_instanceList, const Rect& rect)
77  : instanceList(a_instanceList), searchRect(rect) {
78  }
79  bool visit(InstanceTree::InstanceTreeNode* node, int d);
80  };
81 
82  bool InstanceListCollector::visit(InstanceTree::InstanceTreeNode* node, int d) {
83  InstanceTree::InstanceList& list = node->data();
84  for(InstanceTree::InstanceList::const_iterator it(list.begin()); it != list.end(); ++it) {
85  ModelCoordinate coords = (*it)->getLocationRef().getLayerCoordinates();
86  if( searchRect.contains(Point(coords.x,coords.y)) ) {
87  instanceList.push_back(*it);
88  }
89  }
90  return true;
91  }
92 
93  void InstanceTree::findInstances(const ModelCoordinate& point, int w, int h, InstanceTree::InstanceList& list) {
94  InstanceTreeNode * node = m_tree.find_container(point.x, point.y, w, h);
95  Rect rect(point.x, point.y, w, h);
96  InstanceListCollector collector(list,rect);
97 
98  node->apply_visitor(collector);
99 
100  node = node->parent();
101  while( node ) {
102  for(InstanceList::const_iterator it(node->data().begin()); it != node->data().end(); ++it) {
103  ModelCoordinate coords = (*it)->getLocationRef().getLayerCoordinates();
104  if( rect.contains(Point(coords.x,coords.y)) ) {
105  list.push_back(*it);
106  }
107  }
108  node = node->parent();
109  }
110  }
111 
112 }