Mercurial > fife-parpg
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 } |