FIFE
2008.0
|
00001 /*************************************************************************** 00002 * Copyright (C) 2005-2008 by the FIFE team * 00003 * http://www.fifengine.de * 00004 * This file is part of FIFE. * 00005 * * 00006 * FIFE is free software; you can redistribute it and/or * 00007 * modify it under the terms of the GNU Lesser General Public * 00008 * License as published by the Free Software Foundation; either * 00009 * version 2.1 of the License, or (at your option) any later version. * 00010 * * 00011 * This library is distributed in the hope that it will be useful, * 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * 00014 * Lesser General Public License for more details. * 00015 * * 00016 * You should have received a copy of the GNU Lesser General Public * 00017 * License along with this library; if not, write to the * 00018 * Free Software Foundation, Inc., * 00019 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * 00020 ***************************************************************************/ 00021 00022 // Standard C++ library includes 00023 00024 // 3rd party library includes 00025 00026 // FIFE includes 00027 // These includes are split up in two parts, separated by one empty line 00028 // First block: files included from the FIFE root src directory 00029 // Second block: files included from the same folder 00030 #include "util/structures/purge.h" 00031 #include "model/metamodel/abstractpather.h" 00032 #include "model/metamodel/object.h" 00033 #include "model/metamodel/grids/cellgrid.h" 00034 #include "structures/map.h" 00035 #include "structures/layer.h" 00036 #include "structures/instance.h" 00037 #include "util/base/exception.h" 00038 #include "view/rendererbase.h" 00039 #include "video/renderbackend.h" 00040 #include "video/imagepool.h" 00041 #include "video/animationpool.h" 00042 00043 #include "model.h" 00044 00045 namespace FIFE { 00046 00047 Model::Model(RenderBackend* renderbackend, const std::vector<RendererBase*>& renderers, 00048 ImagePool* imagepool, AnimationPool* animpool): 00049 FifeClass(), 00050 m_last_namespace(NULL), 00051 m_timeprovider(NULL), 00052 m_renderbackend(renderbackend), 00053 m_imagepool(imagepool), 00054 m_animpool(animpool), 00055 m_renderers(renderers){ 00056 } 00057 00058 Model::~Model() { 00059 purge(m_maps); 00060 for(std::list<namespace_t>::iterator nspace = m_namespaces.begin(); nspace != m_namespaces.end(); ++nspace) 00061 purge_map(nspace->second); 00062 purge(m_pathers); 00063 purge(m_created_grids); 00064 purge(m_adopted_grids); 00065 } 00066 00067 Map* Model::createMap(const std::string& identifier) { 00068 std::list<Map*>::const_iterator it = m_maps.begin(); 00069 for(; it != m_maps.end(); ++it) { 00070 if(identifier == (*it)->getId()) { 00071 throw NameClash(identifier); 00072 } 00073 } 00074 00075 Map* map = new Map(identifier, m_renderbackend, m_renderers, m_imagepool, m_animpool, &m_timeprovider); 00076 m_maps.push_back(map); 00077 return map; 00078 } 00079 00080 void Model::adoptPather(AbstractPather* pather) { 00081 m_pathers.push_back(pather); 00082 } 00083 00084 AbstractPather* Model::getPather(const std::string& pathername) { 00085 std::vector<AbstractPather*>::const_iterator it = m_pathers.begin(); 00086 for(; it != m_pathers.end(); ++it) { 00087 if ((*it)->getName() == pathername) { 00088 return *it; 00089 } 00090 } 00091 return NULL; 00092 } 00093 00094 void Model::adoptCellGrid(CellGrid* grid) { 00095 m_adopted_grids.push_back(grid); 00096 } 00097 00098 CellGrid* Model::getCellGrid(const std::string& gridtype) { 00099 std::vector<CellGrid*>::const_iterator it = m_adopted_grids.begin(); 00100 for(; it != m_adopted_grids.end(); ++it) { 00101 if ((*it)->getType() == gridtype) { 00102 CellGrid* newcg = (*it)->clone(); 00103 m_created_grids.push_back(newcg); 00104 return newcg; 00105 } 00106 } 00107 return NULL; 00108 } 00109 00110 00111 Map* Model::getMap(const std::string& identifier) const { 00112 std::list<Map*>::const_iterator it = m_maps.begin(); 00113 for(; it != m_maps.end(); ++it) { 00114 if((*it)->getId() == identifier) 00115 return *it; 00116 } 00117 00118 throw NotFound(std::string("Tried to get non-existent map: ") + identifier + "."); 00119 } 00120 00121 void Model::deleteMap(Map* map) { 00122 std::list<Map*>::iterator it = m_maps.begin(); 00123 for(; it != m_maps.end(); ++it) { 00124 if(*it == map) { 00125 delete *it; 00126 m_maps.erase(it); 00127 return ; 00128 } 00129 } 00130 } 00131 00132 uint32_t Model::getNumMaps() const { 00133 return m_maps.size(); 00134 } 00135 00136 void Model::deleteMaps() { 00137 purge(m_maps); 00138 m_maps.clear(); 00139 } 00140 00141 std::list<std::string> Model::getNamespaces() const { 00142 std::list<std::string> namespace_list; 00143 std::list<namespace_t>::const_iterator nspace = m_namespaces.begin(); 00144 for(; nspace != m_namespaces.end(); ++nspace) { 00145 namespace_list.push_back(nspace->first); 00146 } 00147 return namespace_list; 00148 } 00149 00150 Object* Model::createObject(const std::string& identifier, const std::string& name_space, Object* parent) { 00151 // Find or create namespace 00152 namespace_t* nspace = selectNamespace(name_space); 00153 if(!nspace) { 00154 m_namespaces.push_back(namespace_t(name_space,objectmap_t())); 00155 nspace = selectNamespace(name_space); 00156 } 00157 00158 // Check for nameclashes 00159 objectmap_t::const_iterator it = nspace->second.find(identifier); 00160 if( it != nspace->second.end() ) { 00161 throw NameClash(identifier); 00162 } 00163 00164 // Finally insert & create 00165 Object* object = new Object(identifier, name_space, parent); 00166 nspace->second[identifier] = object; 00167 return object; 00168 } 00169 00170 bool Model::deleteObject(Object* object) { 00171 // WARNING: This code has obviously not been tested (thoroughly). 00172 00173 // Check if any instances exist. If yes - bail out. 00174 std::list<Layer*>::const_iterator jt; 00175 std::vector<Instance*>::const_iterator kt; 00176 for(std::list<Map*>::iterator it = m_maps.begin(); it != m_maps.end(); ++it) { 00177 for(jt = (*it)->getLayers().begin(); jt != (*it)->getLayers().end(); ++jt) { 00178 for(kt = (*jt)->getInstances().begin(); kt != (*jt)->getInstances().end(); ++kt) { 00179 Object* o = (*kt)->getObject(); 00180 if(o == object) { 00181 return false; 00182 } 00183 } 00184 } 00185 } 00186 00187 // Check if the namespace exists 00188 namespace_t* nspace = selectNamespace(object->getNamespace()); 00189 if(!nspace) 00190 return true; 00191 00192 // If yes - delete+erase object. 00193 objectmap_t::iterator it = nspace->second.find(object->getId()); 00194 if( it != nspace->second.end()) { 00195 delete it->second; 00196 nspace->second.erase(it); 00197 } 00198 00199 return true; 00200 } 00201 00202 bool Model::deleteObjects() { 00203 // If we have layers with instances - bail out. 00204 std::list<Layer*>::const_iterator jt; 00205 for(std::list<Map*>::iterator it = m_maps.begin(); it != m_maps.end(); ++it) { 00206 for(jt = (*it)->getLayers().begin(); jt != (*it)->getLayers().end(); ++jt) { 00207 if((*jt)->hasInstances()) 00208 return false; 00209 } 00210 } 00211 00212 // Otherwise delete every object in every namespace 00213 std::list<namespace_t>::iterator nspace = m_namespaces.begin(); 00214 while(nspace != m_namespaces.end()) { 00215 objectmap_t::iterator it = nspace->second.begin(); 00216 for(; it != nspace->second.end(); ++it) { 00217 delete it->second; 00218 } 00219 nspace = m_namespaces.erase(nspace); 00220 } 00221 m_last_namespace = 0; 00222 return true; 00223 } 00224 00225 Object* Model::getObject(const std::string& id, const std::string& name_space) { 00226 namespace_t* nspace = selectNamespace(name_space); 00227 if(nspace) { 00228 objectmap_t::iterator it = nspace->second.find(id); 00229 if( it != nspace->second.end() ) 00230 return it->second; 00231 } 00232 return 0; 00233 } 00234 00235 std::list<Object*> Model::getObjects(const std::string& name_space) const { 00236 std::list<Object*> object_list; 00237 const namespace_t* nspace = selectNamespace(name_space); 00238 if(nspace) { 00239 objectmap_t::const_iterator it = nspace->second.begin(); 00240 for(; it != nspace->second.end(); ++it ) 00241 object_list.push_back(it->second); 00242 } 00243 00244 return object_list; 00245 } 00246 00247 const Model::namespace_t* Model::selectNamespace(const std::string& name_space) const { 00248 std::list<namespace_t>::const_iterator nspace = m_namespaces.begin(); 00249 for(; nspace != m_namespaces.end(); ++nspace) { 00250 if( nspace->first == name_space ) { 00251 return &(*nspace); 00252 } 00253 } 00254 return 0; 00255 } 00256 00257 Model::namespace_t* Model::selectNamespace(const std::string& name_space) { 00258 if( m_last_namespace && m_last_namespace->first == name_space ) 00259 return m_last_namespace; 00260 std::list<namespace_t>::iterator nspace = m_namespaces.begin(); 00261 for(; nspace != m_namespaces.end(); ++nspace) { 00262 if( nspace->first == name_space ) { 00263 m_last_namespace = &(*nspace); 00264 return m_last_namespace; 00265 } 00266 } 00267 m_last_namespace = 0; 00268 return 0; 00269 } 00270 00271 void Model::update() { 00272 std::list<Map*>::iterator it = m_maps.begin(); 00273 for(; it != m_maps.end(); ++it) { 00274 (*it)->update(); 00275 } 00276 std::vector<AbstractPather*>::iterator jt = m_pathers.begin(); 00277 for(; jt != m_pathers.end(); ++jt) { 00278 (*jt)->update(); 00279 } 00280 } 00281 00282 } //FIFE 00283