FIFE
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
map.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  * Copyright (C) 2005-2013 by the FIFE team *
3  * http://www.fifengine.net *
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 #include <string>
24 
25 // 3rd party library includes
26 #include <boost/lexical_cast.hpp>
27 
28 // FIFE includes
29 // These includes are split up in two parts, separated by one empty line
30 // First block: files included from the FIFE root src directory
31 // Second block: files included from the same folder
32 #include "util/base/exception.h"
33 #include "util/structures/purge.h"
34 #include "util/structures/rect.h"
35 #include "view/camera.h"
36 #include "view/rendererbase.h"
37 #include "video/renderbackend.h"
38 
39 #include "map.h"
40 #include "layer.h"
41 #include "cellcache.h"
42 #include "instance.h"
43 
44 namespace FIFE {
45 
46  Map::Map(const std::string& identifier, RenderBackend* renderBackend,
47  const std::vector<RendererBase*>& renderers, TimeProvider* tp_master):
48  m_id(identifier),
49  m_filename(""),
50  m_timeProvider(tp_master),
51  m_changeListeners(),
52  m_changedLayers(),
53  m_renderBackend(renderBackend),
54  m_renderers(renderers),
55  m_changed(false){
56  }
57 
59  // remove all cameras
60  std::vector<Camera*>::iterator iter = m_cameras.begin();
61  for ( ; iter != m_cameras.end(); ++iter) {
62  delete *iter;
63  }
64  m_cameras.clear();
65 
66  deleteLayers();
67  }
68 
69  Layer* Map::getLayer(const std::string& id) {
70  std::list<Layer*>::const_iterator it = m_layers.begin();
71  for(; it != m_layers.end(); ++it) {
72  if((*it)->getId() == id)
73  return *it;
74  }
75  return NULL;
76  }
77 
79  return m_layers.size();
80  }
81 
82  Layer* Map::createLayer(const std::string& identifier, CellGrid* grid) {
83  std::list<Layer*>::const_iterator it = m_layers.begin();
84  for(; it != m_layers.end(); ++it) {
85  if(identifier == (*it)->getId())
86  throw NameClash(identifier);
87  }
88 
89  Layer* layer = new Layer(identifier, this, grid);
90  m_layers.push_back(layer);
91  m_changed = true;
92  std::vector<MapChangeListener*>::iterator i = m_changeListeners.begin();
93  while (i != m_changeListeners.end()) {
94  (*i)->onLayerCreate(this, layer);
95  ++i;
96  }
97 
98  return layer;
99  }
100 
101  void Map::deleteLayer(Layer* layer) {
102  std::list<Layer*>::iterator it = m_layers.begin();
103  for(; it != m_layers.end(); ++it) {
104  if((*it) == layer) {
105  std::vector<MapChangeListener*>::iterator i = m_changeListeners.begin();
106  while (i != m_changeListeners.end()) {
107  (*i)->onLayerDelete(this, layer);
108  ++i;
109  }
110  delete layer;
111  m_layers.erase(it);
112  return ;
113  }
114  }
115  m_changed = true;
116  }
117 
119  std::list<Layer*> temp_layers = m_layers;
120  std::list<Layer*>::iterator temp_it = temp_layers.begin();
121  for(; temp_it != temp_layers.end(); ++temp_it) {
122  std::vector<MapChangeListener*>::iterator i = m_changeListeners.begin();
123  while (i != m_changeListeners.end()) {
124  (*i)->onLayerDelete(this, *temp_it);
125  ++i;
126  }
127  std::list<Layer*>::iterator it = m_layers.begin();
128  for(; it != m_layers.end(); ++it) {
129  if(*it == *temp_it) {
130  delete *it;
131  m_layers.erase(it);
132  break;
133  }
134  }
135  }
136  }
137 
139  if (m_layers.empty()) {
140  return;
141  }
142  std::list<Layer*>::iterator it = m_layers.begin();
143  Layer* layer = *it;
144  for (; it != m_layers.end(); ++it) {
145  ModelCoordinate newMin, newMax;
146  (*it)->getMinMaxCoordinates(newMin, newMax, layer);
147 
148  if (newMin.x < min.x) {
149  min.x = newMin.x;
150  }
151  if (newMax.x > max.x) {
152  max.x = newMax.x;
153  }
154  if (newMin.y < min.y) {
155  min.y = newMin.y;
156  }
157  if (newMax.y > max.y) {
158  max.y = newMax.y;
159  }
160  }
161  Location lmin(layer);
162  Location lmax(layer);
163  lmin.setExactLayerCoordinates(min);
164  lmax.setExactLayerCoordinates(max);
165 
166  min = lmin.getMapCoordinates();
167  max = lmax.getMapCoordinates();
168  }
169 
170  bool Map::update() {
171  m_changedLayers.clear();
172  // transfer instances from one layer to another
173  if (!m_transferInstances.empty()) {
174  std::map<Instance*, Location>::iterator it = m_transferInstances.begin();
175  for (; it != m_transferInstances.end(); ++it) {
176  Instance* inst = (*it).first;
177  Location target_loc = (*it).second;
178  Layer* source = inst->getOldLocationRef().getLayer();
179  Layer* target = target_loc.getLayer();
180  if (source != target) {
181  source->removeInstance(inst);
182  target->addInstance(inst, target_loc.getExactLayerCoordinates());
183  }
184  }
185  m_transferInstances.clear();
186  }
187  std::vector<CellCache*> cellCaches;
188  std::list<Layer*>::iterator it = m_layers.begin();
189  // update Layers
190  for(; it != m_layers.end(); ++it) {
191  if ((*it)->update()) {
192  m_changedLayers.push_back(*it);
193  }
194  CellCache* cache = (*it)->getCellCache();
195  if (cache) {
196  cellCaches.push_back(cache);
197  }
198  }
199  // loop over Caches and update
200  for (std::vector<CellCache*>::iterator cacheIt = cellCaches.begin();
201  cacheIt != cellCaches.end(); ++cacheIt) {
202  (*cacheIt)->update();
203  }
204  if (!m_changedLayers.empty()) {
205  std::vector<MapChangeListener*>::iterator i = m_changeListeners.begin();
206  while (i != m_changeListeners.end()) {
207  (*i)->onMapChanged(this, m_changedLayers);
208  ++i;
209  }
210  }
211 
212  // loop over cameras and update if enabled
213  std::vector<Camera*>::iterator camIter = m_cameras.begin();
214  for ( ; camIter != m_cameras.end(); ++camIter) {
215  if ((*camIter)->isEnabled()) {
216  (*camIter)->update();
217  (*camIter)->render();
218  }
219  }
220 
221  bool retval = m_changed;
222  m_changed = false;
223  return retval;
224  }
225 
227  m_changeListeners.push_back(listener);
228  }
229 
231  std::vector<MapChangeListener*>::iterator i = m_changeListeners.begin();
232  while (i != m_changeListeners.end()) {
233  if ((*i) == listener) {
234  m_changeListeners.erase(i);
235  return;
236  }
237  ++i;
238  }
239  }
240 
241  Camera* Map::addCamera(const std::string &id, Layer *layer, const Rect& viewport) {
242  if (layer == NULL) {
243  throw NotSupported("Must have valid layer for camera");
244  }
245 
246  if (getCamera(id)) {
247  std::string errorStr = "Camera: " + id + " already exists";
248  throw NameClash(errorStr);
249  }
250 
251  // create new camera and add to list of cameras
252  Camera* camera = new Camera(id, layer, viewport, m_renderBackend);
253  m_cameras.push_back(camera);
254 
255  std::vector<RendererBase*>::iterator iter = m_renderers.begin();
256  for ( ; iter != m_renderers.end(); ++iter) {
257  camera->addRenderer((*iter)->clone());
258  }
259 
260  return camera;
261  }
262 
263  void Map::removeCamera(const std::string &id) {
264  std::vector<Camera*>::iterator iter = m_cameras.begin();
265  for ( ; iter != m_cameras.end(); ++iter) {
266  if ((*iter)->getId() == id) {
267  // camera has been found delete it
268  delete *iter;
269 
270  // now remove it from the vector
271  // note this invalidates iterators, but we do not need
272  // to worry about it in this case since we are done
273  m_cameras.erase(iter);
274 
275  break;
276  }
277  }
278  }
279 
280  Camera* Map::getCamera(const std::string &id) {
281  std::vector<Camera*>::iterator iter = m_cameras.begin();
282  for ( ; iter != m_cameras.end(); ++iter) {
283  if ((*iter)->getId() == id) {
284  return *iter;
285  }
286  }
287 
288  return NULL;
289  }
290 
291  const std::vector<Camera*>& Map::getCameras() const {
292  return m_cameras;
293  }
294 
295  void Map::addInstanceForTransfer(Instance* instance, const Location& target) {
296  std::pair<std::map<Instance*, Location>::iterator, bool> insertiter = m_transferInstances.insert(std::make_pair(instance, target));
297  if (insertiter.second == false) {
298  Location& loc = insertiter.first->second;
299  loc.setLayer(target.getLayer());
301  }
302  }
303 
305  std::map<Instance*, Location>::iterator it = m_transferInstances.find(instance);
306  if (it != m_transferInstances.end()) {
307  m_transferInstances.erase(it);
308  }
309  }
310 
312  if (m_layers.empty()) {
313  return;
314  }
315 
316  std::list<Layer*>::iterator layit = m_layers.begin();
317  // first add interacts to walkables
318  for (; layit != m_layers.end(); ++layit) {
319  if ((*layit)->isInteract()) {
320  Layer* temp = getLayer((*layit)->getWalkableId());
321  if (temp) {
322  temp->addInteractLayer(*layit);
323  }
324  }
325  }
326  // then create CellCaches for walkables
327  layit = m_layers.begin();
328  for (; layit != m_layers.end(); ++layit) {
329  if ((*layit)->isWalkable()) {
330  (*layit)->createCellCache();
331  }
332  }
333  }
334 
336  // create Cells and generate neighbours
337  std::list<Layer*>::iterator layit = m_layers.begin();
338  for (; layit != m_layers.end(); ++layit) {
339  CellCache* cache = (*layit)->getCellCache();
340  if (cache) {
341  cache->createCells();
342  cache->forceUpdate();
343  }
344  }
345  }
346 } //FIFE
347 
Abstract interface for all the renderbackends.
Definition: renderbackend.h:92
Timeprovider is an utility providing time management functionality You can have hierarchy of time pro...
Definition: timeprovider.h:42
bool update()
Called periodically to update events on map.
Definition: map.cpp:170
~Map()
Destructor.
Definition: map.cpp:58
void setExactLayerCoordinates(const ExactModelCoordinate &coordinates)
Sets precise layer coordinates to this location.
Definition: location.cpp:87
Layer * getLayer(const std::string &identifier)
Get the layer with the given id.
Definition: map.cpp:69
Camera * addCamera(const std::string &id, Layer *layer, const Rect &viewport)
Adds camera to the map.
Definition: map.cpp:241
void removeChangeListener(MapChangeListener *listener)
Removes associated change listener.
Definition: map.cpp:230
std::map< Instance *, Location > m_transferInstances
holds instances which should be transferred on the next update
Definition: map.h:246
void setLayer(Layer *layer)
Sets layer where this location is pointing to.
Definition: location.cpp:79
A CellCache is an abstract depiction of one or a few layers and contains additional information...
Definition: cellcache.h:111
void addChangeListener(MapChangeListener *listener)
Adds new change listener.
Definition: map.cpp:226
void deleteLayers()
Delete all layers from the map.
Definition: map.cpp:118
Camera describes properties of a view port shown in the main screen Main screen can have multiple cam...
Definition: camera.h:58
Layer * getLayer() const
Gets the layer where this location is pointing to.
Definition: location.cpp:83
std::vector< MapChangeListener * > m_changeListeners
listeners for map changes
Definition: map.h:228
Camera * getCamera(const std::string &id)
Get a camera by its identifier.
Definition: map.cpp:280
void addInteractLayer(Layer *layer)
Adds a interact layer to the walkable layer.
Definition: layer.cpp:424
uint32_t getLayerCount() const
Get the overall number of layers.
Definition: map.cpp:78
std::list< Layer * > m_layers
Definition: map.h:221
void removeInstance(Instance *instance)
Remove an instance from the layer.
Definition: layer.cpp:158
void addRenderer(RendererBase *renderer)
Adds new renderer on the view.
Definition: camera.cpp:677
void deleteLayer(Layer *)
Delete a layer from the map.
Definition: map.cpp:101
Map(const std::string &identifier, RenderBackend *renderbackend, const std::vector< RendererBase * > &renderers, TimeProvider *tp_master=NULL)
Construct a map To add map to model, one should call Model::addMap (otherwise map is not registered w...
Definition: map.cpp:46
bool addInstance(Instance *instance, const ExactModelCoordinate &p)
Add a valid instance at a specific position.
Definition: layer.cpp:133
Location & getOldLocationRef()
Gets reference of old location of instance.
Definition: instance.cpp:839
void removeInstanceForTransfer(Instance *instance)
Removes instance that should be transferred to another layer.
Definition: map.cpp:304
A basic layer on a map.
Definition: layer.h:98
Layer * createLayer(const std::string &identifier, CellGrid *grid)
Add a Layer to this Map.
Definition: map.cpp:82
void addInstanceForTransfer(Instance *instance, const Location &target)
Adds instance that is to be transferred to another layer.
Definition: map.cpp:295
void getMinMaxCoordinates(ExactModelCoordinate &min, ExactModelCoordinate &max)
Retrieves the minimum/maximum coordinates of instances on the map.
Definition: map.cpp:138
std::vector< Layer * > m_changedLayers
holds changed layers after each update
Definition: map.h:231
void forceUpdate()
Updates all cells.
Definition: cellcache.cpp:682
void createCells()
Creates cells for this CellCache based on the size of the assigned layer.
Definition: cellcache.cpp:586
void removeCamera(const std::string &id)
Removes a camera from the map.
Definition: map.cpp:263
std::vector< Camera * > m_cameras
holds the cameras attached to this map
Definition: map.h:234
bool m_changed
true, if something was changed on map during previous update (layer change, creation, deletion)
Definition: map.h:243
void finalizeCellCaches()
Creates cellcaches for this map.
Definition: map.cpp:335
void initializeCellCaches()
Creates cellcaches for this map.
Definition: map.cpp:311
unsigned int uint32_t
Definition: core.h:40
std::vector< RendererBase * > m_renderers
holds handles to all created renderers
Definition: map.h:240
ExactModelCoordinate getExactLayerCoordinates() const
Gets exact layer coordinates set to this location.
Definition: location.cpp:109
const std::vector< Camera * > & getCameras() const
Get a list containing all cameras.
Definition: map.cpp:291
RenderBackend * m_renderBackend
pointer to renderbackend
Definition: map.h:237
An Instance is an &quot;instantiation&quot; of an Object at a Location.
Definition: instance.h:97
ExactModelCoordinate getMapCoordinates() const
Gets map coordinates set to this location.
Definition: location.cpp:117
Listener interface for changes happening on map.
Definition: map.h:55