Mercurial > fife-parpg
view engine/core/util/resource/pool.cpp @ 144:d2f1e81fbe2c
* Fixed a scons issue, where libraries checked for C instead of C++
* Fixed a shutdown order problem - deleting a GLImage will reference the RenderBackend, thus image pools must be deleted first.
* Added an explicit Engine.destroy method to force the shutdown, in case python fails to do so. Necessary - see above.
* The Pool::printStatistics now gives out information how many resources are loaded. Called before destruction. Add 'pool' to the LogModules to check memory pooling issues.
author | phoku@33b003aa-7bff-0310-803a-e67f0ece8222 |
---|---|
date | Thu, 09 Oct 2008 06:18:36 +0000 |
parents | 69a7d40ccf62 |
children | 54b3984e1afc |
line wrap: on
line source
/*************************************************************************** * Copyright (C) 2005-2008 by the FIFE team * * http://www.fifengine.de * * This file is part of FIFE. * * * * FIFE is free software; you can redistribute it and/or * * modify it under the terms of the GNU Lesser General Public * * License as published by the Free Software Foundation; either * * version 2.1 of the License, or (at your option) any later version. * * * * This library is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * * Lesser General Public License for more details. * * * * You should have received a copy of the GNU Lesser General Public * * License along with this library; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * ***************************************************************************/ // Standard C++ library includes // 3rd party library includes // FIFE includes // These includes are split up in two parts, separated by one empty line // First block: files included from the FIFE root src directory // Second block: files included from the same folder #include "util/base/exception.h" #include "util/log/logger.h" #include "pool.h" namespace FIFE { static Logger _log(LM_POOL); Pool::Pool(): m_entries(), m_location_to_entry(), m_listeners(), m_loaders(), m_curind(0) { } Pool::~Pool() { FL_LOG(_log, LMsg("Pool destroyed ")); printStatistics(); clear(); std::vector<ResourceLoader*>::iterator loader; for (loader = m_loaders.begin(); loader != m_loaders.end(); loader++) { delete (*loader); } } void Pool::clear() { std::vector<IPoolListener*>::iterator listener; for (listener = m_listeners.begin(); listener != m_listeners.end(); listener++) { (*listener)->poolCleared(); } std::vector<PoolEntry*>::iterator entry; for (entry = m_entries.begin(); entry != m_entries.end(); entry++) { delete (*entry); } m_entries.clear(); m_location_to_entry.clear(); } void Pool::addResourceLoader(ResourceLoader* loader) { m_loaders.push_back(loader); } int Pool::addResourceFromLocation(const ResourceLocation& loc) { ResourceLocationToEntry::const_iterator it = m_location_to_entry.find(loc); if (it != m_location_to_entry.end()) { return (*it).second; } PoolEntry* entry = new PoolEntry(); entry->location = loc.clone(); m_entries.push_back(entry); size_t index = m_entries.size(); m_location_to_entry[loc] = index; return index - 1; } int Pool::addResourceFromFile(const std::string& filename) { return addResourceFromLocation(ResourceLocation(filename)); } IResource& Pool::get(unsigned int index, bool inc) { if (index >= m_entries.size()) { FL_ERR(_log, LMsg("Tried to get with index ") << index << ", only " << m_entries.size() << " items in pool"); throw IndexOverflow( __FUNCTION__ ); } IResource* res = NULL; PoolEntry* entry = m_entries[index]; if (entry->resource) { res = entry->resource; } else { if (!entry->loader) { findAndSetProvider(*entry); } else { entry->resource = entry->loader->loadResource(*entry->location); } if (!entry->loader) { LMsg msg("No suitable loader was found for resource "); msg << entry->location->getFilename(); FL_ERR(_log, msg); throw NotFound(msg.str); } if (!entry->resource) { LMsg msg("No loader was able to load the requested resource "); msg << entry->location->getFilename(); FL_ERR(_log, msg); throw NotFound(msg.str); } res = entry->resource; } if (inc) { res->addRef(); } res->setPoolId(index); return *res; } unsigned int Pool::getIndex(const std::string& filename) { std::vector<PoolEntry*>::iterator it = m_entries.begin(); int index = 0; // look for the appropriate entry for (; it != m_entries.end(); it++) { if ((*it)->location->getFilename() == filename) { return index; } index++; } // create resource return addResourceFromFile(filename); } void Pool::release(unsigned int index, bool dec) { if (index >= m_entries.size()) { throw IndexOverflow( __FUNCTION__ ); } IResource* res = NULL; PoolEntry* entry = m_entries[index]; if (entry->resource) { res = entry->resource; if (dec) { res->decRef(); } if(res->getRefCount() == 0) { delete entry->resource; entry->resource = 0; } } } int Pool::getResourceCount(int status) { int amount = 0; std::vector<PoolEntry*>::iterator entry; for (entry = m_entries.begin(); entry != m_entries.end(); entry++) { if (status & RES_LOADED) { if ((*entry)->resource) { amount++; } } if (status & RES_NON_LOADED) { if (!(*entry)->resource) { amount++; } } } return amount; } void Pool::addPoolListener(IPoolListener* listener) { m_listeners.push_back(listener); } void Pool::removePoolListener(IPoolListener* listener) { std::vector<IPoolListener*>::iterator i = m_listeners.begin(); while (i != m_listeners.end()) { if ((*i) == listener) { m_listeners.erase(i); return; } ++i; } } void Pool::findAndSetProvider(PoolEntry& entry) { std::vector<ResourceLoader*>::iterator it = m_loaders.begin(); std::vector<ResourceLoader*>::iterator end = m_loaders.end(); if( it == end ) { FL_PANIC(_log, "no loader constructors given for resource pool"); } for(; it != end; ++it) { IResource* res = (*it)->loadResource(*entry.location); if (res) { entry.resource = res; entry.loader = *it; return; } }; } void Pool::printStatistics() { FL_LOG(_log, LMsg("Pool not loaded =") << getResourceCount(RES_NON_LOADED)); FL_LOG(_log, LMsg("Pool loaded =") << getResourceCount(RES_LOADED)); FL_LOG(_log, LMsg("Pool total size =") << m_entries.size()); } }