FIFE  2008.0
 All Classes Namespaces Functions Variables Enumerations Enumerator Pages
map.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 #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 
42 namespace FIFE {
43 
44  Map::Map(const std::string& identifier, RenderBackend* renderBackend,
45  const std::vector<RendererBase*>& renderers, TimeProvider* tp_master):
46  m_id(identifier),
47  m_filename(""),
48  m_timeprovider(tp_master),
49  m_changelisteners(),
50  m_changedlayers(),
51  m_renderbackend(renderBackend),
52  m_renderers(renderers),
53  m_changed(false){
54  }
55 
57  // remove all cameras
58  std::vector<Camera*>::iterator iter = m_cameras.begin();
59  for ( ; iter != m_cameras.end(); ++iter) {
60  delete *iter;
61  }
62  m_cameras.clear();
63 
64  deleteLayers();
65  }
66 
67  Layer* Map::getLayer(const std::string& id) {
68  std::list<Layer*>::const_iterator it = m_layers.begin();
69  for(; it != m_layers.end(); ++it) {
70  if((*it)->getId() == id)
71  return *it;
72  }
73 
74  throw NotFound(id);
75  }
76 
77  uint32_t Map::getLayerCount() const {
78  return m_layers.size();
79  }
80 
81  Layer* Map::createLayer(const std::string& identifier, CellGrid* grid) {
82  std::list<Layer*>::const_iterator it = m_layers.begin();
83  for(; it != m_layers.end(); ++it) {
84  if(identifier == (*it)->getId())
85  throw NameClash(identifier);
86  }
87 
88  Layer* layer = new Layer(identifier, this, grid);
89  m_layers.push_back(layer);
90  m_changed = true;
91  std::vector<MapChangeListener*>::iterator i = m_changelisteners.begin();
92  while (i != m_changelisteners.end()) {
93  (*i)->onLayerCreate(this, layer);
94  ++i;
95  }
96 
97  return layer;
98  }
99 
100  void Map::deleteLayer(Layer* layer) {
101  std::list<Layer*>::iterator it = m_layers.begin();
102  for(; it != m_layers.end(); ++it) {
103  if((*it) == layer) {
104  std::vector<MapChangeListener*>::iterator i = m_changelisteners.begin();
105  while (i != m_changelisteners.end()) {
106  (*i)->onLayerDelete(this, layer);
107  ++i;
108  }
109  delete layer;
110  m_layers.erase(it);
111  return ;
112  }
113  }
114  m_changed = true;
115  }
116 
118  std::list<Layer*>::iterator it = m_layers.begin();
119  for(; it != m_layers.end(); ++it) {
120  std::vector<MapChangeListener*>::iterator i = m_changelisteners.begin();
121  while (i != m_changelisteners.end()) {
122  (*i)->onLayerDelete(this, *it);
123  ++i;
124  }
125  }
126  purge(m_layers);
127  m_layers.clear();
128  }
129 
131  Location lmin;
132  Location lmax;
133  std::list<Layer*>::iterator it = m_layers.begin();
134  Layer* layer = *it;
135  for (; it != m_layers.end(); ++it) {
136  ModelCoordinate newMin, newMax;
137  (*it)->getMinMaxCoordinates(newMin, newMax, layer);
138 
139  if (newMin.x < min.x) {
140  min.x = newMin.x;
141  }
142  if (newMax.x > max.x) {
143  max.x = newMax.x;
144  }
145  if (newMin.y < min.y) {
146  min.y = newMin.y;
147  }
148  if (newMax.y > max.y) {
149  max.y = newMax.y;
150  }
151  }
152  lmin.setLayer(layer);
153  lmax.setLayer(layer);
154  lmin.setExactLayerCoordinates(min);
155  lmax.setExactLayerCoordinates(max);
156 
157  min = lmin.getMapCoordinates();
158  max = lmax.getMapCoordinates();
159  }
160 
161  bool Map::update() {
162  m_changedlayers.clear();
163  std::list<Layer*>::iterator it = m_layers.begin();
164  for(; it != m_layers.end(); ++it) {
165  if ((*it)->update()) {
166  m_changedlayers.push_back(*it);
167  }
168  }
169  if (!m_changedlayers.empty()) {
170  std::vector<MapChangeListener*>::iterator i = m_changelisteners.begin();
171  while (i != m_changelisteners.end()) {
172  (*i)->onMapChanged(this, m_changedlayers);
173  ++i;
174  }
175  }
176 
177  // loop over cameras and update if enabled
178  std::vector<Camera*>::iterator camIter = m_cameras.begin();
179  for ( ; camIter != m_cameras.end(); ++camIter) {
180  if ((*camIter)->isEnabled()) {
181  (*camIter)->update();
182  (*camIter)->render();
183  }
184  }
185 
186  bool retval = m_changed;
187  m_changed = false;
188  return retval;
189  }
190 
192  m_changelisteners.push_back(listener);
193  }
194 
196  std::vector<MapChangeListener*>::iterator i = m_changelisteners.begin();
197  while (i != m_changelisteners.end()) {
198  if ((*i) == listener) {
199  m_changelisteners.erase(i);
200  return;
201  }
202  ++i;
203  }
204  }
205 
206  Camera* Map::addCamera(const std::string &id, Layer *layer, const Rect& viewport) {
207  if (layer == NULL) {
208  throw NotSupported("Must have valid layer for camera");
209  }
210 
211  if (getCamera(id)) {
212  std::string errorStr = "Camera: " + id + " already exists";
213  throw NameClash(errorStr);
214  }
215 
216  // create new camera and add to list of cameras
217  Camera* camera = new Camera(id, layer, viewport, m_renderbackend);
218  m_cameras.push_back(camera);
219 
220  std::vector<RendererBase*>::iterator iter = m_renderers.begin();
221  for ( ; iter != m_renderers.end(); ++iter) {
222  camera->addRenderer((*iter)->clone());
223  }
224 
225  return camera;
226  }
227 
228  void Map::removeCamera(const std::string &id) {
229  std::vector<Camera*>::iterator iter = m_cameras.begin();
230  for ( ; iter != m_cameras.end(); ++iter) {
231  if ((*iter)->getId() == id) {
232  // camera has been found delete it
233  delete *iter;
234 
235  // now remove it from the vector
236  // note this invalidates iterators, but we do not need
237  // to worry about it in this case since we are done
238  m_cameras.erase(iter);
239 
240  break;
241  }
242  }
243  }
244 
245  Camera* Map::getCamera(const std::string &id) {
246  std::vector<Camera*>::iterator iter = m_cameras.begin();
247  for ( ; iter != m_cameras.end(); ++iter) {
248  if ((*iter)->getId() == id) {
249  return *iter;
250  }
251  }
252 
253  return NULL;
254  }
255 
256  const std::vector<Camera*>& Map::getCameras() const {
257  return m_cameras;
258  }
259 
260 } //FIFE
261