Main Page | Class Hierarchy | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals

ResourcePack.h

Go to the documentation of this file.
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  * Share resources.
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     //NOTE: we cannot call virtual functions from desctructor,
00029     // call removeAll before delete
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      * Free all resources.
00040      * NOTE: we cannot call virtual functions from desctructor
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      * Unload all resources with this name.
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      * Store resource under this name.
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      * Get resource with this name.
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      * Get all resources with this name.
00098      * NOTE: range can be empty.
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      * Get resource at random index or return NULL.
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      * Count resources with this name.
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 

Generated on Wed Jun 1 09:54:31 2005 for Fish Fillets - Next Generation by  doxygen 1.4.2