Mercurial > fife-parpg
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) { |