forked from metin2/client
Solution refactoring and restructuring, removed Boost dependency, removed unused tools
This commit is contained in:
525
src/EterLib/ResourceManager.cpp
Normal file
525
src/EterLib/ResourceManager.cpp
Normal file
@ -0,0 +1,525 @@
|
||||
#include "StdAfx.h"
|
||||
#include <io.h>
|
||||
#include "../eterBase/CRC32.h"
|
||||
#include "../eterBase/Timer.h"
|
||||
#include "../eterBase/Stl.h"
|
||||
#include "../eterPack/EterPackManager.h"
|
||||
|
||||
#include "ResourceManager.h"
|
||||
#include "GrpImage.h"
|
||||
|
||||
int g_iLoadingDelayTime = 20;
|
||||
|
||||
const long c_Deleting_Wait_Time = 30000; // <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>ð<EFBFBD> (30<33><30>)
|
||||
const long c_DeletingCountPerFrame = 30; // <20><><EFBFBD><EFBFBD><EFBFBD>Ӵ<EFBFBD> üũ <20><><EFBFBD>ҽ<EFBFBD> <20><><EFBFBD><EFBFBD>
|
||||
const long c_Reference_Decrease_Wait_Time = 30000; // <20><><EFBFBD>ε<EFBFBD> <20><><EFBFBD>ҽ<EFBFBD><D2BD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>ð<EFBFBD> (30<33><30>)
|
||||
|
||||
CFileLoaderThread CResourceManager::ms_loadingThread;
|
||||
|
||||
void CResourceManager::LoadStaticCache(const char* c_szFileName)
|
||||
{
|
||||
CResource* pkRes=GetResourcePointer(c_szFileName);
|
||||
if (!pkRes)
|
||||
{
|
||||
Lognf(1, "CResourceManager::LoadStaticCache %s - FAILED", c_szFileName);
|
||||
return;
|
||||
}
|
||||
|
||||
DWORD dwCacheKey=GetCRC32(c_szFileName, strlen(c_szFileName));
|
||||
TResourcePointerMap::iterator f=m_pCacheMap.find(dwCacheKey);
|
||||
if (m_pCacheMap.end()!=f)
|
||||
return;
|
||||
|
||||
pkRes->AddReference();
|
||||
m_pCacheMap.insert(TResourcePointerMap::value_type(dwCacheKey, pkRes));
|
||||
|
||||
}
|
||||
|
||||
void CResourceManager::ProcessBackgroundLoading()
|
||||
{
|
||||
TResourceRequestMap::iterator itor = m_RequestMap.begin();
|
||||
|
||||
while (itor != m_RequestMap.end())
|
||||
{
|
||||
DWORD dwFileCRC = itor->first;
|
||||
std::string & stFileName = itor->second;
|
||||
|
||||
if (isResourcePointerData(dwFileCRC) ||
|
||||
(m_WaitingMap.end() != m_WaitingMap.find(dwFileCRC)))
|
||||
{
|
||||
//printf("SKP %s\n", stFileName.c_str());
|
||||
itor = m_RequestMap.erase(itor);
|
||||
continue;
|
||||
}
|
||||
|
||||
//printf("REQ %s\n", stFileName.c_str());
|
||||
ms_loadingThread.Request(stFileName);
|
||||
m_WaitingMap.insert(TResourceRequestMap::value_type(dwFileCRC, stFileName));
|
||||
itor = m_RequestMap.erase(itor);
|
||||
//break; // NOTE: <20><><EFBFBD>⼭ break <20>ϸ<EFBFBD> õõ<C3B5><C3B5> <20>ε<EFBFBD> <20>ȴ<EFBFBD>.
|
||||
}
|
||||
|
||||
DWORD dwCurrentTime = ELTimer_GetMSec();
|
||||
|
||||
CFileLoaderThread::TData * pData;
|
||||
while (ms_loadingThread.Fetch(&pData))
|
||||
{
|
||||
//printf("LOD %s\n", pData->stFileName.c_str());
|
||||
CResource * pResource = GetResourcePointer(pData->stFileName.c_str());
|
||||
|
||||
if (pResource)
|
||||
{
|
||||
if (pResource->IsEmpty())
|
||||
{
|
||||
pResource->OnLoad(pData->dwSize, pData->pvBuf);
|
||||
pResource->AddReferenceOnly();
|
||||
|
||||
// <20><><EFBFBD>⼭ <20>ö<EFBFBD><C3B6><EFBFBD> <20><><EFBFBD>۷<EFBFBD><DBB7><EFBFBD> ī<><C4AB>Ʈ<EFBFBD><C6AE> <20><><EFBFBD><EFBFBD> <20>ð<EFBFBD><C3B0><EFBFBD> <20><><EFBFBD><EFBFBD> <20>ڿ<EFBFBD> Ǯ<><C7AE><EFBFBD>ֱ<EFBFBD> <20><><EFBFBD>Ͽ<EFBFBD>
|
||||
m_pResRefDecreaseWaitingMap.insert(TResourceRefDecreaseWaitingMap::value_type(dwCurrentTime, pResource));
|
||||
}
|
||||
}
|
||||
|
||||
m_WaitingMap.erase(GetCRC32(pData->stFileName.c_str(), pData->stFileName.size()));
|
||||
|
||||
delete [] ((char *) pData->pvBuf);
|
||||
delete pData;
|
||||
}
|
||||
|
||||
// DO : <20><><EFBFBD><EFBFBD> <20>ð<EFBFBD><C3B0><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20≯<EFBFBD> <20>ε<EFBFBD><CEB5><EFBFBD> <20>ξ<EFBFBD><CEBE><EFBFBD> <20><><EFBFBD>ҽ<EFBFBD><D2BD><EFBFBD> <20><><EFBFBD>۷<EFBFBD><DBB7><EFBFBD> ī<><C4AB>Ʈ<EFBFBD><C6AE> <20><><EFBFBD><EFBFBD> <20><>Ų<EFBFBD><C5B2> - [levites]
|
||||
long lCurrentTime = ELTimer_GetMSec();
|
||||
|
||||
TResourceRefDecreaseWaitingMap::iterator itorRef = m_pResRefDecreaseWaitingMap.begin();
|
||||
|
||||
while (itorRef != m_pResRefDecreaseWaitingMap.end())
|
||||
{
|
||||
const long & rCreatingTime = itorRef->first;
|
||||
|
||||
if (lCurrentTime - rCreatingTime > c_Reference_Decrease_Wait_Time)
|
||||
{
|
||||
CResource * pResource = itorRef->second;
|
||||
|
||||
// Decrease Reference Count
|
||||
pResource->Release();
|
||||
itorRef = m_pResRefDecreaseWaitingMap.erase(itorRef);
|
||||
//Tracef("Decrease Pre Loading Resource\n", rCreatingTime);
|
||||
}
|
||||
else
|
||||
++itorRef;
|
||||
}
|
||||
}
|
||||
|
||||
void CResourceManager::PushBackgroundLoadingSet(std::set<std::string> & LoadingSet)
|
||||
{
|
||||
std::set<std::string>::iterator itor = LoadingSet.begin();
|
||||
|
||||
while (itor != LoadingSet.end())
|
||||
{
|
||||
DWORD dwFileCRC = __GetFileCRC(itor->c_str());
|
||||
|
||||
if (NULL != isResourcePointerData(dwFileCRC))
|
||||
{
|
||||
++itor;
|
||||
continue;
|
||||
}
|
||||
|
||||
m_RequestMap.insert(TResourceRequestMap::value_type(dwFileCRC, itor->c_str()));
|
||||
++itor;
|
||||
}
|
||||
}
|
||||
|
||||
void CResourceManager::__DestroyCacheMap()
|
||||
{
|
||||
TResourcePointerMap::iterator i;
|
||||
for (i = m_pCacheMap.begin(); i != m_pCacheMap.end(); ++i)
|
||||
{
|
||||
CResource* pResource = i->second;
|
||||
pResource->Release();
|
||||
}
|
||||
|
||||
m_pCacheMap.clear();
|
||||
}
|
||||
|
||||
void CResourceManager::__DestroyDeletingResourceMap()
|
||||
{
|
||||
Tracenf("CResourceManager::__DestroyDeletingResourceMap %d", m_ResourceDeletingMap.size());
|
||||
for (TResourceDeletingMap::iterator i = m_ResourceDeletingMap.begin(); i != m_ResourceDeletingMap.end(); ++i)
|
||||
(i->first)->Clear();
|
||||
|
||||
m_ResourceDeletingMap.clear();
|
||||
}
|
||||
|
||||
void CResourceManager::__DestroyResourceMap()
|
||||
{
|
||||
Tracenf("CResourceManager::__DestroyResourceMap %d", m_pResMap.size());
|
||||
|
||||
TResourcePointerMap::iterator i;
|
||||
for (i = m_pResMap.begin(); i != m_pResMap.end(); ++i)
|
||||
{
|
||||
CResource* pResource = i->second;
|
||||
pResource->Clear();
|
||||
}
|
||||
|
||||
stl_wipe_second(m_pResMap);
|
||||
}
|
||||
|
||||
void CResourceManager::DestroyDeletingList()
|
||||
{
|
||||
CResource::SetDeleteImmediately(true);
|
||||
|
||||
__DestroyCacheMap();
|
||||
__DestroyDeletingResourceMap();
|
||||
}
|
||||
|
||||
void CResourceManager::Destroy()
|
||||
{
|
||||
assert(m_ResourceDeletingMap.empty() && "CResourceManager::Destroy - YOU MUST CALL DestroyDeletingList");
|
||||
__DestroyResourceMap();
|
||||
}
|
||||
|
||||
void CResourceManager::RegisterResourceNewFunctionPointer(const char* c_szFileExt, CResource* (*pNewFunc)(const char* c_szFileName))
|
||||
{
|
||||
m_pResNewFuncMap[c_szFileExt] = pNewFunc;
|
||||
}
|
||||
|
||||
void CResourceManager::RegisterResourceNewFunctionByTypePointer(int iType, CResource* (*pNewFunc) (const char* c_szFileName))
|
||||
{
|
||||
assert(iType >= 0);
|
||||
m_pResNewFuncByTypeMap[iType] = pNewFunc;
|
||||
}
|
||||
|
||||
CResource * CResourceManager::InsertResourcePointer(DWORD dwFileCRC, CResource* pResource)
|
||||
{
|
||||
TResourcePointerMap::iterator itor = m_pResMap.find(dwFileCRC);
|
||||
|
||||
if (m_pResMap.end() != itor)
|
||||
{
|
||||
TraceError("CResource::InsertResourcePointer: %s is already registered\n", pResource->GetFileName());
|
||||
assert(!"CResource::InsertResourcePointer: Resource already resistered");
|
||||
delete pResource;
|
||||
return itor->second;
|
||||
}
|
||||
|
||||
m_pResMap.insert(TResourcePointerMap::value_type(dwFileCRC, pResource));
|
||||
return pResource;
|
||||
}
|
||||
|
||||
|
||||
int __ConvertPathName(const char * c_szPathName, char * pszRetPathName, int retLen)
|
||||
{
|
||||
const char * pc;
|
||||
int len = 0;
|
||||
|
||||
for (pc = c_szPathName; *pc && len < retLen; ++pc, ++len)
|
||||
{
|
||||
if (*pc == '/')
|
||||
*(pszRetPathName++) = '\\';
|
||||
else
|
||||
*(pszRetPathName++) = (char) korean_tolower(*pc);
|
||||
}
|
||||
|
||||
*pszRetPathName = '\0';
|
||||
return len;
|
||||
}
|
||||
|
||||
CResource * CResourceManager::GetTypeResourcePointer(const char * c_szFileName, int iType)
|
||||
{
|
||||
if (!c_szFileName || !*c_szFileName)
|
||||
{
|
||||
assert(c_szFileName != NULL && *c_szFileName != '\0');
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const char * c_pszFile;
|
||||
DWORD dwFileCRC = __GetFileCRC(c_szFileName, &c_pszFile);
|
||||
CResource * pResource = FindResourcePointer(dwFileCRC);
|
||||
|
||||
if (pResource) // <20>̹<EFBFBD> <20><><EFBFBD>ҽ<EFBFBD><D2BD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>Ѵ<EFBFBD>.
|
||||
return pResource;
|
||||
|
||||
CResource * (*newFunc) (const char *) = NULL;
|
||||
|
||||
if (iType != -1)
|
||||
{
|
||||
TResourceNewFunctionByTypePointerMap::iterator f = m_pResNewFuncByTypeMap.find(iType);
|
||||
|
||||
if (m_pResNewFuncByTypeMap.end() != f)
|
||||
newFunc = f->second;
|
||||
}
|
||||
else
|
||||
{
|
||||
const char * pcFileExt = strrchr(c_pszFile, '.');
|
||||
|
||||
if (pcFileExt)
|
||||
{
|
||||
static char s_szFileExt[8 + 1];
|
||||
strncpy(s_szFileExt, pcFileExt + 1, 8);
|
||||
|
||||
TResourceNewFunctionPointerMap::iterator f = m_pResNewFuncMap.find(s_szFileExt);
|
||||
|
||||
if (m_pResNewFuncMap.end() != f)
|
||||
newFunc = f->second;
|
||||
}
|
||||
}
|
||||
|
||||
if (!newFunc)
|
||||
{
|
||||
TraceError("ResourceManager::GetResourcePointer: NOT SUPPORT FILE %s", c_pszFile);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pResource = InsertResourcePointer(dwFileCRC, newFunc(c_pszFile));
|
||||
return pResource;
|
||||
}
|
||||
|
||||
CResource * CResourceManager::GetResourcePointer(const char * c_szFileName)
|
||||
{
|
||||
if (!c_szFileName || !*c_szFileName)
|
||||
{
|
||||
TraceError("CResourceManager::GetResourcePointer: filename error!");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const char * c_pszFile;
|
||||
DWORD dwFileCRC = __GetFileCRC(c_szFileName, &c_pszFile);
|
||||
CResource * pResource = FindResourcePointer(dwFileCRC);
|
||||
|
||||
if (pResource) // <20>̹<EFBFBD> <20><><EFBFBD>ҽ<EFBFBD><D2BD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>Ѵ<EFBFBD>.
|
||||
return pResource;
|
||||
|
||||
const char * pcFileExt = strrchr(c_pszFile, '.');
|
||||
|
||||
#ifdef _DEBUG
|
||||
if (!IsFileExist(c_szFileName) )
|
||||
{
|
||||
if( pcFileExt == NULL || (stricmp( pcFileExt, ".fnt" ) != 0) ) {
|
||||
TraceError("CResourceManager::GetResourcePointer: File not exist %s", c_szFileName);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
CResource * (*newFunc) (const char *) = NULL;
|
||||
|
||||
if (pcFileExt)
|
||||
{
|
||||
static char s_szFileExt[8 + 1];
|
||||
strncpy(s_szFileExt, pcFileExt + 1, 8);
|
||||
|
||||
TResourceNewFunctionPointerMap::iterator f = m_pResNewFuncMap.find(s_szFileExt);
|
||||
|
||||
if (m_pResNewFuncMap.end() != f)
|
||||
newFunc = f->second;
|
||||
}
|
||||
|
||||
if (!newFunc)
|
||||
{
|
||||
TraceError("ResourceManager::GetResourcePointer: NOT SUPPORT FILE %s", c_pszFile);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pResource = InsertResourcePointer(dwFileCRC, newFunc(c_pszFile));
|
||||
return pResource;
|
||||
}
|
||||
|
||||
CResource * CResourceManager::FindResourcePointer(DWORD dwFileCRC)
|
||||
{
|
||||
TResourcePointerMap::iterator itor = m_pResMap.find(dwFileCRC);
|
||||
|
||||
if (m_pResMap.end() == itor)
|
||||
return NULL;
|
||||
|
||||
return itor->second;
|
||||
}
|
||||
|
||||
bool CResourceManager::isResourcePointerData(DWORD dwFileCRC)
|
||||
{
|
||||
TResourcePointerMap::iterator itor = m_pResMap.find(dwFileCRC);
|
||||
|
||||
if (m_pResMap.end() == itor)
|
||||
return NULL;
|
||||
|
||||
return (itor->second)->IsData();
|
||||
}
|
||||
|
||||
DWORD CResourceManager::__GetFileCRC(const char * c_szFileName, const char ** c_ppszLowerFileName)
|
||||
{
|
||||
static char s_szFullPathFileName[MAX_PATH];
|
||||
const char * src = c_szFileName;
|
||||
char * dst = s_szFullPathFileName;
|
||||
int len = 0;
|
||||
|
||||
while (src[len])
|
||||
{
|
||||
if (src[len]=='/')
|
||||
dst[len] = '\\';
|
||||
else
|
||||
dst[len] = (char) korean_tolower(src[len]);
|
||||
|
||||
++len;
|
||||
}
|
||||
|
||||
dst[len] = '\0';
|
||||
|
||||
if (c_ppszLowerFileName)
|
||||
*c_ppszLowerFileName = &s_szFullPathFileName[0];
|
||||
|
||||
return (GetCRC32(s_szFullPathFileName, len));
|
||||
}
|
||||
|
||||
typedef struct SDumpData
|
||||
{
|
||||
const char * filename;
|
||||
float KB;
|
||||
DWORD cost;
|
||||
} TDumpData;
|
||||
|
||||
bool DumpKBCompare(const TDumpData& lhs, const TDumpData& rhs)
|
||||
{
|
||||
return (lhs.KB > rhs.KB) ? true : false;
|
||||
}
|
||||
|
||||
bool DumpCostCompare(const TDumpData& lhs, const TDumpData& rhs)
|
||||
{
|
||||
return (lhs.cost > rhs.cost) ? true : false;
|
||||
}
|
||||
|
||||
struct FDumpPrint
|
||||
{
|
||||
FILE * m_fp;
|
||||
static float m_totalKB;
|
||||
|
||||
void operator () (TDumpData & data)
|
||||
{
|
||||
m_totalKB += data.KB;
|
||||
fprintf(m_fp, "%6.1f %s\n", data.KB, data.filename);
|
||||
}
|
||||
};
|
||||
|
||||
float FDumpPrint::m_totalKB;
|
||||
|
||||
struct FDumpCostPrint
|
||||
{
|
||||
FILE * m_fp;
|
||||
|
||||
void operator() (TDumpData & data)
|
||||
{
|
||||
fprintf(m_fp, "%-4d %s\n", data.cost, data.filename);
|
||||
}
|
||||
};
|
||||
|
||||
void CResourceManager::DumpFileListToTextFile(const char* c_szFileName)
|
||||
{
|
||||
std::vector<TDumpData> dumpVector;
|
||||
|
||||
for (TResourcePointerMap::iterator i = m_pResMap.begin(); i != m_pResMap.end(); ++i)
|
||||
{
|
||||
CResource* pResource = i->second;
|
||||
TDumpData data;
|
||||
|
||||
if (pResource->IsEmpty())
|
||||
continue;
|
||||
|
||||
data.filename = pResource->GetFileName();
|
||||
|
||||
int filesize;
|
||||
|
||||
const char * ext = strrchr(data.filename, '.');
|
||||
|
||||
if (pResource->IsType(CGraphicImage::Type()) && strnicmp(ext, ".sub", 4))
|
||||
filesize = ((CGraphicImage*) pResource)->GetWidth() * ((CGraphicImage*) pResource)->GetHeight() * 4;
|
||||
else
|
||||
{
|
||||
FILE * fp2 = fopen(data.filename, "rb");
|
||||
|
||||
if (fp2)
|
||||
{
|
||||
fseek(fp2, 0L, SEEK_END);
|
||||
filesize = ftell(fp2);
|
||||
fclose(fp2);
|
||||
}
|
||||
else
|
||||
filesize = 0;
|
||||
}
|
||||
|
||||
data.KB = (float) filesize / (float) 1024;
|
||||
data.cost = pResource->GetLoadCostMilliSecond();
|
||||
|
||||
dumpVector.push_back(data);
|
||||
}
|
||||
|
||||
FILE * fp = fopen(c_szFileName, "w");
|
||||
|
||||
if (fp)
|
||||
{
|
||||
std::sort(dumpVector.begin(), dumpVector.end(), DumpKBCompare);
|
||||
|
||||
FDumpPrint DumpPrint;
|
||||
DumpPrint.m_fp = fp;
|
||||
DumpPrint.m_totalKB = 0;
|
||||
|
||||
std::for_each(dumpVector.begin(), dumpVector.end(), DumpPrint);
|
||||
fprintf(fp, "total: %.2fmb", DumpPrint.m_totalKB / 1024.0f);
|
||||
|
||||
FDumpCostPrint DumpCostPrint;
|
||||
DumpCostPrint.m_fp = fp;
|
||||
|
||||
std::sort(dumpVector.begin(), dumpVector.end(), DumpCostCompare);
|
||||
std::for_each(dumpVector.begin(), dumpVector.end(), DumpCostPrint);
|
||||
fprintf(fp, "total: %.2fmb", DumpPrint.m_totalKB / 1024.0f);
|
||||
|
||||
fclose(fp);
|
||||
}
|
||||
}
|
||||
|
||||
bool CResourceManager::IsFileExist(const char * c_szFileName)
|
||||
{
|
||||
return CEterPackManager::Instance().isExist(c_szFileName);
|
||||
}
|
||||
|
||||
void CResourceManager::Update()
|
||||
{
|
||||
DWORD CurrentTime = ELTimer_GetMSec();
|
||||
CResource * pResource;
|
||||
int Count = 0;
|
||||
|
||||
TResourceDeletingMap::iterator itor = m_ResourceDeletingMap.begin();
|
||||
|
||||
while (itor != m_ResourceDeletingMap.end())
|
||||
{
|
||||
pResource = itor->first;
|
||||
|
||||
if (CurrentTime >= itor->second)
|
||||
{
|
||||
if (pResource->canDestroy())
|
||||
{
|
||||
//Tracef("Resource Clear %s\n", pResource->GetFileName());
|
||||
pResource->Clear();
|
||||
}
|
||||
|
||||
itor = m_ResourceDeletingMap.erase(itor);
|
||||
|
||||
if (++Count >= c_DeletingCountPerFrame)
|
||||
break;
|
||||
}
|
||||
else
|
||||
++itor;
|
||||
}
|
||||
|
||||
ProcessBackgroundLoading();
|
||||
}
|
||||
|
||||
void CResourceManager::ReserveDeletingResource(CResource * pResource)
|
||||
{
|
||||
DWORD dwCurrentTime = ELTimer_GetMSec();
|
||||
m_ResourceDeletingMap.insert(TResourceDeletingMap::value_type(pResource, dwCurrentTime + c_Deleting_Wait_Time));
|
||||
}
|
||||
|
||||
CResourceManager::CResourceManager()
|
||||
{
|
||||
//ms_loadingThread.Create(0);
|
||||
}
|
||||
|
||||
CResourceManager::~CResourceManager()
|
||||
{
|
||||
Destroy();
|
||||
//ms_loadingThread.Shutdown();
|
||||
}
|
Reference in New Issue
Block a user