/* ScummVM - Graphic Adventure Engine * * ScummVM is the legal property of its developers, whose names * are too numerous to list here. Please refer to the COPYRIGHT * file distributed with this source distribution. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * */ /* * Copyright (C) 2006-2010 - Frictional Games * * This file is part of HPL1 Engine. */ #include "hpl1/engine/resources/ResourceManager.h" #include "hpl1/engine/system/String.h" #include "hpl1/engine/resources/FileSearcher.h" #include "hpl1/engine/resources/ResourceBase.h" #include "hpl1/engine/resources/low_level_resources.h" #include "hpl1/engine/system/low_level_system.h" #include "common/algorithm.h" namespace hpl { int iResourceManager::mlTabCount = 0; ////////////////////////////////////////////////////////////////////////// // CONSTRUCTORS ////////////////////////////////////////////////////////////////////////// //----------------------------------------------------------------------- iResourceManager::iResourceManager(cFileSearcher *apFileSearcher, LowLevelResources *apLowLevelResources, LowLevelSystem *apLowLevelSystem) { mpFileSearcher = apFileSearcher; mpLowLevelResources = apLowLevelResources; mpLowLevelSystem = apLowLevelSystem; mlHandleCount = 0; } //----------------------------------------------------------------------- ////////////////////////////////////////////////////////////////////////// // PUBLIC METHODS ////////////////////////////////////////////////////////////////////////// //----------------------------------------------------------------------- iResourceBase *iResourceManager::GetByName(const tString &asName) { tString sName = cString::ToLowerCase(asName); // Log("Looking for '%s' \n", sName.c_str()); tResourceNameMapIt it = m_mapNameResources.find(sName); if (it == m_mapNameResources.end()) return NULL; return it->second; } //----------------------------------------------------------------------- iResourceBase *iResourceManager::GetByHandle(unsigned long alHandle) { tResourceHandleMapIt it = m_mapHandleResources.find(alHandle); if (it == m_mapHandleResources.end()) return NULL; return it->second; } //----------------------------------------------------------------------- cResourceBaseIterator iResourceManager::GetResourceBaseIterator() { return cResourceBaseIterator(&m_mapNameResources); } //----------------------------------------------------------------------- /*void iResourceManager::Destroy(iResourceBase* apResource) { apResource->DecUserCount(); if(apResource->HasUsers()==false){ m_mapHandleResources.erase(apResource->GetHandle()); m_mapNameResources.erase(apResource->GetName()); hplDelete(apResource); } }*/ //----------------------------------------------------------------------- class cSortResources { public: bool operator()(iResourceBase *apResourceA, iResourceBase *apResourceB) { if (apResourceA->GetUserCount() != apResourceB->GetUserCount()) { return apResourceA->GetUserCount() > apResourceB->GetUserCount(); } return apResourceA->GetTime() > apResourceB->GetTime(); } }; //----------------------------------------------------------------------- void iResourceManager::DestroyUnused(int alMaxToKeep) { // Log("Start Num Of: %d\n",m_mapHandleResources.size()); // Check if there are too many resources. if ((int)m_mapHandleResources.size() <= alMaxToKeep) return; // Add resources to a vector Common::Array vResources; vResources.reserve(m_mapHandleResources.size()); tResourceHandleMapIt it = m_mapHandleResources.begin(); for (; it != m_mapHandleResources.end(); ++it) { vResources.push_back(it->second); } // Sort the sounds according to num of users and then time. Common::sort(vResources.data(), vResources.data() + vResources.size(), cSortResources()); // Log("-------------Num: %d-----------------\n",vResources.size()); for (size_t i = alMaxToKeep; i < vResources.size(); ++i) { iResourceBase *pRes = vResources[i]; // Log("%s count:%d time:%d\n",pRes->GetName().c_str(), // pRes->GetUserCount(), // pRes->GetTime()); if (pRes->HasUsers() == false) { RemoveResource(pRes); hplDelete(pRes); } } // Log("--------------------------------------\n"); // Log("End Num Of: %d\n",m_mapHandleResources.size()); } //----------------------------------------------------------------------- void iResourceManager::DestroyAll() { tResourceHandleMapIt it = m_mapHandleResources.begin(); while (it != m_mapHandleResources.end()) { // Log("Start destroy..."); iResourceBase *pResource = it->second; // Log(" res: : %d ...",pResource->GetName().c_str(),pResource->GetUserCount()); while (pResource->HasUsers()) pResource->DecUserCount(); Destroy(pResource); it = m_mapHandleResources.begin(); // Log(" Done!\n"); } } //----------------------------------------------------------------------- ////////////////////////////////////////////////////////////////////////// // PROTECTED METHODS ////////////////////////////////////////////////////////////////////////// //----------------------------------------------------------------------- void iResourceManager::BeginLoad(const tString &asFile) { mlTimeStart = GetApplicationTime(); // Log("Begin resource: %s\n",asFile.c_str()); mlTabCount++; } //----------------------------------------------------------------------- void iResourceManager::EndLoad() { mlTabCount--; } //----------------------------------------------------------------------- iResourceBase *iResourceManager::FindLoadedResource(const tString &asName, tString &asFilePath) { iResourceBase *pResource = GetByName(asName); if (pResource == NULL) { asFilePath = mpFileSearcher->GetFilePath(asName); } else { asFilePath = ""; } return pResource; } //----------------------------------------------------------------------- tString iResourceManager::GetTabs() { tString sTabs = ""; for (int i = 0; i < mlTabCount; ++i) sTabs += " "; return sTabs; } void iResourceManager::AddResource(iResourceBase *apResource, bool abLog) { apResource->SetHandle(GetHandle()); tString sName = cString::ToLowerCase(apResource->GetName()); m_mapHandleResources.insert(tResourceHandleMap::value_type( apResource->GetHandle(), apResource)); m_mapNameResources.insert(tResourceNameMap::value_type( sName, apResource)); if (abLog && iResourceBase::GetLogCreateAndDelete()) { unsigned long lTime = GetApplicationTime() - mlTimeStart; Log("%sLoaded resource %s in %d ms\n", GetTabs().c_str(), apResource->GetName().c_str(), lTime); apResource->SetLogDestruction(true); } // Log("End resource: %s\n",apResource->GetName().c_str()); } //----------------------------------------------------------------------- void iResourceManager::RemoveResource(iResourceBase *apResource) { m_mapHandleResources.erase(apResource->GetHandle()); m_mapNameResources.erase(cString::ToLowerCase(apResource->GetName())); // Log("Removing %s %d %d!\n", apResource->GetName().c_str(),x,y); } //----------------------------------------------------------------------- unsigned long iResourceManager::GetHandle() { return mlHandleCount++; } //----------------------------------------------------------------------- } // namespace hpl