comparison engine/core/model/structures/layer.cpp @ 0:4a0efb7baf70

* Datasets becomes the new trunk and retires after that :-)
author mvbarracuda@33b003aa-7bff-0310-803a-e67f0ece8222
date Sun, 29 Jun 2008 18:44:17 +0000
parents
children 61fdc090b0d4
comparison
equal deleted inserted replaced
-1:000000000000 0:4a0efb7baf70
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 modify *
7 * it under the terms of the GNU General Public License as published by *
8 * the Free Software Foundation; either version 2 of the License, or *
9 * (at your option) any later version. *
10 * *
11 * This program 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 *
14 * GNU General Public License for more details. *
15 * *
16 * You should have received a copy of the GNU General Public License *
17 * along with this program; if not, write to the *
18 * Free Software Foundation, Inc., *
19 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA *
20 ***************************************************************************/
21
22 // Standard C++ library includes
23
24 // 3rd party library includes
25 #include <SDL.h>
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/structures/purge.h"
32
33 #include "layer.h"
34 #include "instance.h"
35 #include "map.h"
36 #include "instancetree.h"
37
38 namespace FIFE {
39
40 Layer::Layer(const std::string& identifier, Map* map, CellGrid* grid)
41 : m_id(identifier),
42 m_map(map),
43 m_instances_visibility(true),
44 m_instanceTree(new InstanceTree()),
45 m_grid(grid),
46 m_pathingstrategy(CELL_EDGES_ONLY),
47 m_changelisteners(),
48 m_changedinstances(),
49 m_changed(false) {
50 }
51
52 Layer::~Layer() {
53 purge(m_instances);
54 delete m_instanceTree;
55 }
56
57 bool Layer::hasInstances() const {
58 return !m_instances.empty();
59 }
60
61 Instance* Layer::createInstance(Object* object, const ModelCoordinate& p, const std::string& id) {
62 ExactModelCoordinate emc(static_cast<double>(p.x), static_cast<double>(p.y), static_cast<double>(p.z));
63 return createInstance(object, emc, id);
64 }
65
66 Instance* Layer::createInstance(Object* object, const ExactModelCoordinate& p, const std::string& id) {
67 Location l;
68 l.setLayer(this);
69 l.setExactLayerCoordinates(p);
70
71 if(id != "") {
72 std::vector<Instance*>::iterator it = m_instances.begin();
73 for(; it != m_instances.end(); ++it) {
74 if((*it)->getId() == id)
75 throw NameClash(id);
76 }
77 }
78
79 Instance* instance = new Instance(object, l, id);
80 m_instances.push_back(instance);
81 m_instanceTree->addInstance(instance);
82
83 std::vector<LayerChangeListener*>::iterator i = m_changelisteners.begin();
84 while (i != m_changelisteners.end()) {
85 (*i)->onInstanceCreate(this, instance);
86 ++i;
87 }
88 m_changed = true;
89 return instance;
90 }
91
92 void Layer::deleteInstance(Instance* instance) {
93 std::vector<LayerChangeListener*>::iterator i = m_changelisteners.begin();
94 while (i != m_changelisteners.end()) {
95 (*i)->onInstanceDelete(this, instance);
96 ++i;
97 }
98
99 std::vector<Instance*>::iterator it = m_instances.begin();
100 for(; it != m_instances.end(); ++it) {
101 if(*it == instance) {
102 m_instanceTree->removeInstance(*it);
103 delete *it;
104 m_instances.erase(it);
105 break;
106 }
107 }
108 m_changed = true;
109 }
110
111 Instance* Layer::getInstance(const std::string& id) {
112 std::vector<Instance*>::iterator it = m_instances.begin();
113 for(; it != m_instances.end(); ++it) {
114 if((*it)->getId() == id)
115 return *it;
116 }
117
118 throw NotFound(id);
119 }
120
121 void Layer::getMinMaxCoordinates(ModelCoordinate& min, ModelCoordinate& max, const Layer* layer) const {
122
123 if(layer == 0) {
124 layer = this;
125 }
126
127 min = m_instances.front()->getLocationRef().getLayerCoordinates(layer);
128 max = min;
129
130 for(std::vector<Instance*>::const_iterator i = m_instances.begin();
131 i != m_instances.end();
132 ++i) {
133
134 ModelCoordinate coord = (*i)->getLocationRef().getLayerCoordinates(layer);
135
136 if(coord.x < min.x) {
137 min.x = coord.x;
138 }
139
140 if(coord.x > max.x) {
141 max.x = coord.x;
142 }
143
144 if(coord.y < min.y) {
145 min.y = coord.y;
146 }
147
148 if(coord.y > max.y) {
149 max.y = coord.y;
150 }
151 }
152 }
153
154 void Layer::setInstancesVisible(bool vis) {
155 m_instances_visibility = vis;
156 }
157 void Layer::toggleInstancesVisible() {
158 m_instances_visibility = !m_instances_visibility;
159 }
160
161 bool Layer::cellContainsBlockingInstance(const ModelCoordinate& cellCoordinate) {
162 std::list<Instance*> adjacentInstances;
163 m_instanceTree->findInstances(cellCoordinate, 0, 0, adjacentInstances);
164 bool blockingInstance = false;
165 for(std::list<Instance*>::const_iterator j = adjacentInstances.begin(); j != adjacentInstances.end(); ++j) {
166 if((*j)->getObject()->isBlocking() && (*j)->getLocationRef().getLayerCoordinates() == cellCoordinate) {
167 blockingInstance = true;
168 }
169 }
170 return blockingInstance;
171 }
172
173 bool Layer::update() {
174 m_changedinstances.clear();
175 unsigned int curticks = SDL_GetTicks();
176 std::vector<Instance*>::iterator it = m_instances.begin();
177 for(; it != m_instances.end(); ++it) {
178 if ((*it)->update(curticks) != ICHANGE_NO_CHANGES) {
179 m_changedinstances.push_back(*it);
180 m_changed = true;
181 }
182 }
183 if (!m_changedinstances.empty()) {
184 std::vector<LayerChangeListener*>::iterator i = m_changelisteners.begin();
185 while (i != m_changelisteners.end()) {
186 (*i)->onLayerChanged(this, m_changedinstances);
187 ++i;
188 }
189 //std::cout << "Layer named " << Id() << " changed = 1\n";
190 }
191 //std::cout << "Layer named " << Id() << " changed = 0\n";
192 bool retval = m_changed;
193 m_changed = false;
194 return retval;
195 }
196
197 void Layer::addChangeListener(LayerChangeListener* listener) {
198 m_changelisteners.push_back(listener);
199 }
200
201 void Layer::removeChangeListener(LayerChangeListener* listener) {
202 std::vector<LayerChangeListener*>::iterator i = m_changelisteners.begin();
203 while (i != m_changelisteners.end()) {
204 if ((*i) == listener) {
205 m_changelisteners.erase(i);
206 return;
207 }
208 ++i;
209 }
210 }
211 } // FIFE