FIFE  2008.0
model.cpp
1 /***************************************************************************
2  * Copyright (C) 2005-2011 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"
32 #include "model/metamodel/ipather.h"
33 #include "model/metamodel/object.h"
34 #include "model/metamodel/grids/cellgrid.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);
59  purge(m_pathers);
60  purge(m_created_grids);
61  purge(m_adopted_grids);
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 
92  void Model::adoptCellGrid(CellGrid* grid) {
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 
131  uint32_t Model::getMapCount() const {
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
Definition: model.cpp:140
Map * getMap(const std::string &identifier) const
Definition: model.cpp:110
void adoptCellGrid(CellGrid *grid)
Definition: model.cpp:92
bool deleteObjects()
Definition: model.cpp:201
Object * createObject(const std::string &identifier, const std::string &name_space, Object *parent=0)
Definition: model.cpp:149
void update()
Definition: model.cpp:271
void deleteMaps()
Definition: model.cpp:135
uint32_t getMapCount() const
Definition: model.cpp:131
CellGrid * getCellGrid(const std::string &gridtype)
Definition: model.cpp:96
Model(RenderBackend *renderbackend, const std::vector< RendererBase * > &renderers)
Definition: model.cpp:47
void deleteMap(Map *)
Definition: model.cpp:120
IPather * getPather(const std::string &pathername)
Definition: model.cpp:81
void adoptPather(IPather *pather)
Definition: model.cpp:77
Object * getObject(const std::string &id, const std::string &name_space)
Definition: model.cpp:224
bool deleteObject(Object *)
Definition: model.cpp:169
Definition: map.h:86
std::list< Object * > getObjects(const std::string &name_space) const
Definition: model.cpp:234
credit to phoku for his NodeDisplay example which the visitor code is adapted from ( he coded the qua...
Definition: soundclip.cpp:39
Map * createMap(const std::string &identifier)
Definition: model.cpp:64