00001 // resmanager.h 00002 // 00003 // Copyright (C) 2001 Chris Laurel <claurel@shatters.net> 00004 // 00005 // This program is free software; you can redistribute it and/or 00006 // modify it under the terms of the GNU General Public License 00007 // as published by the Free Software Foundation; either version 2 00008 // of the License, or (at your option) any later version. 00009 00010 #ifndef _CELUTIL_RESMANAGER_H_ 00011 #define _CELUTIL_RESMANAGER_H_ 00012 00013 #include <string> 00014 #include <vector> 00015 #include <map> 00016 #include <celutil/reshandle.h> 00017 00018 00019 enum ResourceState { 00020 ResourceNotLoaded = 0, 00021 ResourceLoaded = 1, 00022 ResourceLoadingFailed = 2, 00023 }; 00024 00025 00026 template<class T> class ResourceInfo 00027 { 00028 public: 00029 ResourceInfo() : state(ResourceNotLoaded), resource(NULL) {}; 00030 virtual ~ResourceInfo() {}; 00031 00032 virtual std::string resolve(const std::string&) = 0; 00033 virtual T* load(const std::string&) = 0; 00034 00035 typedef T ResourceType; 00036 ResourceState state; 00037 std::string resolvedName; 00038 T* resource; 00039 }; 00040 00041 00042 template<class T> class ResourceManager 00043 { 00044 private: 00045 std::string baseDir; 00046 00047 public: 00048 ResourceManager(); 00049 ResourceManager(std::string _baseDir) : baseDir(_baseDir) {}; 00050 ~ResourceManager(); 00051 00052 typedef typename T::ResourceType ResourceType; 00053 00054 private: 00055 typedef std::vector<T> ResourceTable; 00056 typedef std::map<T, ResourceHandle> ResourceHandleMap; 00057 typedef std::map<std::string, ResourceType*> NameMap; 00058 00059 typedef typename ResourceHandleMap::value_type ResourceHandleMapValue; 00060 typedef typename NameMap::value_type NameMapValue; 00061 00062 ResourceTable resources; 00063 ResourceHandleMap handles; 00064 NameMap loadedResources; 00065 00066 public: 00067 ResourceHandle getHandle(const T& info) 00068 { 00069 typename ResourceHandleMap::iterator iter = handles.find(info); 00070 if (iter != handles.end()) 00071 { 00072 return iter->second; 00073 } 00074 else 00075 { 00076 ResourceHandle h = handles.size(); 00077 resources.insert(resources.end(), info); 00078 handles.insert(ResourceHandleMapValue(info, h)); 00079 return h; 00080 } 00081 } 00082 00083 ResourceType* find(ResourceHandle h) 00084 { 00085 if (h >= (int) handles.size() || h < 0) 00086 { 00087 return NULL; 00088 } 00089 else 00090 { 00091 if (resources[h].state == ResourceNotLoaded) 00092 { 00093 resources[h].resolvedName = resources[h].resolve(baseDir); 00094 typename NameMap::iterator iter = 00095 loadedResources.find(resources[h].resolvedName); 00096 if (iter != loadedResources.end()) 00097 { 00098 resources[h].resource = iter->second; 00099 resources[h].state = ResourceLoaded; 00100 } 00101 else 00102 { 00103 resources[h].resource = resources[h].load(resources[h].resolvedName); 00104 if (resources[h].resource == NULL) 00105 { 00106 resources[h].state = ResourceLoadingFailed; 00107 } 00108 else 00109 { 00110 resources[h].state = ResourceLoaded; 00111 loadedResources.insert(NameMapValue(resources[h].resolvedName, resources[h].resource)); 00112 } 00113 } 00114 } 00115 00116 if (resources[h].state == ResourceLoaded) 00117 return resources[h].resource; 00118 else 00119 return NULL; 00120 } 00121 } 00122 00123 const T* getResourceInfo(ResourceHandle h) 00124 { 00125 if (h >= (int) handles.size() || h < 0) 00126 return NULL; 00127 else 00128 return &resources[h]; 00129 } 00130 }; 00131 00132 #endif // _CELUTIL_RESMANAGER_H_ 00133
1.4.1