comparison engine/core/util/resource/pool.cpp @ 146:54b3984e1afc

The getIndex function was a hack that shadowed another bug that caused the pools to misbehave. AddResourceFromFile works now exactly as getIndex, it's just faster. Fixed GUIImage to not hold a reference, it uses the index directly anyway. Plus heaps of minor adjustments for more informative debug output and statistics.
author phoku@33b003aa-7bff-0310-803a-e67f0ece8222
date Thu, 09 Oct 2008 12:36:21 +0000
parents d2f1e81fbe2c
children fb6ccb367dd1
comparison
equal deleted inserted replaced
145:e7a431577c95 146:54b3984e1afc
33 #include "pool.h" 33 #include "pool.h"
34 34
35 namespace FIFE { 35 namespace FIFE {
36 static Logger _log(LM_POOL); 36 static Logger _log(LM_POOL);
37 37
38 Pool::Pool(): 38 Pool::Pool(const std::string& name):
39 m_entries(), 39 m_entries(),
40 m_location_to_entry(), 40 m_location_to_entry(),
41 m_listeners(), 41 m_listeners(),
42 m_loaders(), 42 m_loaders(),
43 m_curind(0) 43 m_curind(0),
44 m_name(name)
44 { 45 {
45 } 46 }
46 47
47 Pool::~Pool() { 48 Pool::~Pool() {
48 FL_LOG(_log, LMsg("Pool destroyed ")); 49 FL_LOG(_log, LMsg("Pool destroyed: ") << m_name);
49 printStatistics(); 50 printStatistics();
50 clear(); 51 clear();
51 std::vector<ResourceLoader*>::iterator loader; 52 std::vector<ResourceLoader*>::iterator loader;
52 for (loader = m_loaders.begin(); loader != m_loaders.end(); loader++) { 53 for (loader = m_loaders.begin(); loader != m_loaders.end(); loader++) {
53 delete (*loader); 54 delete (*loader);
59 for (listener = m_listeners.begin(); listener != m_listeners.end(); listener++) { 60 for (listener = m_listeners.begin(); listener != m_listeners.end(); listener++) {
60 (*listener)->poolCleared(); 61 (*listener)->poolCleared();
61 } 62 }
62 std::vector<PoolEntry*>::iterator entry; 63 std::vector<PoolEntry*>::iterator entry;
63 for (entry = m_entries.begin(); entry != m_entries.end(); entry++) { 64 for (entry = m_entries.begin(); entry != m_entries.end(); entry++) {
65 // Warn about leaks, but at least display ALL of them
66 // Instead of bailing out with an exception in the FifeClass destructor.
67 if( (*entry)->resource && (*entry)->resource->getRefCount() > 0 ) {
68 FL_WARN(_log, LMsg(m_name + " leak: ") << (*entry)->location->getFilename());
69 (*entry)->resource = 0;
70 }
64 delete (*entry); 71 delete (*entry);
65 } 72 }
66 m_entries.clear(); 73 m_entries.clear();
67 m_location_to_entry.clear(); 74 m_location_to_entry.clear();
68 } 75 }
78 } 85 }
79 86
80 PoolEntry* entry = new PoolEntry(); 87 PoolEntry* entry = new PoolEntry();
81 entry->location = loc.clone(); 88 entry->location = loc.clone();
82 m_entries.push_back(entry); 89 m_entries.push_back(entry);
83 size_t index = m_entries.size(); 90 size_t index = m_entries.size() - 1;
84 m_location_to_entry[loc] = index; 91 m_location_to_entry[loc] = index;
85 return index - 1; 92 return index;
86 } 93 }
87 94
88 int Pool::addResourceFromFile(const std::string& filename) { 95 int Pool::addResourceFromFile(const std::string& filename) {
89 return addResourceFromLocation(ResourceLocation(filename)); 96 return addResourceFromLocation(ResourceLocation(filename));
90 } 97 }
91 98
92 IResource& Pool::get(unsigned int index, bool inc) { 99 IResource& Pool::get(unsigned int index, bool inc) {
93 if (index >= m_entries.size()) { 100 if (index >= m_entries.size()) {
94 FL_ERR(_log, LMsg("Tried to get with index ") << index << ", only " << m_entries.size() << " items in pool"); 101 FL_ERR(_log, LMsg("Tried to get with index ") << index << ", only " << m_entries.size() << " items in pool " + m_name);
95 throw IndexOverflow( __FUNCTION__ ); 102 throw IndexOverflow( __FUNCTION__ );
96 } 103 }
97 IResource* res = NULL; 104 IResource* res = NULL;
98 PoolEntry* entry = m_entries[index]; 105 PoolEntry* entry = m_entries[index];
99 if (entry->resource) { 106 if (entry->resource) {
102 if (!entry->loader) { 109 if (!entry->loader) {
103 findAndSetProvider(*entry); 110 findAndSetProvider(*entry);
104 } else { 111 } else {
105 entry->resource = entry->loader->loadResource(*entry->location); 112 entry->resource = entry->loader->loadResource(*entry->location);
106 } 113 }
114
107 if (!entry->loader) { 115 if (!entry->loader) {
108 LMsg msg("No suitable loader was found for resource "); 116 LMsg msg("No suitable loader was found for resource ");
109 msg << entry->location->getFilename(); 117 msg << "#" << index << "<" << entry->location->getFilename()
118 << "> in pool " << m_name;
119 FL_ERR(_log, msg);
120
121 throw NotFound(msg.str);
122 }
123
124 if (!entry->resource) {
125 LMsg msg("No loader was able to load the requested resource ");
126 msg << "#" << index << "<" << entry->location->getFilename()
127 << "> in pool " << m_name;
110 FL_ERR(_log, msg); 128 FL_ERR(_log, msg);
111 throw NotFound(msg.str); 129 throw NotFound(msg.str);
112 } 130 }
113 if (!entry->resource) {
114 LMsg msg("No loader was able to load the requested resource ");
115 msg << entry->location->getFilename();
116 FL_ERR(_log, msg);
117 throw NotFound(msg.str);
118 }
119 res = entry->resource; 131 res = entry->resource;
120 } 132 }
121 if (inc) { 133 if (inc) {
122 res->addRef(); 134 res->addRef();
123 } 135 }
124 res->setPoolId(index); 136 res->setPoolId(index);
125 return *res; 137 return *res;
126 } 138 }
127 139
128 unsigned int Pool::getIndex(const std::string& filename) { 140 int Pool::getIndex(const std::string& filename) {
129 std::vector<PoolEntry*>::iterator it = m_entries.begin();
130 int index = 0;
131
132 // look for the appropriate entry
133 for (; it != m_entries.end(); it++) {
134
135 if ((*it)->location->getFilename() == filename) {
136 return index;
137 }
138 index++;
139 }
140
141 // create resource 141 // create resource
142 return addResourceFromFile(filename); 142 return addResourceFromFile(filename);
143 } 143 }
144 144
145 void Pool::release(unsigned int index, bool dec) { 145 void Pool::release(unsigned int index, bool dec) {
211 } 211 }
212 212
213 void Pool::printStatistics() { 213 void Pool::printStatistics() {
214 FL_LOG(_log, LMsg("Pool not loaded =") << getResourceCount(RES_NON_LOADED)); 214 FL_LOG(_log, LMsg("Pool not loaded =") << getResourceCount(RES_NON_LOADED));
215 FL_LOG(_log, LMsg("Pool loaded =") << getResourceCount(RES_LOADED)); 215 FL_LOG(_log, LMsg("Pool loaded =") << getResourceCount(RES_LOADED));
216 int amount = 0;
217 std::vector<PoolEntry*>::iterator entry;
218 for (entry = m_entries.begin(); entry != m_entries.end(); entry++) {
219 if ((*entry)->resource) {
220 if ((*entry)->resource->getRefCount() > 0) {
221 amount++;
222 }
223 }
224 }
225 FL_LOG(_log, LMsg("Pool locked =") << amount);
216 FL_LOG(_log, LMsg("Pool total size =") << m_entries.size()); 226 FL_LOG(_log, LMsg("Pool total size =") << m_entries.size());
217 } 227 }
218 } 228 }