comparison engine/core/model/model.cpp @ 145:e7a431577c95

Cleaned the basic model up. Code is cleaner now and a bit faster. Some code path were never tested in depth :-( Added a 'time_to_load' attribute to XMLMapLoader, which records the seconds it took to load a map. Down from 6s to 5.6s for reio de hola. Yay!
author phoku@33b003aa-7bff-0310-803a-e67f0ece8222
date Thu, 09 Oct 2008 08:23:13 +0000
parents 90005975cdbb
children 9d94f4676d17
comparison
equal deleted inserted replaced
144:d2f1e81fbe2c 145:e7a431577c95
40 40
41 namespace FIFE { 41 namespace FIFE {
42 42
43 Model::Model(): 43 Model::Model():
44 FifeClass(), 44 FifeClass(),
45 m_last_namespace(NULL),
45 m_timeprovider(NULL) { 46 m_timeprovider(NULL) {
46 } 47 }
47 48
48 Model::~Model() { 49 Model::~Model() {
49 purge(m_maps); 50 purge(m_maps);
50 for(std::list<namespace_t>::iterator nspace = m_namespaces.begin(); nspace != m_namespaces.end(); ++nspace) 51 for(std::list<namespace_t>::iterator nspace = m_namespaces.begin(); nspace != m_namespaces.end(); ++nspace)
51 purge(nspace->second); 52 purge_map(nspace->second);
52 purge(m_pathers); 53 purge(m_pathers);
53 purge(m_created_grids); 54 purge(m_created_grids);
54 purge(m_adopted_grids); 55 purge(m_adopted_grids);
55 } 56 }
56 57
126 purge(m_maps); 127 purge(m_maps);
127 m_maps.clear(); 128 m_maps.clear();
128 } 129 }
129 130
130 std::list<std::string> Model::getNamespaces() const { 131 std::list<std::string> Model::getNamespaces() const {
131 std::list<std::string> lst; 132 std::list<std::string> namespace_list;
132 std::list<namespace_t>::const_iterator nspace = m_namespaces.begin(); 133 std::list<namespace_t>::const_iterator nspace = m_namespaces.begin();
133 for(; nspace != m_namespaces.end(); ++nspace) { 134 for(; nspace != m_namespaces.end(); ++nspace) {
134 lst.push_back(nspace->first); 135 namespace_list.push_back(nspace->first);
135 } 136 }
136 137 return namespace_list;
137 return lst;
138 } 138 }
139 139
140 Object* Model::createObject(const std::string& identifier, const std::string& name_space, Object* parent) { 140 Object* Model::createObject(const std::string& identifier, const std::string& name_space, Object* parent) {
141 141 // Find or create namespace
142 std::list<namespace_t>::iterator nspace = m_namespaces.begin(); 142 namespace_t* nspace = selectNamespace(name_space);
143 for(; nspace != m_namespaces.end(); ++nspace) { 143 if(!nspace) {
144 if(nspace->first == name_space) break; 144 m_namespaces.push_back(namespace_t(name_space,objectmap_t()));
145 } 145 nspace = selectNamespace(name_space);
146 146 }
147 if(nspace == m_namespaces.end()) { 147
148 m_namespaces.push_back(namespace_t(name_space,std::list<Object*>())); 148 // Check for nameclashes
149 nspace = m_namespaces.end(); 149 objectmap_t::const_iterator it = nspace->second.find(identifier);
150 --nspace; 150 if( it != nspace->second.end() ) {
151 } 151 throw NameClash(identifier);
152 152 }
153 std::list<Object*>::const_iterator it = nspace->second.begin(); 153
154 for(; it != nspace->second.end(); ++it) { 154 // Finally insert & create
155 if(identifier == (*it)->getId())
156 throw NameClash(identifier);
157 }
158
159 Object* object = new Object(identifier, name_space, parent); 155 Object* object = new Object(identifier, name_space, parent);
160 nspace->second.push_back(object); 156 nspace->second[identifier] = object;
161 return object; 157 return object;
162 } 158 }
163 159
164 bool Model::deleteObject(Object* object) { 160 bool Model::deleteObject(Object* object) {
161 // WARNING: This code has obviously not been tested (thoroughly).
162
163 // Check if any instances exist. If yes - bail out.
165 std::list<Layer*>::const_iterator jt; 164 std::list<Layer*>::const_iterator jt;
166 std::vector<Instance*>::const_iterator kt; 165 std::vector<Instance*>::const_iterator kt;
167 for(std::list<Map*>::iterator it = m_maps.begin(); it != m_maps.end(); ++it) { 166 for(std::list<Map*>::iterator it = m_maps.begin(); it != m_maps.end(); ++it) {
168 for(jt = (*it)->getLayers().begin(); jt != (*it)->getLayers().end(); ++jt) { 167 for(jt = (*it)->getLayers().begin(); jt != (*it)->getLayers().end(); ++jt) {
169 for(kt = (*jt)->getInstances().begin(); kt != (*jt)->getInstances().end(); ++kt) { 168 for(kt = (*jt)->getInstances().begin(); kt != (*jt)->getInstances().end(); ++kt) {
170 Object* o = (*kt)->getObject(); 169 Object* o = (*kt)->getObject();
171 while(o != 0) { 170 if(o == object) {
172 if(o == object) 171 return false;
173 return false;
174 } 172 }
175 } 173 }
176 } 174 }
177 } 175 }
178 176
179 std::string name_space = object->getNamespace(); 177 // Check if the namespace exists
180 std::list<namespace_t>::iterator nspace = m_namespaces.begin(); 178 namespace_t* nspace = selectNamespace(object->getNamespace());
181 for(; nspace != m_namespaces.end(); ++nspace) { 179 if(!nspace)
182 if(nspace->first == name_space) break;
183 }
184
185 if(nspace == m_namespaces.end())
186 return true; 180 return true;
187 181
188 std::list<Object*>::iterator it = nspace->second.begin(); 182 // If yes - delete+erase object.
189 for(; it != nspace->second.end(); ++it) { 183 objectmap_t::iterator it = nspace->second.find(object->getId());
190 if(*it == object) { 184 if( it != nspace->second.end()) {
191 delete *it; 185 delete it->second;
192 nspace->second.erase(it); 186 nspace->second.erase(it);
193 return true;
194 }
195 } 187 }
196 188
197 return true; 189 return true;
198 } 190 }
199 191
200 bool Model::deleteObjects() { 192 bool Model::deleteObjects() {
193 // If we have layers with instances - bail out.
201 std::list<Layer*>::const_iterator jt; 194 std::list<Layer*>::const_iterator jt;
202 for(std::list<Map*>::iterator it = m_maps.begin(); it != m_maps.end(); ++it) { 195 for(std::list<Map*>::iterator it = m_maps.begin(); it != m_maps.end(); ++it) {
203 for(jt = (*it)->getLayers().begin(); jt != (*it)->getLayers().end(); ++jt) { 196 for(jt = (*it)->getLayers().begin(); jt != (*it)->getLayers().end(); ++jt) {
204 if((*jt)->hasInstances()) 197 if((*jt)->hasInstances())
205 return false; 198 return false;
206 } 199 }
207 } 200 }
208 201
202 // Otherwise delete every object in every namespace
209 std::list<namespace_t>::iterator nspace = m_namespaces.begin(); 203 std::list<namespace_t>::iterator nspace = m_namespaces.begin();
210 while(nspace != m_namespaces.end()) { 204 while(nspace != m_namespaces.end()) {
211 std::list<Object*>::iterator it = nspace->second.begin(); 205 objectmap_t::iterator it = nspace->second.begin();
212 for(; it != nspace->second.end(); ++it) { 206 for(; it != nspace->second.end(); ++it) {
213 delete *it; 207 delete it->second;
214 } 208 }
215 nspace = m_namespaces.erase(nspace); 209 nspace = m_namespaces.erase(nspace);
216 } 210 }
211 m_last_namespace = 0;
217 return true; 212 return true;
218 } 213 }
219 214
220 Object* Model::getObject(const std::string& id, const std::string& name_space) { 215 Object* Model::getObject(const std::string& id, const std::string& name_space) {
216 namespace_t* nspace = selectNamespace(name_space);
217 if(nspace) {
218 objectmap_t::iterator it = nspace->second.find(id);
219 if( it != nspace->second.end() )
220 return it->second;
221 }
222 return 0;
223 }
224
225 std::list<Object*> Model::getObjects(const std::string& name_space) const {
226 std::list<Object*> object_list;
227 const namespace_t* nspace = selectNamespace(name_space);
228 if(nspace) {
229 objectmap_t::const_iterator it = nspace->second.begin();
230 for(; it != nspace->second.end(); ++it )
231 object_list.push_back(it->second);
232 return object_list;
233 }
234 throw NotFound(name_space);
235 }
236
237 const Model::namespace_t* Model::selectNamespace(const std::string& name_space) const {
238 std::list<namespace_t>::const_iterator nspace = m_namespaces.begin();
239 for(; nspace != m_namespaces.end(); ++nspace) {
240 if( nspace->first == name_space ) {
241 return &(*nspace);
242 }
243 }
244 return 0;
245 }
246
247 Model::namespace_t* Model::selectNamespace(const std::string& name_space) {
248 if( m_last_namespace && m_last_namespace->first == name_space )
249 return m_last_namespace;
221 std::list<namespace_t>::iterator nspace = m_namespaces.begin(); 250 std::list<namespace_t>::iterator nspace = m_namespaces.begin();
222 for(; nspace != m_namespaces.end(); ++nspace) { 251 for(; nspace != m_namespaces.end(); ++nspace) {
223 if(nspace->first == name_space) { 252 if( nspace->first == name_space ) {
224 std::list<Object*>::iterator obj = nspace->second.begin(); 253 m_last_namespace = &(*nspace);
225 for(; obj != nspace->second.end(); ++obj) 254 return m_last_namespace;
226 if((*obj)->getId() == id) return *obj; 255 }
227 } 256 }
228 } 257 m_last_namespace = 0;
229 for(; nspace != m_namespaces.end(); ++nspace) {
230 std::list<Object*>::iterator obj = nspace->second.begin();
231 for(; obj != nspace->second.end(); ++obj)
232 if((*obj)->getId() == id) return *obj;
233 }
234
235 return 0; 258 return 0;
236 }
237
238 const std::list<Object*>& Model::getObjects(const std::string& name_space) const {
239 std::list<namespace_t>::const_iterator nspace = m_namespaces.begin();
240 for(; nspace != m_namespaces.end(); ++nspace) {
241 if(nspace->first == name_space) return nspace->second;
242 }
243
244 throw NotFound(name_space);
245 } 259 }
246 260
247 void Model::update() { 261 void Model::update() {
248 std::list<Map*>::iterator it = m_maps.begin(); 262 std::list<Map*>::iterator it = m_maps.begin();
249 for(; it != m_maps.end(); ++it) { 263 for(; it != m_maps.end(); ++it) {