00001 #ifndef HEADER_RESOURCEPACK_H
00002 #define HEADER_RESOURCEPACK_H
00003
00004 #include "Log.h"
00005 #include "Random.h"
00006 #include "INamed.h"
00007 #include "ResourceException.h"
00008
00009 #include <string>
00010 #include <vector>
00011 #include <map>
00012
00013
00014
00015
00016 template <class T>
00017 class ResourcePack : public INamed {
00018 public:
00019 typedef std::vector<T> t_range;
00020 protected:
00021 typedef std::multimap<std::string,T> t_reses;
00022 typedef typename t_reses::iterator t_resIterator;
00023 typedef typename t_reses::const_iterator t_constIterator;
00024 t_reses m_reses;
00025 virtual void unloadRes(T res) = 0;
00026
00027 public:
00028
00029
00030 virtual ~ResourcePack()
00031 {
00032 if (!m_reses.empty()) {
00033 LOG_WARNING(ExInfo("resources are not released")
00034 .addInfo("pack", toString()));
00035 }
00036 }
00037
00038
00039
00040
00041
00042 void removeAll()
00043 {
00044 t_resIterator end = m_reses.end();
00045 for (t_resIterator item = m_reses.begin(); item != end; ++item) {
00046 unloadRes(item->second);
00047 }
00048 m_reses.clear();
00049 }
00050
00051
00052
00053
00054 void removeRes(const std::string &name)
00055 {
00056 std::pair<t_resIterator, t_resIterator> range =
00057 m_reses.equal_range(name);
00058 while (range.first != range.second) {
00059 unloadRes(range.first->second);
00060 ++(range.first);
00061 }
00062 m_reses.erase(name);
00063 LOG_DEBUG(ExInfo("removed resources")
00064 .addInfo("name", name));
00065 }
00066
00067
00068
00069
00070
00071 void addRes(const std::string &name, T res)
00072 {
00073 m_reses.insert(
00074 std::pair<std::string,T>(name, res));
00075 }
00076
00077
00078
00079
00080 T getRes(const std::string &name, int rank=0)
00081 {
00082 std::pair<t_resIterator, t_resIterator> range =
00083 m_reses.equal_range(name);
00084 for (int i = 0; i < rank && range.first != range.second; ++i) {
00085 ++(range.first);
00086 }
00087 if (range.second == range.first) {
00088 throw ResourceException(ExInfo("no such resource at index")
00089 .addInfo("name", name)
00090 .addInfo("index", rank)
00091 .addInfo("pack", toString()));
00092 }
00093 return range.first->second;
00094 }
00095
00096
00097
00098
00099
00100 t_range getRange(const std::string &name)
00101 {
00102 t_range result;
00103 std::pair<t_resIterator, t_resIterator> range =
00104 m_reses.equal_range(name);
00105 while (range.first != range.second) {
00106 result.push_back(range.first->second);
00107 range.first++;
00108 }
00109
00110 return result;
00111 }
00112
00113
00114
00115
00116 T getRandomRes(const std::string &name)
00117 {
00118 T result = NULL;
00119 typename t_reses::size_type count = m_reses.count(name);
00120 if (count > 0) {
00121 result = getRes(name, Random::randomInt(count));
00122 }
00123 else {
00124 LOG_WARNING(ExInfo("no such resource")
00125 .addInfo("name", name)
00126 .addInfo("pack", toString()));
00127 }
00128 return result;
00129 }
00130
00131
00132
00133
00134 int countRes(const std::string &name)
00135 {
00136 return m_reses.count(name);
00137 }
00138
00139 std::string toString() const
00140 {
00141 ExInfo available_res = ExInfo("resources")
00142 .addInfo("name", getName());
00143
00144 t_constIterator end = m_reses.end();
00145 for (t_constIterator item = m_reses.begin(); item != end; ++item) {
00146 available_res.addInfo("key", item->first);
00147 }
00148 return available_res.info();
00149 }
00150
00151 };
00152
00153 #endif
00154