FIFE  6e1afdbeda11afe9ac53e6023a4be96ef88f1dc6
map.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  * Copyright (C) 2005-2017 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 #include "triggercontroller.h"
44 
45 namespace FIFE {
46 
47  Map::Map(const std::string& identifier, RenderBackend* renderBackend,
48  const std::vector<RendererBase*>& renderers, TimeProvider* tp_master):
49  m_id(identifier),
50  m_filename(""),
51  m_timeProvider(tp_master),
52  m_changeListeners(),
53  m_changedLayers(),
54  m_renderBackend(renderBackend),
55  m_renderers(renderers),
56  m_changed(false) {
57 
59  }
60 
62  delete m_triggerController;
63  // remove all cameras
64  std::vector<Camera*>::iterator iter = m_cameras.begin();
65  for ( ; iter != m_cameras.end(); ++iter) {
66  delete *iter;
67  }
68  m_cameras.clear();
69 
70  deleteLayers();
71  }
72 
73  Layer* Map::getLayer(const std::string& id) {
74  std::list<Layer*>::const_iterator it = m_layers.begin();
75  for(; it != m_layers.end(); ++it) {
76  if((*it)->getId() == id)
77  return *it;
78  }
79  return NULL;
80  }
81 
83  return m_layers.size();
84  }
85 
86  Layer* Map::createLayer(const std::string& identifier, CellGrid* grid) {
87  std::list<Layer*>::const_iterator it = m_layers.begin();
88  for(; it != m_layers.end(); ++it) {
89  if(identifier == (*it)->getId())
90  throw NameClash(identifier);
91  }
92 
93  Layer* layer = new Layer(identifier, this, grid);
94  m_layers.push_back(layer);
95  m_changed = true;
96  std::vector<MapChangeListener*>::iterator i = m_changeListeners.begin();
97  while (i != m_changeListeners.end()) {
98  (*i)->onLayerCreate(this, layer);
99  ++i;
100  }
101 
102  return layer;
103  }
104 
105  void Map::deleteLayer(Layer* layer) {
106  std::list<Layer*>::iterator it = m_layers.begin();
107  for(; it != m_layers.end(); ++it) {
108  if((*it) == layer) {
109  std::vector<MapChangeListener*>::iterator i = m_changeListeners.begin();
110  while (i != m_changeListeners.end()) {
111  (*i)->onLayerDelete(this, layer);
112  ++i;
113  }
114  delete layer;
115  m_layers.erase(it);
116  return ;
117  }
118  }
119  m_changed = true;
120  }
121 
123  std::list<Layer*> temp_layers = m_layers;
124  std::list<Layer*>::iterator temp_it = temp_layers.begin();
125  for(; temp_it != temp_layers.end(); ++temp_it) {
126  std::vector<MapChangeListener*>::iterator i = m_changeListeners.begin();
127  while (i != m_changeListeners.end()) {
128  (*i)->onLayerDelete(this, *temp_it);
129  ++i;
130  }
131  std::list<Layer*>::iterator it = m_layers.begin();
132  for(; it != m_layers.end(); ++it) {
133  if(*it == *temp_it) {
134  delete *it;
135  m_layers.erase(it);
136  break;
137  }
138  }
139  }
140  }
141 
143  if (m_layers.empty()) {
144  return;
145  }
146  std::list<Layer*>::iterator it = m_layers.begin();
147  Layer* layer = *it;
148  for (; it != m_layers.end(); ++it) {
149  ModelCoordinate newMin, newMax;
150  (*it)->getMinMaxCoordinates(newMin, newMax, layer);
151 
152  if (newMin.x < min.x) {
153  min.x = newMin.x;
154  }
155  if (newMax.x > max.x) {
156  max.x = newMax.x;
157  }
158  if (newMin.y < min.y) {
159  min.y = newMin.y;
160  }
161  if (newMax.y > max.y) {
162  max.y = newMax.y;
163  }
164  }
165  Location lmin(layer);
166  Location lmax(layer);
167  lmin.setExactLayerCoordinates(min);
168  lmax.setExactLayerCoordinates(max);
169 
170  min = lmin.getMapCoordinates();
171  max = lmax.getMapCoordinates();
172  }
173 
174  bool Map::update() {
175  m_changedLayers.clear();
176  // transfer instances from one layer to another
177  if (!m_transferInstances.empty()) {
178  std::map<Instance*, Location>::iterator it = m_transferInstances.begin();
179  for (; it != m_transferInstances.end(); ++it) {
180  Instance* inst = (*it).first;
181  Location target_loc = (*it).second;
182  Layer* source = inst->getOldLocationRef().getLayer();
183  Layer* target = target_loc.getLayer();
184  if (source != target) {
185  source->removeInstance(inst);
186  target->addInstance(inst, target_loc.getExactLayerCoordinates());
187  }
188  }
189  m_transferInstances.clear();
190  }
191  std::vector<CellCache*> cellCaches;
192  std::list<Layer*>::iterator it = m_layers.begin();
193  // update Layers
194  for(; it != m_layers.end(); ++it) {
195  if ((*it)->update()) {
196  m_changedLayers.push_back(*it);
197  }
198  CellCache* cache = (*it)->getCellCache();
199  if (cache) {
200  cellCaches.push_back(cache);
201  }
202  }
203  // loop over Caches and update
204  for (std::vector<CellCache*>::iterator cacheIt = cellCaches.begin();
205  cacheIt != cellCaches.end(); ++cacheIt) {
206  (*cacheIt)->update();
207  }
208  if (!m_changedLayers.empty()) {
209  std::vector<MapChangeListener*>::iterator i = m_changeListeners.begin();
210  while (i != m_changeListeners.end()) {
211  (*i)->onMapChanged(this, m_changedLayers);
212  ++i;
213  }
214  }
215 
216  // loop over cameras and update if enabled
217  std::vector<Camera*>::iterator camIter = m_cameras.begin();
218  for ( ; camIter != m_cameras.end(); ++camIter) {
219  if ((*camIter)->isEnabled()) {
220  (*camIter)->update();
221  (*camIter)->render();
222  }
223  }
224 
225  bool retval = m_changed;
226  m_changed = false;
227  return retval;
228  }
229 
231  m_changeListeners.push_back(listener);
232  }
233 
235  std::vector<MapChangeListener*>::iterator i = m_changeListeners.begin();
236  while (i != m_changeListeners.end()) {
237  if ((*i) == listener) {
238  m_changeListeners.erase(i);
239  return;
240  }
241  ++i;
242  }
243  }
244 
245  Camera* Map::addCamera(const std::string &id, Layer *layer, const Rect& viewport) {
246  if (layer == NULL) {
247  throw NotSupported("Must have valid layer for camera");
248  }
249 
250  if (getCamera(id)) {
251  std::string errorStr = "Camera: " + id + " already exists";
252  throw NameClash(errorStr);
253  }
254 
255  // create new camera and add to list of cameras
256  Camera* camera = new Camera(id, layer, viewport, m_renderBackend);
257  m_cameras.push_back(camera);
258 
259  std::vector<RendererBase*>::iterator iter = m_renderers.begin();
260  for ( ; iter != m_renderers.end(); ++iter) {
261  camera->addRenderer((*iter)->clone());
262  }
263 
264  return camera;
265  }
266 
267  void Map::removeCamera(const std::string &id) {
268  std::vector<Camera*>::iterator iter = m_cameras.begin();
269  for ( ; iter != m_cameras.end(); ++iter) {
270  if ((*iter)->getId() == id) {
271  // camera has been found delete it
272  delete *iter;
273 
274  // now remove it from the vector
275  // note this invalidates iterators, but we do not need
276  // to worry about it in this case since we are done
277  m_cameras.erase(iter);
278 
279  break;
280  }
281  }
282  }
283 
284  Camera* Map::getCamera(const std::string &id) {
285  std::vector<Camera*>::iterator iter = m_cameras.begin();
286  for ( ; iter != m_cameras.end(); ++iter) {
287  if ((*iter)->getId() == id) {
288  return *iter;
289  }
290  }
291 
292  return NULL;
293  }
294 
295  const std::vector<Camera*>& Map::getCameras() const {
296  return m_cameras;
297  }
298 
300  uint32_t count = 0;
301  std::vector<Camera*>::const_iterator it = m_cameras.begin();
302  for ( ; it != m_cameras.end(); ++it) {
303  if ((*it)->isEnabled()) {
304  count += 1;
305  }
306  }
307  return count;
308  }
309 
310  void Map::addInstanceForTransfer(Instance* instance, const Location& target) {
311  std::pair<std::map<Instance*, Location>::iterator, bool> insertiter = m_transferInstances.insert(std::make_pair(instance, target));
312  if (insertiter.second == false) {
313  Location& loc = insertiter.first->second;
314  loc.setLayer(target.getLayer());
316  }
317  }
318 
320  std::map<Instance*, Location>::iterator it = m_transferInstances.find(instance);
321  if (it != m_transferInstances.end()) {
322  m_transferInstances.erase(it);
323  }
324  }
325 
327  if (m_layers.empty()) {
328  return;
329  }
330 
331  std::list<Layer*>::iterator layit = m_layers.begin();
332  // first add interacts to walkables
333  for (; layit != m_layers.end(); ++layit) {
334  if ((*layit)->isInteract()) {
335  Layer* temp = getLayer((*layit)->getWalkableId());
336  if (temp) {
337  temp->addInteractLayer(*layit);
338  }
339  }
340  }
341  // then create CellCaches for walkables
342  layit = m_layers.begin();
343  for (; layit != m_layers.end(); ++layit) {
344  if ((*layit)->isWalkable()) {
345  (*layit)->createCellCache();
346  }
347  }
348  }
349 
351  // create Cells and generate neighbours
352  std::list<Layer*>::iterator layit = m_layers.begin();
353  for (; layit != m_layers.end(); ++layit) {
354  CellCache* cache = (*layit)->getCellCache();
355  if (cache) {
356  cache->createCells();
357  cache->forceUpdate();
358  }
359  }
360  }
361 } //FIFE
362 
Abstract interface for all the renderbackends.
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:174
~Map()
Destructor.
Definition: map.cpp:61
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:73
Camera * addCamera(const std::string &id, Layer *layer, const Rect &viewport)
Adds camera to the map.
Definition: map.cpp:245
void removeChangeListener(MapChangeListener *listener)
Removes associated change listener.
Definition: map.cpp:234
std::map< Instance *, Location > m_transferInstances
holds instances which should be transferred on the next update
Definition: map.h:251
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:230
void deleteLayers()
Delete all layers from the map.
Definition: map.cpp:122
Camera describes properties of a view port shown in the main screen Main screen can have multiple cam...
Definition: camera.h:59
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:233
Camera * getCamera(const std::string &id)
Get a camera by its identifier.
Definition: map.cpp:284
void addInteractLayer(Layer *layer)
Adds a interact layer to the walkable layer.
Definition: layer.cpp:544
uint32_t getLayerCount() const
Get the overall number of layers.
Definition: map.cpp:82
std::list< Layer * > m_layers
Definition: map.h:226
void removeInstance(Instance *instance)
Remove an instance from the layer.
Definition: layer.cpp:159
void addRenderer(RendererBase *renderer)
Adds new renderer on the view.
Definition: camera.cpp:720
void deleteLayer(Layer *)
Delete a layer from the map.
Definition: map.cpp:105
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:47
bool addInstance(Instance *instance, const ExactModelCoordinate &p)
Add a valid instance at a specific position.
Definition: layer.cpp:134
Location & getOldLocationRef()
Gets reference of old location of instance.
Definition: instance.cpp:917
void removeInstanceForTransfer(Instance *instance)
Removes instance that should be transferred to another layer.
Definition: map.cpp:319
A basic layer on a map.
Definition: layer.h:99
Layer * createLayer(const std::string &identifier, CellGrid *grid)
Add a Layer to this Map.
Definition: map.cpp:86
void addInstanceForTransfer(Instance *instance, const Location &target)
Adds instance that is to be transferred to another layer.
Definition: map.cpp:310
void getMinMaxCoordinates(ExactModelCoordinate &min, ExactModelCoordinate &max)
Retrieves the minimum/maximum coordinates of instances on the map.
Definition: map.cpp:142
std::vector< Layer * > m_changedLayers
holds changed layers after each update
Definition: map.h:236
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:267
std::vector< Camera * > m_cameras
holds the cameras attached to this map
Definition: map.h:239
bool m_changed
true, if something was changed on map during previous update (layer change, creation, deletion)
Definition: map.h:248
void finalizeCellCaches()
Creates cellcaches for this map.
Definition: map.cpp:350
void initializeCellCaches()
Creates cellcaches for this map.
Definition: map.cpp:326
TriggerController * m_triggerController
Definition: map.h:253
This class serves as a central place to manage triggers for a Map.
unsigned int uint32_t
Definition: core.h:40
std::vector< RendererBase * > m_renderers
holds handles to all created renderers
Definition: map.h:245
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:295
RenderBackend * m_renderBackend
pointer to renderbackend
Definition: map.h:242
An Instance is an "instantiation" of an Object at a Location.
Definition: instance.h:101
ExactModelCoordinate getMapCoordinates() const
Gets map coordinates set to this location.
Definition: location.cpp:117
uint32_t getActiveCameraCount() const
Return the number of enabled cameras in this map.
Definition: map.cpp:299
Listener interface for changes happening on map.
Definition: map.h:56