src/ResourceManager/ResourceManager.cpp

Go to the documentation of this file.
00001 /* Crown and Cutlass
00002  * Resource Manager Code
00003  */
00004 
00005 #include <string>
00006 #include <map>
00007 #include <vector>
00008 #include "../Log.h"
00009 #include "../tinyxml.h"
00010 #include "../ccmath.h"
00011 #include "IResource.h"
00012 #include "IResourceFactory.h"
00013 #include "ResourceManager.h"
00014 
00015 using namespace std;
00016 
00017 struct ResourceEntry {
00018   IResource *resource;
00019   unsigned int refCount;
00020 };
00021 
00022 ResourceManager* ResourceManager::s_resourceManager = NULL;
00023 
00024 ResourceManager::ResourceManager() {
00025   // Does anything need to happen here?
00026   Log::s_log->Message("Resource manager initialized");
00027 }
00028 
00029 ResourceManager::~ResourceManager() {
00030   ResourceEntry *entry;
00031   string key;
00032 
00033   m_typeVectors.clear();
00034 
00035   // Loop through all the resources, free them and the ResourceEntry the map was using
00036   while (!m_resources.empty()) {
00037     entry = m_resources.begin()->second;
00038     key = m_resources.begin()->first;
00039     delete entry->resource;
00040     m_resources.erase(key);
00041     delete entry;
00042   }
00043 
00044   if (!m_resources.empty()) {
00045     Log::s_log->Message("Warning: Could not empty resource map");
00046   }
00047 
00048   Log::s_log->Message("Resource manager shut down");
00049 }
00050 
00051 IResource* ResourceManager::Acquire(string key) {
00052   ResourceEntry *entry;
00053 
00054   entry = m_resources[key];
00055   if (entry == NULL) {
00056     throw string("Key not found in resource map (" + key + ")");
00057   }
00058 
00059   return DoAcquireResource(entry);
00060 }
00061 
00062 IResource* ResourceManager::AcquireRandom(string type) {
00063   ResourceEntryVector resources;
00064   unsigned int index;
00065   ResourceEntry *entry;
00066 
00067   resources = m_typeVectors[type];
00068   if (resources.empty()) {
00069     throw string("Zero resources of type " + type + " found");
00070   }
00071 
00072   index = (unsigned int) randInt(resources.size() - 1);
00073   entry = resources[index];
00074   Log::s_log->Message("Got random resource: %s", entry->resource->GetKey().c_str());
00075 
00076   return DoAcquireResource(entry);
00077 }
00078 
00079 IResource* ResourceManager::DoAcquireResource(ResourceEntry *entry) {
00080   // Check to see if this is the first use of this resource, load it if it is
00081   if (entry->refCount == 0) {
00082     entry->resource->Load();
00083   }
00084   // Increment the reference count
00085   ++entry->refCount;
00086 
00087   return entry->resource;
00088 }
00089 
00090 void ResourceManager::Release(IResource *resource) {
00091   ResourceEntry *entry;
00092 
00093   entry = m_resources[resource->GetKey()];
00094   if (entry == NULL) {
00095     throw string("Key not found in resource map (" + resource->GetKey() + ")");
00096   }
00097 
00098   // Decrement the reference count
00099   --entry->refCount;
00100   // Check to see if we are releasing the last reference to this resource, and unload it if we are
00101   if (entry->refCount == 0) {
00102     entry->resource->Unload();
00103   }
00104 }
00105 
00106 void ResourceManager::LoadXMLFile(std::string filename, auto_ptr<IResourceFactory> factory) {
00107   TiXmlElement *elem;
00108   TiXmlDocument doc( filename.c_str() );
00109 
00110   doc.LoadFile();
00111   if (doc.Error()) {
00112     // Should throw an exception
00113     Log::s_log->Message("Warning: Could not load %s. %s (line %d, column %d)", filename.c_str(), doc.ErrorDesc(), doc.ErrorRow(), doc.ErrorCol());
00114     return;
00115   }
00116 
00117   for (elem = doc.FirstChildElement("Resources")->FirstChildElement("Resource"); elem; elem = elem->NextSiblingElement("Resource")) {
00118     ResourceEntry *entry = new ResourceEntry;
00119     entry->refCount = 0;
00120     try {
00121       entry->resource = factory->NewResource(elem);
00122       if (entry->resource == NULL) {
00123         throw string("Factory returned null pointer");
00124       }
00125       m_resources[entry->resource->GetKey()] = entry;
00126 
00127       m_typeVectors[entry->resource->GetType()].push_back(entry);
00128     } catch (string e) {
00129       delete entry;
00130       throw e;
00131     }
00132   }
00133 
00134   Log::s_log->Message("Resource file %s loaded", filename.c_str());
00135 }
00136 
00137 void ResourceManager::LogDebugInfo() {
00138   Log::s_log->Message("%d total resources", m_resources.size());
00139 }
00140 
00141 void ResourceManager::Initialize() {
00142   if (s_resourceManager != NULL) {
00143     Log::s_log->Message("Warning: Attempt to re-initialize resource manager");
00144     return;
00145   }
00146 
00147   s_resourceManager = new ResourceManager();
00148 }
00149 
00150 void ResourceManager::Shutdown() {
00151   if (s_resourceManager == NULL) {
00152     Log::s_log->Message("Warning: Attempt to re-shutdown resource manager");
00153     return;
00154   }
00155   delete s_resourceManager;
00156   s_resourceManager = NULL;
00157 }
00158 

Generated on Mon Jan 8 22:34:12 2007 for CrownandCutlass by  doxygen 1.4.7