FIFE
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
model.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 
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  Model::Model(RenderBackend* renderbackend, const std::vector<RendererBase*>& renderers)
48  : FifeClass(),
49  m_last_namespace(NULL),
50  m_timeprovider(NULL),
51  m_renderbackend(renderbackend),
52  m_renderers(renderers){
53  }
54 
56  purge(m_maps);
57  for(std::list<namespace_t>::iterator nspace = m_namespaces.begin(); nspace != m_namespaces.end(); ++nspace)
58  purge_map(nspace->second);
62  }
63 
64  Map* Model::createMap(const std::string& identifier) {
65  std::list<Map*>::const_iterator it = m_maps.begin();
66  for(; it != m_maps.end(); ++it) {
67  if(identifier == (*it)->getId()) {
68  throw NameClash(identifier);
69  }
70  }
71 
72  Map* map = new Map(identifier, m_renderbackend, m_renderers, &m_timeprovider);
73  m_maps.push_back(map);
74  return map;
75  }
76 
77  void Model::adoptPather(IPather* pather) {
78  m_pathers.push_back(pather);
79  }
80 
81  IPather* Model::getPather(const std::string& pathername) {
82  std::vector<IPather*>::const_iterator it = m_pathers.begin();
83  for(; it != m_pathers.end(); ++it) {
84  if ((*it)->getName() == pathername) {
85  return *it;
86  }
87  }
88  FL_WARN(_log, "No pather of requested type \"" + pathername + "\" found.");
89  return NULL;
90  }
91 
93  m_adopted_grids.push_back(grid);
94  }
95 
96  CellGrid* Model::getCellGrid(const std::string& gridtype) {
97  std::vector<CellGrid*>::const_iterator it = m_adopted_grids.begin();
98  for(; it != m_adopted_grids.end(); ++it) {
99  if ((*it)->getType() == gridtype) {
100  CellGrid* newcg = (*it)->clone();
101  m_created_grids.push_back(newcg);
102  return newcg;
103  }
104  }
105  FL_WARN(_log, "No cellgrid of requested type \"" + gridtype + "\" found.");
106  return NULL;
107  }
108 
109 
110  Map* Model::getMap(const std::string& identifier) const {
111  std::list<Map*>::const_iterator it = m_maps.begin();
112  for(; it != m_maps.end(); ++it) {
113  if((*it)->getId() == identifier)
114  return *it;
115  }
116 
117  throw NotFound(std::string("Tried to get non-existent map: ") + identifier + ".");
118  }
119 
120  void Model::deleteMap(Map* map) {
121  std::list<Map*>::iterator it = m_maps.begin();
122  for(; it != m_maps.end(); ++it) {
123  if(*it == map) {
124  delete *it;
125  m_maps.erase(it);
126  return ;
127  }
128  }
129  }
130 
132  return m_maps.size();
133  }
134 
136  purge(m_maps);
137  m_maps.clear();
138  }
139 
140  std::list<std::string> Model::getNamespaces() const {
141  std::list<std::string> namespace_list;
142  std::list<namespace_t>::const_iterator nspace = m_namespaces.begin();
143  for(; nspace != m_namespaces.end(); ++nspace) {
144  namespace_list.push_back(nspace->first);
145  }
146  return namespace_list;
147  }
148 
149  Object* Model::createObject(const std::string& identifier, const std::string& name_space, Object* parent) {
150  // Find or create namespace
151  namespace_t* nspace = selectNamespace(name_space);
152  if(!nspace) {
153  m_namespaces.push_back(namespace_t(name_space,objectmap_t()));
154  nspace = selectNamespace(name_space);
155  }
156 
157  // Check for nameclashes
158  objectmap_t::const_iterator it = nspace->second.find(identifier);
159  if( it != nspace->second.end() ) {
160  throw NameClash(identifier);
161  }
162 
163  // Finally insert & create
164  Object* object = new Object(identifier, name_space, parent);
165  nspace->second[identifier] = object;
166  return object;
167  }
168 
169  bool Model::deleteObject(Object* object) {
170  // WARNING: This code has obviously not been tested (thoroughly).
171 
172  // Check if any instances exist. If yes - bail out.
173  std::list<Layer*>::const_iterator jt;
174  std::vector<Instance*>::const_iterator kt;
175  for(std::list<Map*>::iterator it = m_maps.begin(); it != m_maps.end(); ++it) {
176  for(jt = (*it)->getLayers().begin(); jt != (*it)->getLayers().end(); ++jt) {
177  for(kt = (*jt)->getInstances().begin(); kt != (*jt)->getInstances().end(); ++kt) {
178  Object* o = (*kt)->getObject();
179  if(o == object) {
180  return false;
181  }
182  }
183  }
184  }
185 
186  // Check if the namespace exists
187  namespace_t* nspace = selectNamespace(object->getNamespace());
188  if(!nspace)
189  return true;
190 
191  // If yes - delete+erase object.
192  objectmap_t::iterator it = nspace->second.find(object->getId());
193  if( it != nspace->second.end()) {
194  delete it->second;
195  nspace->second.erase(it);
196  }
197 
198  return true;
199  }
200 
202  // If we have layers with instances - bail out.
203  std::list<Layer*>::const_iterator jt;
204  for(std::list<Map*>::iterator it = m_maps.begin(); it != m_maps.end(); ++it) {
205  for(jt = (*it)->getLayers().begin(); jt != (*it)->getLayers().end(); ++jt) {
206  if((*jt)->hasInstances())
207  return false;
208  }
209  }
210 
211  // Otherwise delete every object in every namespace
212  std::list<namespace_t>::iterator nspace = m_namespaces.begin();
213  while(nspace != m_namespaces.end()) {
214  objectmap_t::iterator it = nspace->second.begin();
215  for(; it != nspace->second.end(); ++it) {
216  delete it->second;
217  }
218  nspace = m_namespaces.erase(nspace);
219  }
220  m_last_namespace = 0;
221  return true;
222  }
223 
224  Object* Model::getObject(const std::string& id, const std::string& name_space) {
225  namespace_t* nspace = selectNamespace(name_space);
226  if(nspace) {
227  objectmap_t::iterator it = nspace->second.find(id);
228  if( it != nspace->second.end() )
229  return it->second;
230  }
231  return NULL;
232  }
233 
234  std::list<Object*> Model::getObjects(const std::string& name_space) const {
235  std::list<Object*> object_list;
236  const namespace_t* nspace = selectNamespace(name_space);
237  if(nspace) {
238  objectmap_t::const_iterator it = nspace->second.begin();
239  for(; it != nspace->second.end(); ++it )
240  object_list.push_back(it->second);
241  }
242 
243  return object_list;
244  }
245 
246  const Model::namespace_t* Model::selectNamespace(const std::string& name_space) const {
247  std::list<namespace_t>::const_iterator nspace = m_namespaces.begin();
248  for(; nspace != m_namespaces.end(); ++nspace) {
249  if( nspace->first == name_space ) {
250  return &(*nspace);
251  }
252  }
253 
254  return NULL;
255  }
256 
257  Model::namespace_t* Model::selectNamespace(const std::string& name_space) {
258  if( m_last_namespace && m_last_namespace->first == name_space )
259  return m_last_namespace;
260  std::list<namespace_t>::iterator nspace = m_namespaces.begin();
261  for(; nspace != m_namespaces.end(); ++nspace) {
262  if( nspace->first == name_space ) {
263  m_last_namespace = &(*nspace);
264  return m_last_namespace;
265  }
266  }
267  m_last_namespace = 0;
268  return NULL;
269  }
270 
271  void Model::update() {
272  std::list<Map*>::iterator it = m_maps.begin();
273  for(; it != m_maps.end(); ++it) {
274  (*it)->update();
275  }
276  std::vector<IPather*>::iterator jt = m_pathers.begin();
277  for(; jt != m_pathers.end(); ++jt) {
278  (*jt)->update();
279  }
280  }
281 
282 } //FIFE
283 
std::list< std::string > getNamespaces() const
Get a list of namespaces currently referenced by objects in the metamodel.
Definition: model.cpp:140
#define FL_WARN(logger, msg)
Definition: logger.h:72
Abstract interface for all the renderbackends.
Definition: renderbackend.h:92
Map * getMap(const std::string &identifier) const
Get a map.
Definition: model.cpp:110
void adoptCellGrid(CellGrid *grid)
Adds cellgrid to model.
Definition: model.cpp:92
std::vector< CellGrid * > m_adopted_grids
Definition: model.h:173
RenderBackend * m_renderbackend
Definition: model.h:177
bool deleteObjects()
Attempt to remove all objects from the model Fails and returns false if any maps with instances are p...
Definition: model.cpp:201
namespace_t * m_last_namespace
Used to remember last &#39;selected&#39; namespace.
Definition: model.h:163
const std::string & getNamespace() const
Definition: object.h:69
Object class.
Definition: object.h:51
const std::string & getId() const
Definition: object.h:68
std::vector< IPather * > m_pathers
Definition: model.h:171
Object * createObject(const std::string &identifier, const std::string &name_space, Object *parent=0)
Add an object to the metamodel.
Definition: model.cpp:149
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:271
static Logger _log(LM_AUDIO)
std::vector< RendererBase * > m_renderers
Definition: model.h:179
void purge(Seq &c)
Definition: purge.h:28
std::list< namespace_t > m_namespaces
Definition: model.h:160
void deleteMaps()
Removes all maps from this model.
Definition: model.cpp:135
uint32_t getMapCount() const
Return the number of maps in this model.
Definition: model.cpp:131
void purge_map(Seq &c)
Definition: purge.h:45
std::list< Map * > m_maps
Definition: model.h:156
CellGrid * getCellGrid(const std::string &gridtype)
Returns new copy of cellgrid corresponding given name.
Definition: model.cpp:96
~Model()
Destructor.
Definition: model.cpp:55
Model(RenderBackend *renderbackend, const std::vector< RendererBase * > &renderers)
Constructor.
Definition: model.cpp:47
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:257
TimeProvider m_timeprovider
Definition: model.h:175
void deleteMap(Map *)
Remove a map from this model.
Definition: model.cpp:120
IPather * getPather(const std::string &pathername)
Returns pather corresponding given name.
Definition: model.cpp:81
void adoptPather(IPather *pather)
Adds pather to model.
Definition: model.cpp:77
std::pair< std::string, objectmap_t > namespace_t
Definition: model.h:159
Object * getObject(const std::string &id, const std::string &name_space)
Get an object by its id.
Definition: model.cpp:224
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:169
A container of Layer(s).
Definition: map.h:87
std::vector< CellGrid * > m_created_grids
Definition: model.h:172
unsigned int uint32_t
Definition: core.h:40
std::map< std::string, Object * > objectmap_t
Definition: model.h:158
std::list< Object * > getObjects(const std::string &name_space) const
Get all the objects in the given namespace.
Definition: model.cpp:234
Map * createMap(const std::string &identifier)
Add a map this model, and get a pointer to it.
Definition: model.cpp:64