一个使用模板的资源管理器,
该类可以扩充,也可以使用基本功能,
有模板和派生双重灵活性。
//以下为ResourceMgr.h
//潘李亮,版权所有,2005.11-4
#ifndef __TEMPLATE_RESOURCE_MGR_H__
#define __TEMPLATE_RESOURCE_MGR_H__
#include <map>
#include <vector>
using namespace std;
template <typename ResType> class TBaseResMgr;
//-------------------------------------------------
//定义一个空资源类,如果不想派生这个ResMgr
//的话,需要你的ResType用下面两个函数来load/unload
//-------------------------------------------------
class XNullRes
{
public:
bool load(const char* resName){return true;}
bool unload(){return true;}
};
//-------------------------------------------------
//资源句柄类
//-------------------------------------------------
template <typename ResType> class TResHandle
{
typedef TBaseResMgr<ResType> MyResMgr;
friend class MyResMgr;
MyResMgr* m_pResMgr;
int m_iData;
//面向资源管理器的类
public:
TResHandle(){m_pResMgr = NULL;}
MyResMgr* getOwner(){return m_pResMgr;}
int data(){return m_iData;}
//面向用户的类
public:
ResType* getResource();
bool confirm();
bool invalidate();
bool isHandle(){return m_pResMgr != NULL;}
};
//------------------------------------------------------
//Resource Manager的接口,
//所有的不同类型的Resource Manager都可以用这个接口来进行
//一些相同功能的操作
//------------------------------------------------------
class IResManager
{
public:
virtual void unload() = 0;
virtual void loadAll() = 0;
virtual void update(unsigned int passedTime) = 0;
virtual void release() = 0;
};
//------------------------------------------------------
//资源管理器类的基类
//基类不知道如何 创建和销毁一个实际资源,
//只负责管理逻辑
//------------------------------------------------------
template <typename ResType> class TBaseResMgr : public IResManager
{
protected:
struct ResSlot
{
ResType* m_pRes;
string m_ResName;
};
typedef vector<ResSlot> ResSlots;
typedef map<string,int> StringToIndexMap;
typedef TResHandle<ResType> MyResHandle;
ResSlots m_ResSlots;
StringToIndexMap m_StrToIndexMap;
virtual ResType* _load(const char* strResName) = 0;
virtual bool _unload(ResType* pRes) = 0;
MyResHandle _add(ResType* pRes,const char* strResName)
{
MyResHandle handle;
handle.m_iData = m_ResSlots.size();
handle.m_pResMgr = this;
m_StrToIndexMap.insert(StringToIndexMap::value_type(strResName,handle.m_iData));
m_ResSlots.push_back(ResSlot());
ResSlot& Slot = m_ResSlots[handle.m_iData];
Slot.m_pRes = pRes;
Slot.m_ResName = strResName;
return handle;
}
public:
ResType* getResource(MyResHandle& handle)
{
if(isHandle(handle) == false)
return NULL;
ResSlot& slot = m_ResSlots[handle.m_iData];
return slot.m_pRes;
}
MyResHandle add(const char* strResName,bool bLoadImmediate)
{
MyResHandle handle = find(strResName);
if(handle.isHandle())
{
return handle;
}
else
{
ResType* pRes = NULL;
if(bLoadImmediate)
{
pRes = _load(strResName);
if(pRes == NULL)
{
MyResHandle handle;
return handle;
}
}
handle = _add(pRes,strResName);
return handle;
}
}
bool isHandle(MyResHandle& handle)
{
if(handle.m_iData < 0 ) return false;
if(handle.m_iData >= (int)m_ResSlots.size()) return false;
if(handle.m_pResMgr != this) return false;
return true;
}
bool confirm(MyResHandle& handle)
{
if( !isHandle(handle))
return false;
ResSlot& Slot = m_ResSlots[handle.m_iData];
if(Slot.m_pRes != NULL)
return true;
else
{
Slot.m_pRes = _load(Slot.m_ResName.c_str());
return true;
}
}
MyResHandle find(const char* strResName)
{
MyResHandle handle;
StringToIndexMap::iterator iPos = m_StrToIndexMap.find(strResName);
if(iPos != m_StrToIndexMap.end() )
{
handle.m_iData = iPos->second;
handle.m_pResMgr = this;
return handle;
}
handle.m_pResMgr = NULL;
return handle;
}
bool unload(MyResHandle handle)
{
assert(handle.m_pResMgr == this);
ResSlot& slot = m_ResSlots[handle.m_iData];
return _unload(slot.m_pRes);
}
//虚函数,行为可以继承
public:
virtual void loadAll()
{
size_t i = 0;
size_t n = m_ResSlots.size();
for(i = 0 ; i < n ; ++i)
{
ResSlot& Slot = m_ResSlots[i];
if(Slot.m_pRes == NULL)
{
Slot.m_pRes = _load(Slot.m_ResName.c_str());
}
}
}
virtual void update(unsigned int passedTime)
{
}
virtual void unload()
{
size_t nRes = m_ResSlots.size();
for(size_t i = 0 ; i < nRes ; i++)
{
ResSlot& slot = m_ResSlots[i];
_unload(slot.m_pRes);
}
}
virtual void release()
{
unload();
m_ResSlots.clear();
m_StrToIndexMap.clear();
}
};
//-----------------------------------------------------------------------------------
//一个通用的ResMgr,
//只要求ResType实现了XNullRes的接口
//-----------------------------------------------------------------------------------
template <typename ResType> class TCommonResMgr: public TBaseResMgr<ResType>
{
protected:
ResType* _load(const char* strResName)
{
ResType* pRes = new ResType;
pRes->load(strResName);
return pRes;
}
bool _unload(ResType* pRes)
{
pRes->unload();
delete pRes;
return ;
}
};
//--------------------------------------------------------------------
// Resource Hanlde 的实现函数
//--------------------------------------------------------------------
template <typename ResType> ResType* TResHandle<ResType>::getResource()
{
return m_pResMgr->getResource(*this);
}
template <typename ResType> bool TResHandle<ResType>::confirm()
{
return m_pResMgr->confirm(*this);
}
template <typename ResType> bool TResHandle<ResType>::invalidate()
{
return m_pResMgr->unload(*this);
}
#endif
//end of the ResourceMgr.h
//--------------------------------------------------------------------------------------------------------
//以下类具体实现了一个ResManager
//因为XRMTexture没有load/unload函数,所以需要重载TBaseResMgr.
//如果XRMTexture实现了XNullRes的两个函数,那么可以简单使用 TCommonResMgr类
//--------------------------------------------------------------------------------------------------------
class XRMTextureMgr;
class XRMTexture
{
unsigned int m_hTexture;
int m_iStage;
string m_TextureName;
friend class XRMTextureMgr;
XRMTexture(){}
public:
bool create(const char* filename);
bool create(const char* filename,const char* buf,int buflen);
void apply(int iStage);
void load();
void unload();
void free();
};
typedef TResHandle<XRMTexture> HRMTexture;
class XRMTextureMgr: public TBaseResMgr<XRMTexture>
{
XRMTexture* _load(const char* strResName)
{
XRMTexture* pTex = new XRMTexture;
if(pTex->create(strResName) ==false)
{
delete pTex;
return NULL;
}
return pTex;
}
bool _unload(XRMTexture* pTex)
{
pTex->unload();
delete pTex;
return true;
}
public:
HRMTexture addTexture(const char* filename,const char* buf,int buflen,bool bLoadImmediate)
{
HRMTexture handle = find(filename);
if(handle.isHandle())
{
return handle;
}
else
{
XRMTexture* pRes = new XRMTexture;
bool ret = pRes->create(filename,buf,buflen);
if(ret == false)
{
delete pRes;
HRMTexture hTexture;
return hTexture;
}
handle = _add(pRes,filename);
return handle;
}
}
};
extern XRMTextureMgr g_RMTexMgr;
//==================================
//具体使用如下
//==================================
HRMTexture hTexture = g_RMTexture.add("pll.jpg",true);
if(hTexture.isHandle() == false)
hTexture = g_RMTexture.addTexture("pll.jpg", pFileDataInMem,file_len,true);
assert(hTexture.isHandle() );
//使用纹理对象,
if(hTexture.getResource()) hTexture.getResource()->apply(0);