open source
This commit is contained in:
@@ -0,0 +1,223 @@
|
||||
/**
|
||||
@file JCResManager.h
|
||||
@brief
|
||||
@author James
|
||||
@version 1.0
|
||||
@date 2016_5_12
|
||||
*/
|
||||
|
||||
#ifndef __JCResManager_H__
|
||||
#define __JCResManager_H__
|
||||
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <list>
|
||||
#include <thread>
|
||||
#include <mutex>
|
||||
#include "JCResource.h"
|
||||
|
||||
#define SLEEPINGAGE 300
|
||||
|
||||
namespace laya
|
||||
{
|
||||
/**
|
||||
* @brief
|
||||
资源管理的基类。
|
||||
laya的资源管理方法介绍:
|
||||
manager主要管理两个东西,
|
||||
1 根据key(目前是url)来查找资源,这个随着资源的增加会一直增加,除非显式调用删除函数
|
||||
2 一个活动资源列表。所谓活动资源就是正常状态的资源。与之相对的是非活动资源,即主要内存已经释放,只保留壳的资源。
|
||||
这个列表是不完整的,不能用来查找资源
|
||||
几个典型问题:
|
||||
1.资源的创建
|
||||
1) 外部自己创建,通过addRes来添加到资源管理中
|
||||
2) 以通过manager的 getRes(url,true)来创建,同时会调用增加资源。
|
||||
为了避免使用模板(否则不知道new什么),先不用这种方法
|
||||
2.内存清理
|
||||
当add或者restore后的总内存超出上限了,就需要进行内存清理。为了效率,这里的内存清理不会实时进行。
|
||||
有的资源不希望删除,需要加一个bool canFree()的函数么?
|
||||
如果不希望删除,则不要添加到资源管理中。
|
||||
问题:
|
||||
map的key都是string么?可能是起来类型么。需要用模板来表示key么
|
||||
原来的mesh2d 是 url+textureGroup
|
||||
如果一个资源就超出了上限怎么办
|
||||
某个res增加内存的时候,不能把自己释放掉
|
||||
测试
|
||||
函数的多次调用
|
||||
可能会出的问题
|
||||
资源活动列表有多个相同的资源
|
||||
*/
|
||||
class JCResManager
|
||||
{
|
||||
public:
|
||||
|
||||
typedef JCResource* ResType;
|
||||
typedef std::map<std::string, ResType> ResMap;
|
||||
typedef std::vector<ResType> ResVector;
|
||||
|
||||
public:
|
||||
|
||||
JCResManager(int p_nFreeSize,bool bUseMap);
|
||||
|
||||
~JCResManager();
|
||||
|
||||
//设置定期清理的大小
|
||||
void setFreeSize( unsigned int p_nFreeSize );
|
||||
|
||||
void setFreeSize( unsigned int p_nFreeSize, unsigned int p_nMaxSize );
|
||||
|
||||
//设置强制清理的大小
|
||||
void setMaxSize(int p_nSize)
|
||||
{
|
||||
m_nMaxSize = p_nSize;
|
||||
}
|
||||
|
||||
unsigned int getFreeSize() { return m_nFreeSize; }
|
||||
|
||||
unsigned int getMaxSize() { return m_nMaxSize; }
|
||||
|
||||
//返回执行了多少次free的操作,用来做效率检测
|
||||
unsigned int getFreedCount() { return m_nFreedCount; }
|
||||
|
||||
void resetFreeCount() { m_nFreedCount = 0; }
|
||||
|
||||
/*
|
||||
查找一个资源。
|
||||
注意,为了效率不要频繁调用
|
||||
如果需要创建,则改名成 getRes
|
||||
*/
|
||||
ResType find(const std::string& p_key );
|
||||
|
||||
ResType find(int nKey)
|
||||
{
|
||||
return m_AllResVector[nKey];
|
||||
}
|
||||
|
||||
//这个只有一个res资源,只能处理活动列表的问题,不能根据map来查找。
|
||||
//多次调用不会导致内存统计错误
|
||||
void add(ResType pRes);
|
||||
|
||||
/*
|
||||
从活动列表中删除某个资源。
|
||||
并不影响map
|
||||
bDel true 表示不需要资源为恢复做些工作。即这个资源以后不会用到了
|
||||
*/
|
||||
bool freeRes(ResType pRes, bool bDel );
|
||||
|
||||
/*
|
||||
从map中删除。如果 bDel为true,则同时删除对象。
|
||||
返回值:
|
||||
true 找到这个资源了
|
||||
false 没有这个资源
|
||||
*/
|
||||
bool delRes( const std::string& p_key, bool bDel );
|
||||
|
||||
bool delRes(int p_key, bool bDel);
|
||||
|
||||
//每帧都会调用的。
|
||||
//由于resManager不会太多,所以可以每帧都调用,不用用请求列表的方式。
|
||||
void tick();
|
||||
|
||||
//删除所有的,这个不会有回调
|
||||
void destroyAll(bool bDelObj=false);
|
||||
|
||||
//释放所有的。会有回调
|
||||
void freeAll();
|
||||
|
||||
//返回实际释放的大小
|
||||
int freeRes(int p_nSize );
|
||||
|
||||
/*
|
||||
pRes的大小变化了,需要重新统计。这个会引起touch
|
||||
这个操作不会导致pRes被释放。
|
||||
*/
|
||||
void updateRes(ResType pRes );
|
||||
|
||||
/*
|
||||
加到map中。
|
||||
加到活动列表中。
|
||||
*/
|
||||
void setItem(ResType pRes, const char* name);
|
||||
|
||||
void setItem(ResType pRes, int nID);
|
||||
|
||||
/*
|
||||
只是加到map中
|
||||
*/
|
||||
void addToAllRes(ResType pRes, const char* name);
|
||||
|
||||
void addToAllRes(ResType pRes, int nID);
|
||||
|
||||
void touchRes( ResType pRes, bool restoreRes=false );
|
||||
|
||||
void useSetResLock(bool b)
|
||||
{
|
||||
m_bUseSetResLock = b;
|
||||
}
|
||||
|
||||
void chkThread(bool b)
|
||||
{
|
||||
m_bChkThread = b;
|
||||
}
|
||||
|
||||
/*
|
||||
统计活动列表所有对象实际占用的资源大小,与资源管理器统计的资源大小是否一致。
|
||||
这个是测试用的,如果不一致,则会产生bug。
|
||||
*/
|
||||
bool chkMemSize();
|
||||
|
||||
unsigned int count()
|
||||
{
|
||||
return m_bUseMap?m_AllRes.size():m_AllResVector.size();
|
||||
}
|
||||
|
||||
/*
|
||||
设置当前线程为期望共工作线程。
|
||||
如果设置了chkThread(true)则当关键函数在另外的线程中工作的时候,会抛异常。
|
||||
*/
|
||||
void InitWorkThread();
|
||||
|
||||
void printfActiveTextureInfo();
|
||||
|
||||
/*
|
||||
当pRes恢复或者释放的时候都会调用到这个来更新占用内存
|
||||
*/
|
||||
void updateSz(ResType pRes);
|
||||
|
||||
int getGlobalID();
|
||||
|
||||
public:
|
||||
bool m_bUseMap;
|
||||
ResMap m_AllRes;
|
||||
int m_nGlobalID;
|
||||
ResVector m_AllResVector;
|
||||
typedef simpList ResList;
|
||||
ResList m_ActiveRes; //活动状态的资源列表。
|
||||
unsigned int m_nCurTick; //需要一个心跳。
|
||||
unsigned int m_nNextCleanTick; //下次清理的时间
|
||||
std::recursive_mutex m_Lock;
|
||||
unsigned int m_nCurSize; //当前占用的大小
|
||||
unsigned int m_nFreeSize; //触发间隔清理的阀值
|
||||
unsigned int m_nMaxSize; //触发强制清理的阀值
|
||||
bool m_bReleasing;
|
||||
int m_nID;
|
||||
protected:
|
||||
|
||||
std::recursive_mutex m_setResLock;
|
||||
bool m_bUseSetResLock; //是否使用m_setResLock. 例如如果都在一个线程,则没必要使用lock,以免影响效率。
|
||||
|
||||
protected:
|
||||
ResType m_pUpdatingSzRes; //请求进入的资源,清理资源的时候,不会去清理这个资源。
|
||||
bool m_bChkThread;
|
||||
std::thread::id m_WorkThread;
|
||||
ResType m_pLastTouchedRes; //记录上次touch的对象。目的是为了提高效率。例如使用大图集的人,会有很多次相邻的touch完全相同
|
||||
unsigned int m_nFreedCount;
|
||||
};
|
||||
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
|
||||
#endif //__JCResManager_H__
|
||||
|
||||
//-----------------------------END FILE--------------------------------
|
||||
Reference in New Issue
Block a user