FIFE  6e1afdbeda11afe9ac53e6023a4be96ef88f1dc6
model.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 
24 // 3rd party library includes
25 
26 // FIFE includes
27 // These includes are split up in two parts, separated by one empty line
28 // First block: files included from the FIFE root src directory
29 // Second block: files included from the same folder
30 #include "util/structures/purge.h"
31 #include "util/log/logger.h"
33 #include "model/metamodel/object.h"
35 #include "structures/map.h"
36 #include "structures/layer.h"
37 #include "structures/instance.h"
38 #include "util/base/exception.h"
39 #include "view/rendererbase.h"
40 #include "video/renderbackend.h"
41 
42 #include "model.h"
43 
44 namespace FIFE {
45  static Logger _log(LM_MODEL);
46 
47 
50 
51  public:
53  m_model = model;
54  }
55  virtual ~ModelMapObserver() {}
56 
57  virtual void onMapChanged(Map* map, std::vector<Layer*>& changedLayers) {
58  }
59 
60  virtual void onLayerCreate(Map* map, Layer* layer) {
61  }
62 
63  virtual void onLayerDelete(Map* map, Layer* layer) {
64  m_model->removeCellGrid(layer->getCellGrid());
65  }
66  };
67 
68  Model::Model(RenderBackend* renderbackend, const std::vector<RendererBase*>& renderers)
69  : FifeClass(),
70  m_lastNamespace(NULL),
71  m_timeprovider(NULL),
72  m_renderbackend(renderbackend),
73  m_renderers(renderers){
74 
75  m_mapObserver = new ModelMapObserver(this);
76  }
77 
79  // first remove the map observer, we delete all grids anyway
80  for (std::list<Map*>::iterator it = m_maps.begin(); it != m_maps.end(); ++it) {
81  (*it)->removeChangeListener(m_mapObserver);
82  delete *it;
83  }
84  delete m_mapObserver;
85 
86  for(std::list<namespace_t>::iterator nspace = m_namespaces.begin(); nspace != m_namespaces.end(); ++nspace)
87  purge_map(nspace->second);
91  }
92 
93  Map* Model::createMap(const std::string& identifier) {
94  std::list<Map*>::const_iterator it = m_maps.begin();
95  for(; it != m_maps.end(); ++it) {
96  if(identifier == (*it)->getId()) {
97  throw NameClash(identifier);
98  }
99  }
100 
101  Map* map = new Map(identifier, m_renderbackend, m_renderers, &m_timeprovider);
103  m_maps.push_back(map);
104  return map;
105  }
106 
107  void Model::adoptPather(IPather* pather) {
108  m_pathers.push_back(pather);
109  }
110 
111  IPather* Model::getPather(const std::string& pathername) {
112  std::vector<IPather*>::const_iterator it = m_pathers.begin();
113  for(; it != m_pathers.end(); ++it) {
114  if ((*it)->getName() == pathername) {
115  return *it;
116  }
117  }
118  FL_WARN(_log, "No pather of requested type \"" + pathername + "\" found.");
119  return NULL;
120  }
121 
123  m_adoptedGrids.push_back(grid);
124  }
125 
126  CellGrid* Model::getCellGrid(const std::string& gridtype) {
127  std::vector<CellGrid*>::const_iterator it = m_adoptedGrids.begin();
128  for(; it != m_adoptedGrids.end(); ++it) {
129  if ((*it)->getType() == gridtype) {
130  CellGrid* newcg = (*it)->clone();
131  m_createdGrids.push_back(newcg);
132  return newcg;
133  }
134  }
135  FL_WARN(_log, "No cellgrid of requested type \"" + gridtype + "\" found.");
136  return NULL;
137  }
138 
140  if (!grid) return;
141 
142  for (std::vector<CellGrid*>::iterator it = m_createdGrids.begin(); it != m_createdGrids.end(); ++it) {
143  if (*it == grid) {
144  delete *it;
145  m_createdGrids.erase(it);
146  return;
147  }
148  }
149  }
150 
151  Map* Model::getMap(const std::string& identifier) const {
152  std::list<Map*>::const_iterator it = m_maps.begin();
153  for(; it != m_maps.end(); ++it) {
154  if((*it)->getId() == identifier)
155  return *it;
156  }
157 
158  throw NotFound(std::string("Tried to get non-existent map: ") + identifier + ".");
159  }
160 
161  void Model::deleteMap(Map* map) {
162  std::list<Map*>::iterator it = m_maps.begin();
163  for(; it != m_maps.end(); ++it) {
164  if(*it == map) {
165  delete *it;
166  m_maps.erase(it);
167  return;
168  }
169  }
170  }
171 
173  return m_maps.size();
174  }
175 
177  // first remove the map observer, we delete all grids anyway
178  for (std::list<Map*>::iterator it = m_maps.begin(); it != m_maps.end(); ++it) {
179  (*it)->removeChangeListener(m_mapObserver);
180  delete *it;
181  }
182  m_maps.clear();
184  m_createdGrids.clear();
185  }
186 
188  uint32_t count = 0;
189  std::list<Map*>::const_iterator it = m_maps.begin();
190  for(; it != m_maps.end(); ++it) {
191  count += (*it)->getActiveCameraCount();
192  }
193  return count;
194  }
195 
196  std::list<std::string> Model::getNamespaces() const {
197  std::list<std::string> namespace_list;
198  std::list<namespace_t>::const_iterator nspace = m_namespaces.begin();
199  for(; nspace != m_namespaces.end(); ++nspace) {
200  namespace_list.push_back(nspace->first);
201  }
202  return namespace_list;
203  }
204 
205  Object* Model::createObject(const std::string& identifier, const std::string& name_space, Object* parent) {
206  // Find or create namespace
207  namespace_t* nspace = selectNamespace(name_space);
208  if(!nspace) {
209  m_namespaces.push_back(namespace_t(name_space,objectmap_t()));
210  nspace = selectNamespace(name_space);
211  }
212 
213  // Check for nameclashes
214  objectmap_t::const_iterator it = nspace->second.find(identifier);
215  if( it != nspace->second.end() ) {
216  throw NameClash(identifier);
217  }
218 
219  // Finally insert & create
220  Object* object = new Object(identifier, name_space, parent);
221  nspace->second[identifier] = object;
222  return object;
223  }
224 
225  bool Model::deleteObject(Object* object) {
226  // WARNING: This code has obviously not been tested (thoroughly).
227 
228  // Check if any instances exist. If yes - bail out.
229  std::list<Layer*>::const_iterator jt;
230  std::vector<Instance*>::const_iterator kt;
231  for(std::list<Map*>::iterator it = m_maps.begin(); it != m_maps.end(); ++it) {
232  for(jt = (*it)->getLayers().begin(); jt != (*it)->getLayers().end(); ++jt) {
233  for(kt = (*jt)->getInstances().begin(); kt != (*jt)->getInstances().end(); ++kt) {
234  Object* o = (*kt)->getObject();
235  if(o == object) {
236  return false;
237  }
238  }
239  }
240  }
241 
242  // Check if the namespace exists
243  namespace_t* nspace = selectNamespace(object->getNamespace());
244  if(!nspace)
245  return true;
246 
247  // If yes - delete+erase object.
248  objectmap_t::iterator it = nspace->second.find(object->getId());
249  if( it != nspace->second.end()) {
250  delete it->second;
251  nspace->second.erase(it);
252  }
253 
254  return true;
255  }
256 
258  // If we have layers with instances - bail out.
259  std::list<Layer*>::const_iterator jt;
260  for(std::list<Map*>::iterator it = m_maps.begin(); it != m_maps.end(); ++it) {
261  for(jt = (*it)->getLayers().begin(); jt != (*it)->getLayers().end(); ++jt) {
262  if((*jt)->hasInstances())
263  return false;
264  }
265  }
266 
267  // Otherwise delete every object in every namespace
268  std::list<namespace_t>::iterator nspace = m_namespaces.begin();
269  while(nspace != m_namespaces.end()) {
270  objectmap_t::iterator it = nspace->second.begin();
271  for(; it != nspace->second.end(); ++it) {
272  delete it->second;
273  }
274  nspace = m_namespaces.erase(nspace);
275  }
276  m_lastNamespace = 0;
277  return true;
278  }
279 
280  Object* Model::getObject(const std::string& id, const std::string& name_space) {
281  namespace_t* nspace = selectNamespace(name_space);
282  if(nspace) {
283  objectmap_t::iterator it = nspace->second.find(id);
284  if( it != nspace->second.end() )
285  return it->second;
286  }
287  return NULL;
288  }
289 
290  std::list<Object*> Model::getObjects(const std::string& name_space) const {
291  std::list<Object*> object_list;
292  const namespace_t* nspace = selectNamespace(name_space);
293  if(nspace) {
294  objectmap_t::const_iterator it = nspace->second.begin();
295  for(; it != nspace->second.end(); ++it )
296  object_list.push_back(it->second);
297  }
298 
299  return object_list;
300  }
301 
302  const Model::namespace_t* Model::selectNamespace(const std::string& name_space) const {
303  std::list<namespace_t>::const_iterator nspace = m_namespaces.begin();
304  for(; nspace != m_namespaces.end(); ++nspace) {
305  if( nspace->first == name_space ) {
306  return &(*nspace);
307  }
308  }
309 
310  return NULL;
311  }
312 
313  Model::namespace_t* Model::selectNamespace(const std::string& name_space) {
314  if( m_lastNamespace && m_lastNamespace->first == name_space )
315  return m_lastNamespace;
316  std::list<namespace_t>::iterator nspace = m_namespaces.begin();
317  for(; nspace != m_namespaces.end(); ++nspace) {
318  if( nspace->first == name_space ) {
319  m_lastNamespace = &(*nspace);
320  return m_lastNamespace;
321  }
322  }
323  m_lastNamespace = 0;
324  return NULL;
325  }
326 
327  void Model::update() {
328  std::list<Map*>::iterator it = m_maps.begin();
329  for(; it != m_maps.end(); ++it) {
330  (*it)->update();
331  }
332  std::vector<IPather*>::iterator jt = m_pathers.begin();
333  for(; jt != m_pathers.end(); ++jt) {
334  (*jt)->update();
335  }
336  }
337 
338 } //FIFE
339 
std::list< std::string > getNamespaces() const
Get a list of namespaces currently referenced by objects in the metamodel.
Definition: model.cpp:196
#define FL_WARN(logger, msg)
Definition: logger.h:72
Abstract interface for all the renderbackends.
Map * getMap(const std::string &identifier) const
Get a map.
Definition: model.cpp:151
void adoptCellGrid(CellGrid *grid)
Adds cellgrid to model.
Definition: model.cpp:122
RenderBackend * m_renderbackend
Definition: model.h:188
bool deleteObjects()
Attempt to remove all objects from the model Fails and returns false if any maps with instances are p...
Definition: model.cpp:257
const std::string & getNamespace() const
Definition: object.h:69
Object class.
Definition: object.h:51
const std::string & getId() const
Definition: object.h:68
ModelMapObserver(Model *model)
Definition: model.cpp:52
namespace_t * m_lastNamespace
Used to remember last &#39;selected&#39; namespace.
Definition: model.h:174
virtual ~ModelMapObserver()
Definition: model.cpp:55
std::vector< IPather * > m_pathers
Definition: model.h:182
Object * createObject(const std::string &identifier, const std::string &name_space, Object *parent=0)
Add an object to the metamodel.
Definition: model.cpp:205
uint32_t getActiveCameraCount() const
Return the number of enabled cameras in this model.
Definition: model.cpp:187
void addChangeListener(MapChangeListener *listener)
Adds new change listener.
Definition: map.cpp:230
Base class for all fife classes Used e.g.
Definition: fifeclass.h:42
void update()
Called periodically to update events on model.
Definition: model.cpp:327
static Logger _log(LM_AUDIO)
std::vector< RendererBase * > m_renderers
Definition: model.h:190
virtual void onLayerDelete(Map *map, Layer *layer)
Called when some layer gets deleted on map.
Definition: model.cpp:63
virtual void onLayerCreate(Map *map, Layer *layer)
Called when some layer gets created on the map.
Definition: model.cpp:60
std::vector< CellGrid * > m_createdGrids
Definition: model.h:183
void purge(Seq &c)
Definition: purge.h:28
std::vector< CellGrid * > m_adoptedGrids
Definition: model.h:184
std::list< namespace_t > m_namespaces
Definition: model.h:171
virtual void onMapChanged(Map *map, std::vector< Layer * > &changedLayers)
Called when some layer is changed on map.
Definition: model.cpp:57
void deleteMaps()
Removes all maps from this model.
Definition: model.cpp:176
uint32_t getMapCount() const
Return the number of maps in this model.
Definition: model.cpp:172
A basic layer on a map.
Definition: layer.h:99
void purge_map(Seq &c)
Definition: purge.h:45
void removeCellGrid(CellGrid *grid)
Removes cellgrid from model.
Definition: model.cpp:139
A model is a facade for everything in the model.
Definition: model.h:54
ModelMapObserver * m_mapObserver
Definition: model.h:165
CellGrid * getCellGrid() const
Get the Cellgrid.
Definition: layer.cpp:93
std::list< Map * > m_maps
Definition: model.h:167
CellGrid * getCellGrid(const std::string &gridtype)
Returns new copy of cellgrid corresponding given name.
Definition: model.cpp:126
~Model()
Destructor.
Definition: model.cpp:78
Model(RenderBackend *renderbackend, const std::vector< RendererBase * > &renderers)
Constructor.
Definition: model.cpp:68
virtual CellGrid * clone()=0
Returns clone of this cellgrid.
namespace_t * selectNamespace(const std::string &name_space)
Convenience function to retrieve a pointer to a namespace or NULL if it doesn&#39;t exist.
Definition: model.cpp:313
TimeProvider m_timeprovider
Definition: model.h:186
void deleteMap(Map *)
Remove a map from this model.
Definition: model.cpp:161
IPather * getPather(const std::string &pathername)
Returns pather corresponding given name.
Definition: model.cpp:111
void adoptPather(IPather *pather)
Adds pather to model.
Definition: model.cpp:107
std::pair< std::string, objectmap_t > namespace_t
Definition: model.h:170
Object * getObject(const std::string &id, const std::string &name_space)
Get an object by its id.
Definition: model.cpp:280
bool deleteObject(Object *)
Attempt to remove an object from the model Fails and returns false if the object is referenced by an ...
Definition: model.cpp:225
A container of Layer(s).
Definition: map.h:88
unsigned int uint32_t
Definition: core.h:40
std::map< std::string, Object * > objectmap_t
Definition: model.h:169
std::list< Object * > getObjects(const std::string &name_space) const
Get all the objects in the given namespace.
Definition: model.cpp:290
Map * createMap(const std::string &identifier)
Add a map this model, and get a pointer to it.
Definition: model.cpp:93
Listener interface for changes happening on map.
Definition: map.h:56