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