Files
Client/Engine/Zalla3D Base Class/ResourceMgr.h
LGram16 e067522598 Initial commit: ROW Client source code
Game client codebase including:
- CharacterActionControl: Character and creature management
- GlobalScript: Network, items, skills, quests, utilities
- RYLClient: Main client application with GUI and event handlers
- Engine: 3D rendering engine (RYLGL)
- MemoryManager: Custom memory allocation
- Library: Third-party dependencies (DirectX, boost, etc.)
- Tools: Development utilities

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-29 16:24:34 +09:00

519 lines
9.9 KiB
C++

#pragma once
#include "iresourcemgr.h"
#include "CrossMHeader.h"
#include "ResourceObj.h"
#include "../zalla3d scene class/SceneManager.h"
namespace CROSSM {
#define RESOURCE_MAXCOUNT 70
#define RESOURCE_MAXDELCOUNT 5
#define SG_RESOURCE_RELEASEPROCESS
class CResourceMgrObj
{
public:
CResourceMgrObj() : m_iObjsNum(0)
{
m_lstObjs.clear();
}
CResourceMgrObj(int iResourceType,CResourceObj *pObj) : m_iObjsNum(1)
{
m_lstObjs.clear();
m_lstObjs.push_back(pObj);
pObj->SetType(iResourceType);
pObj->AddRef();
}
~CResourceMgrObj()
{
for(int i = 0; i < m_iObjsNum; i++ )
{
//SafeDelete(m_lstObjs[i]);
if(m_lstObjs[i])
{
CSceneManager::_ReleaseObj(m_lstObjs[i]->GetType(),m_lstObjs[i]);
m_lstObjs[i] = NULL;
}
}
m_lstObjs.clear();
}
int AddObj(int iResourceType,CResourceObj *pObj)
{
m_iObjsNum++;
m_lstObjs.push_back(pObj);
pObj->AddRef();
pObj->SetType(iResourceType);
return m_iObjsNum;
}
CResourceObj *GetObj(int iNum)
{
if(iNum < m_iObjsNum)
{
m_lstObjs[iNum]->AddRef();
return m_lstObjs[iNum];
}
return NULL;
}
bool IsLoaded(int iNum)
{
if(iNum < m_iObjsNum)
{
return m_lstObjs[iNum]->IsLoaded();
}
return false;
}
bool ReleaseObj(int iNum)
{
if(iNum < m_iObjsNum)
{
// if(!m_lstObjs[iNum]->IsLoaded()) // Load 가 끝나지 않은객체는 지워지지 않는다.
// return false;
if(m_lstObjs[iNum]->Release() <= 0)
{
#ifndef SG_RESOURCE_RELEASEPROCESS
m_iObjsNum--;
m_lstObjs.erase(&m_lstObjs[iNum]);
#endif
return true;
}
}
return false;
}
#ifdef SG_RESOURCE_RELEASEPROCESS
bool RealReleaseObj(int iNum)
{
if(iNum < m_iObjsNum)
{
if(m_lstObjs[iNum]->GetRef() <= 0) // DelList 에 있는 노드들 지울때 사용하므로 실제적 ref count는 감소하면 안된다.
{
if(m_lstObjs[iNum]->RealRelease() <= 0)
{
m_iObjsNum--;
m_lstObjs.erase(m_lstObjs.begin() + iNum);
return true;
}
}
}
return false;
}
#endif
int m_iObjsNum;
std::vector<CResourceObj *> m_lstObjs;
};
class CDelResourceInfo
{
public:
unsigned long m_iID;
char m_strName[256];
void SetValue(unsigned long iID,const char *strName)
{
m_iID = iID;
strcpy(m_strName,strName);
}
CDelResourceInfo() : m_iID(0)
{
memset(m_strName,0,sizeof(char) * 256);
}
CDelResourceInfo(unsigned long iID,const char *strName)
{
m_iID = iID;
strcpy(m_strName,strName);
}
~CDelResourceInfo()
{}
};
typedef std::map<unsigned long , CResourceMgrObj *> RESOURCEMGRTABLE;
typedef RESOURCEMGRTABLE::value_type RESOURCEMGRTABLEOBJ;
typedef RESOURCEMGRTABLE::iterator RESOURCEMGRTABLEITER;
template <class T>
class CResourceMgr :
public IResourceMgr
{
public:
CResourceMgr(void) : m_iResourceObjsNum(0), m_iMaxCount(RESOURCE_MAXCOUNT),m_DelObjNums(0)
{
m_ResourceTable.clear();
m_iDelCount = 0;
// 2005.01.10 yundi 즉시 로드 상태를 위한 변수 추가
m_nLockedImmediateLoadCount = 0;
}
virtual ~CResourceMgr(void)
{
if(m_iResourceObjsNum > 0)
{
for(RESOURCEMGRTABLEITER itr = m_ResourceTable.begin(); itr != m_ResourceTable.end();)
{
if(itr->second != NULL)
{
SafeDelete(itr->second);
//CSceneManager::_ReleaseObj(POOL_RESOURCEMGROBJ,itr->second);
itr->second = NULL;
}
itr++;
}
m_ResourceTable.clear();
m_iResourceObjsNum = 0;
}
while(!m_DelObjQueue.empty())
{
CDelResourceInfo *pDelObj = m_DelObjQueue.front();
m_DelObjQueue.pop();
SafeDelete(pDelObj);
// CSceneManager::_ReleaseObj(POOL_DELRESOURCEINFOOBJ,pDelObj);
}
}
void SetMaxCount(int iCount)
{
m_iMaxCount = iCount;
}
virtual void ReleaseAllData()
{
if(m_iResourceObjsNum > 0)
{
for(RESOURCEMGRTABLEITER itr = m_ResourceTable.begin(); itr != m_ResourceTable.end();)
{
if(itr->second != NULL)
{
SafeDelete(itr->second);
//CSceneManager::_ReleaseObj(POOL_RESOURCEMGROBJ,itr->second);
itr->second = NULL;
}
itr++;
}
m_ResourceTable.clear();
m_iResourceObjsNum = 0;
}
}
virtual void ReleaseData(const char *strName)
{
bool bEraseObj = false;
unsigned long DataID = GetHashID(strName);
RESOURCEMGRTABLEITER itr = m_ResourceTable.find(DataID);
if(itr != m_ResourceTable.end())
{
if((*itr).second != NULL)
{
for(int iNum = 0; iNum < (*itr).second->m_iObjsNum; iNum++)
{
if(!strcmp((*itr).second->m_lstObjs[iNum]->m_strName,strName))
{
bool bRelease = false;
#ifndef SG_RESOURCE_RELEASEPROCESS
if((bRelease = ((*itr).second)->ReleaseObj(iNum)) && !(*itr).second->m_iObjsNum)
{
// Release 완료(map의 노드 역시 삭제).
SafeDelete(itr->second);
//CSceneManager::_ReleaseObj(POOL_RESOURCEMGROBJ,itr->second);
itr->second = NULL;
m_ResourceTable.erase(itr);
}
#else
if(((*itr).second)->ReleaseObj(iNum))
{
//CDelResourceInfo *pDel = new CDelResourceInfo(DataID,strName);
CDelResourceInfo *pDel = new CDelResourceInfo();//(CDelResourceInfo *)CSceneManager::_CreateObj(POOL_DELRESOURCEINFOOBJ);
pDel->SetValue(DataID,strName);
m_DelObjQueue.push(pDel);
m_DelObjNums++;
}
#endif
if(bRelease)
{
m_iResourceObjsNum--;
}
}
}
}
}
}
virtual void *GetData(const char *strName)
{
unsigned long DataID = GetHashID(strName);
RESOURCEMGRTABLEITER itr = m_ResourceTable.find(DataID);
if(itr == m_ResourceTable.end())
{
return LoadData(strName);
}
else // Table 안에 이미 texture 가 로드되어 있을때
{
if((*itr).second != NULL)
{
for(int iNum = 0; iNum < (*itr).second->m_iObjsNum; iNum++)
{
if(!strcmp((*itr).second->m_lstObjs[iNum]->m_strName,strName))
{
return (*itr).second->GetObj(iNum);
}
}
return LoadData(strName); // Table 의 obj는 있지만 내가 원하는 obj 없을시
}
else
{
CResourceMgrObj *pObj = new CResourceMgrObj();
// CResourceMgrObj *pObj = (CResourceMgrObj *)CSceneManager::_CreateObj(POOL_RESOURCEMGROBJ);
(*itr).second = pObj;
return LoadData(strName); // Table 의 obj는 있지만 내가 원하는 obj 없을시.
}
}
return NULL;
}
protected:
#ifdef SG_RESOURCE_RELEASEPROCESS
void DelObjClear(int iNum)
{
for(int i = 0; i < iNum; i++ )
{
if(!m_DelObjQueue.empty())
{
CDelResourceInfo *pDelObj = m_DelObjQueue.front();
m_DelObjQueue.pop();
m_DelObjNums--;
if(pDelObj)
{
if(!ResourceLoaded(pDelObj->m_iID,pDelObj->m_strName))
{
m_DelObjQueue.push(pDelObj);
}
else
{
RealRelease(pDelObj->m_iID,pDelObj->m_strName);
//SafeDelete(pDelObj);
SafeDelete(pDelObj);
// CSceneManager::_ReleaseObj(POOL_DELRESOURCEINFOOBJ,pDelObj);
}
}
}
else
{
break;
}
}
}
bool ResourceLoaded(unsigned long ID,char *strName)
{
RESOURCEMGRTABLEITER itr = m_ResourceTable.find(ID);
if(itr != m_ResourceTable.end())
{
if((*itr).second != NULL)
{
for(int iNum = 0; iNum < (*itr).second->m_iObjsNum; iNum++)
{
if(!strcmp((*itr).second->m_lstObjs[iNum]->m_strName,strName))
{
if(((*itr).second)->IsLoaded(iNum))
return true;
else
return false;
}
}
}
}
return true;
}
void RealRelease(unsigned long ID,char *strName)
{
bool bEraseObj = false;
RESOURCEMGRTABLEITER itr = m_ResourceTable.find(ID);
if(itr != m_ResourceTable.end())
{
if((*itr).second != NULL)
{
for(int iNum = 0; iNum < (*itr).second->m_iObjsNum; iNum++)
{
if(!strcmp((*itr).second->m_lstObjs[iNum]->m_strName,strName))
{
bool bRelease = false;
if((bRelease = ((*itr).second)->RealReleaseObj(iNum)) && !(*itr).second->m_iObjsNum)
{
// Release 완료(map의 노드 역시 삭제).
SafeDelete(itr->second);
//CSceneManager::_ReleaseObj(POOL_RESOURCEMGROBJ,itr->second);
itr->second = NULL;
m_ResourceTable.erase(itr);
if(bRelease)
{
m_iResourceObjsNum--;
}
break;
}
if(bRelease)
{
m_iResourceObjsNum--;
}
}
}
}
}
}
#endif
virtual void *LoadData(const char *strName)
{
//T *pNode = new T;
T *pNode = (T *)CSceneManager::_CreateObj(m_iResourceType);
strcpy(pNode->m_strName,strName);
if( m_nLockedImmediateLoadCount > 0)
{
CSceneManager::_LoadResourceObj(pNode, true);
}
else
{
CSceneManager::_LoadResourceObj(pNode, false);
}
/*Scene::CMainSceneMgr::_GetResourceLoader()->AddObj(pNode);
*/
unsigned long DataID = GetHashID(strName);
RESOURCEMGRTABLEITER itr = m_ResourceTable.find(DataID);
m_iResourceObjsNum++;
#ifdef SG_RESOURCE_RELEASEPROCESS
if(m_iMaxCount < m_iResourceObjsNum)
{
SetDelCount(m_iResourceObjsNum - m_iMaxCount);
//DelObjClear(m_iResourceObjsNum - m_iMaxCount);
}
#endif
if(itr == m_ResourceTable.end())
{
//CResourceMgrObj*pObj = new CResourceMgrObj(m_iResourceType,pNode);
CResourceMgrObj *pObj = new CResourceMgrObj();//(CResourceMgrObj *)CSceneManager::_CreateObj(POOL_RESOURCEMGROBJ);
pObj->AddObj(m_iResourceType,pNode);
m_ResourceTable.insert(RESOURCEMGRTABLEOBJ(DataID,pObj));
}
else
{// map 안에 똑같은 Hash Index 를 가지는 요소 존재
((*itr).second)->AddObj(m_iResourceType,pNode);
}
return pNode;
}
void SetDelCount(int i)
{
m_iDelCount = i;
}
virtual void Update()
{
int iNum;
if(m_iDelCount > 0)
{
iNum = (RESOURCE_MAXDELCOUNT < m_iDelCount) ? RESOURCE_MAXDELCOUNT : m_iDelCount;
m_iDelCount -= iNum;
DelObjClear(iNum);
}
}
void LockImmediateLoad()
{
++m_nLockedImmediateLoadCount;
}
void UnlockImmediateLoad()
{
if( m_nLockedImmediateLoadCount > 0 )
{
--m_nLockedImmediateLoadCount;
}
}
RESOURCEMGRTABLE m_ResourceTable;
int m_iResourceObjsNum;
std::queue<CDelResourceInfo *> m_DelObjQueue;
int m_DelObjNums;
int m_iMaxCount;
int m_iDelCount;
// 2005.01.10 yundi 즉시 로드 상태를 위한 변수 추가
int m_nLockedImmediateLoadCount;
};
}