Files
Client/Engine/Caldron/Src/Base/ResourceLoader.cpp
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

425 lines
9.0 KiB
C++

#pragma warning( disable : 4786 )
#include "../../include/Caldron.h"
#include "./LoadedObj.h"
#include "ResourceLoader.h"
#include "GMMemory.h"
namespace Caldron {namespace Base {
/* *********************************************************************
* CResourceLoaderObj
* 파일 : ResourceLoader.cpp
* 기능 : Caldron Engine내 CResourceLoader 에서 Load Queue에 들어갈 resource 단위
* 작성일 : 2004.01.06
* history :
wizardbug ( 2004.01.06)
********************************************************************** */
/*
CResourceLoaderObj::CResourceLoaderObj()
{
m_pObj = NULL;
m_State = RLOBJSTATE_READY;
}
CResourceLoaderObj::CResourceLoaderObj(const char *strFileName,CLoadedObj *pObj)
{
strcpy(m_strFileName,strFileName);
m_pObj = pObj;
m_pObj->m_bLoaded = false;
m_State = RLOBJSTATE_READY;
}
CResourceLoaderObj::~CResourceLoaderObj()
{
}
*/
/* *********************************************************************
* CResourceLoader
* 파일 : ResourceLoader.cpp
* 기능 : Caldron Engine내 ResourceLoader,
thread를 분리하여 메린 루틴 과 로딩루틴을 분리 하였다.
* 작성일 : 2004.01.06
* history :
wizardbug ( 2004.01.06)
********************************************************************** */
CThreadQueue<CLoadedObj *> CResourceLoader::m_ReadyQueue(g_iMaxLoaderQueue);
DWORD WINAPI LoaderThreadProc(LPVOID lpParam)
{
CResourceLoader *pLoader = (CResourceLoader *)(lpParam);
pLoader->LoaderFunc();
return 0;
}
DWORD WINAPI ProcessThreadProc(LPVOID lpParam)
{
CResourceLoader *pLoader = (CResourceLoader *)(lpParam);
pLoader->ProcessFunc();
return 0;
}
void CResourceLoader::StartLoader()
{
if(!m_LoaderHandle)
{
if((m_LoaderHandle = CreateThread(NULL,0,LoaderThreadProc,(LPVOID)this,0,&m_LoaderThreadID)) == NULL) {
//CLogMgr::_LogError("CResourceLoader::Loading() : Create Loader Thread Failed");
}
}
if(!m_ProcessHandle)
{
if((m_ProcessHandle = CreateThread(NULL,0,ProcessThreadProc,(LPVOID)this,0,&m_ProcessThreadID)) == NULL) {
//CLogMgr::_LogError("CResourceLoader::Loading() : Create Process Thread Failed");
}
}
}
void CResourceLoader::LoaderFunc()
{
CLoadedObj *pObj = NULL;
while( m_ReadyQueue.RemoveFront(pObj))
{
if(pObj)
{
if(pObj->m_pByteDataObj)
delete pObj->m_pByteDataObj;
pObj->m_pByteDataObj = new CCaldronByteDataObj;
if(!(pObj->m_pByteDataObj->LoadByte(pObj->m_strName)))
{
pObj->m_bLoaded = false;
}
else
{
m_Queue.PushBack(pObj);
}
}
}
}
void CResourceLoader::ProcessFunc()
{
CLoadedObj *pObj = NULL;
while( m_Queue.RemoveFront(pObj))
{
if(pObj)
{
if(!pObj->Load(pObj->m_pByteDataObj))
{ // 로딩 실패시에 다시 queue에 넣어서 ReLoading 시도 한다.
if(pObj->m_iReloadingCount < Caldron::MAX_RELOADING) {
pObj->m_bLoaded = false;
m_Queue.PushBack(pObj);
//CLogMgr::_LogError("CResourceLoader::ProcessFunc: Load fail, Reloading.");
pObj->m_iReloadingCount++;
}
else
{
pObj->m_bLoaded = false;
}
}
else
{
m_ResultQueue.PushBack(pObj);
}
}
else
{
//CLogMgr::_LogError("CResourceLoader::ProcessFunc: Obj Ptr is NULL");
}
}
}
void CResourceLoader::ProcessAllData()
{
while(1)
{
Sleep(2000);
if(!m_ReadyQueue.GetQueueSize() &&
!m_Queue.GetQueueSize())
{
break;
}
}
if(m_ResultQueue.GetQueueSize())
{
int iProcess = m_ResultQueue.GetQueueSize();
CLoadedObj *pObj = NULL;
while(iProcess)
{
if(m_ResultQueue.RemoveFront(pObj))
{
pObj->PostLoad();
SafeDelete(pObj->m_pByteDataObj);
pObj->m_pByteDataObj = NULL;
}
else
{
break;
}
iProcess--;
}
}
}
void CResourceLoader::Process()
{
if(m_ResultQueue.GetQueueSize())
{
int iProcess = (m_ResultQueue.GetQueueSize() > g_iMaxProcessNums) ? g_iMaxProcessNums : m_ResultQueue.GetQueueSize();
CLoadedObj *pObj = NULL;
while(iProcess)
{
if(m_ResultQueue.RemoveFront(pObj))
{
pObj->PostLoad();
SafeDelete(pObj->m_pByteDataObj);
pObj->m_pByteDataObj = NULL;
}
else
{
break;
}
iProcess--;
}
}
}
void CResourceLoader::Clear()
{
ProcessAllData();
m_ReadyQueue.ClearQueue();
m_Queue.ClearQueue();
m_ResultQueue.ClearQueue();
}
/*
class CResourceLoader
{
public:
CResourceLoader();
virtual ~CResourceLoader();
void StartLoader();
int AddObj(CResourceLoaderObj *);
protected:
void LoaderFunc();
void ProcessFunc();
DWORD m_dwWait;
CThreadQueue<CResourceLoaderObj *>m_lstObj;
CThreadQueue<CResourceLoaderObj *>m_Queue;
CCriticalSectionQueue<CLoadedObj *>m_ResultQueue;
unsigned long m_LoaderThreadID;
unsigned long m_ProcessThreadID;
HANDLE m_LoaderHandle;
HANDLE m_ProcessHandle;
};
CResourceLoader::CResourceLoader() : m_Queue(g_iMaxLoaderQueue)
{
m_bLoading = false;
m_dwWait = 0;
m_lstObj.clear();
m_lstReady.clear();
InitializeCriticalSection(&m_ObjCriticalSection);
m_LoaderThreadID = m_ProcessThreadID = 0;
m_EndEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
m_LoaderHandle = 0;
m_ProcessHandle = 0;
}
CResourceLoader::~CResourceLoader()
{
DeleteCriticalSection(&m_ObjCriticalSection);
CloseHandle(m_EndEvent);
CloseHandle(m_LoaderHandle);
CloseHandle(m_ProcessHandle);
}
void CResourceLoader::Loading()
{
m_bLoading = true;
// Event 초기화
ResetEvent(m_EndEvent);
if((m_LoaderHandle = CreateThread(NULL,0,LoaderThreadProc,(LPVOID)this,0,&m_LoaderThreadID)) == NULL) {
CLogMgr::_LogError("CResourceLoader::Loading() : Create Loader Thread Failed");
}
if((m_ProcessHandle = CreateThread(NULL,0,ProcessThreadProc,(LPVOID)this,0,&m_ProcessThreadID)) == NULL) {
CLogMgr::_LogError("CResourceLoader::Loading() : Create Process Thread Failed");
}
}
DWORD CResourceLoader::WaitFinished()
{
return WaitForMultipleObjects(1, &m_EndEvent, FALSE, m_dwWait);
}
int CResourceLoader::FinishPercent() {
return 0;
}
void CResourceLoader::LoaderFunc()
{
for(int iIndex = 0; iIndex < GetObjNum(); iIndex++)
{
CResourceLoaderObj *pObj = &m_lstObj[iIndex];
if(!(pObj->m_ByteData.LoadByte(pObj->m_strFileName)))
{
pObj->m_State = RLOBJSTATE_FAILED;
if(pObj->m_pObj)
pObj->m_pObj->m_bLoaded = false;
}
else
{
pObj->m_State = RLOBJSTATE_LOADING;
m_Queue.PushBack(pObj);
}
}
m_Queue.Terminate();
}
void CResourceLoader::ProcessFunc()
{
CResourceLoaderObj *pObj = NULL;
while( m_Queue.RemoveFront(pObj))
{
if((pObj) && (pObj->m_pObj))
{
if(!pObj->m_pObj->Load(&(pObj->m_ByteData)))
{ // 로딩 실패시에 다시 queue에 넣어서 ReLoading 시도 한다.
if(pObj->m_pObj->m_iReloadingCount < Caldron::MAX_RELOADING) {
pObj->m_State = RLOBJSTATE_LOADING;
pObj->m_pObj->m_bLoaded = false;
m_Queue.PushBack(pObj);
CLogMgr::_LogError("CResourceLoader::ProcessFunc: Load fail, Reloading.");
pObj->m_pObj->m_iReloadingCount++;
}
else
{
pObj->m_State = RLOBJSTATE_FAILED;
pObj->m_pObj->m_bLoaded = true;
}
}
else
{
pObj->m_State = RLOBJSTATE_LOADED;
pObj->m_pObj->m_bLoaded = true;
}
}
else
{
CLogMgr::_LogError("CResourceLoader::ProcessFunc: Obj Ptr is NULL");
}
}
SetEvent(m_EndEvent);
}
int CResourceLoader::AddObj(CResourceLoaderObj &Obj)
{
if(!m_bLoading) {
EnterCriticalSection(&m_ObjCriticalSection);
m_lstObj.push_back(Obj);
LeaveCriticalSection(&m_ObjCriticalSection);
return (int)(m_lstObj.size());
}
else {
m_lstReady.push_back(Obj);
return -2;
}
}
CResourceLoaderObj CResourceLoader::GetObj(int iIndex)
{
EnterCriticalSection(&m_ObjCriticalSection);
CResourceLoaderObj Obj = m_lstObj[iIndex];
LeaveCriticalSection(&m_ObjCriticalSection);
return Obj;
}
void CResourceLoader::SetObj(int iIndex,CResourceLoaderObj &Obj)
{
EnterCriticalSection(&m_ObjCriticalSection);
m_lstObj[iIndex] = Obj;
LeaveCriticalSection(&m_ObjCriticalSection);
}
int CResourceLoader::GetObjNum()
{
EnterCriticalSection(&m_ObjCriticalSection);
int iNum = (int)m_lstObj.size();
LeaveCriticalSection(&m_ObjCriticalSection);
return iNum;
}
void CResourceLoader::ClearAllObj()
{
EnterCriticalSection(&m_ObjCriticalSection);
m_lstObj.clear();
LeaveCriticalSection(&m_ObjCriticalSection);
}
CResourceLoaderObjState CResourceLoader::GetObjState(int iIndex)
{
return m_lstObj[iIndex].m_State;
}
bool CResourceLoader::Finished()
{
if(WaitFinished() != (WAIT_OBJECT_0))
return false;
CloseHandle(m_LoaderHandle);
CloseHandle(m_ProcessHandle);
m_LoaderHandle = m_ProcessHandle = 0;
return true;
}
void CResourceLoader::Process() {
if((m_bLoading == true) && WaitFinished() == (WAIT_OBJECT_0))
{
m_bLoading = false;
ClearAllObj();
CloseHandle(m_LoaderHandle);
CloseHandle(m_ProcessHandle);
m_LoaderHandle = m_ProcessHandle = 0;
}
else
{
if((m_lstObj.size() > 0 )&& (m_bLoading == false))
Loading();
return;
}
if(m_lstReady.size() > 0 && !m_bLoading)
{
// Ready 큐에 들어 있는 것들을 로딩 리스트로 넘긴다
m_lstObj.reserve(m_lstReady.size());
std::copy(m_lstReady.begin(),m_lstReady.end(),std::back_inserter(m_lstObj));
m_lstReady.clear();
Loading();
}
}*/
}}