Add parallel race/motion loading and thread-safe Pack/Pool managers

This commit is contained in:
savis
2026-01-04 17:25:51 +01:00
parent 2550008f6d
commit d5624a8cdd
7 changed files with 102 additions and 24 deletions

View File

@@ -18,13 +18,19 @@ bool CPropertyManager::Initialize(const char * c_pszPackFileName)
if (c_pszPackFileName)
{
m_pack = std::make_shared<CPack>();
if (!m_pack->Open(c_pszPackFileName, m_fileDict)) {
if (!m_pack->Load(c_pszPackFileName)) {
LogBoxf("Cannot open property pack file (filename %s)", c_pszPackFileName);
return false;
}
m_isFileMode = false;
const auto& index = m_pack->GetIndex();
for (const auto& entry : index)
{
m_fileDict.emplace(entry.file_name, std::make_pair(m_pack, entry));
}
for (auto it = m_fileDict.begin(); it != m_fileDict.end(); ++it) {
std::string stFileName = it->second.second.file_name;
if (!stricmp("property/reserve", stFileName.c_str())) {

View File

@@ -137,6 +137,7 @@ class CRaceData
void Destroy();
// Codes For Client
DWORD GetRaceIndex() const { return m_dwRaceIndex; }
const char* GetBaseModelFileName() const;
const char* GetAttributeFileName() const;
const char* GetMotionListFileName() const;

View File

@@ -2,6 +2,10 @@
#include "RaceManager.h"
#include "RaceMotionData.h"
#include "PackLib/PackManager.h"
#include <future>
#include <vector>
#include <set>
#include <algorithm>
bool CRaceManager::s_bPreloaded = false;
@@ -456,34 +460,54 @@ void CRaceManager::PreloadPlayerRaceMotions()
if (s_bPreloaded)
return;
// Preload all player races (0-7)
CRaceManager& rkRaceMgr = CRaceManager::Instance();
// Phase 1: Parallel Load Race Data (MSM)
std::vector<std::future<CRaceData*>> raceLoadFutures;
for (DWORD dwRace = 0; dwRace <= 7; ++dwRace)
{
TRaceDataIterator it = rkRaceMgr.m_RaceDataMap.find(dwRace);
if (it == rkRaceMgr.m_RaceDataMap.end()) {
raceLoadFutures.push_back(std::async(std::launch::async, [&rkRaceMgr, dwRace]() {
return rkRaceMgr.__LoadRaceData(dwRace);
}));
}
}
for (auto& f : raceLoadFutures) {
CRaceData* pRaceData = f.get();
if (pRaceData) {
rkRaceMgr.m_RaceDataMap.insert(TRaceDataMap::value_type(pRaceData->GetRaceIndex(), pRaceData));
}
}
// Phase 2: Parallel Load Motions
std::set<CGraphicThing*> uniqueMotions;
for (DWORD dwRace = 0; dwRace <= 7; ++dwRace)
{
CRaceData* pRaceData = NULL;
if (!Instance().GetRaceDataPointer(dwRace, &pRaceData))
TRaceDataIterator it = rkRaceMgr.m_RaceDataMap.find(dwRace);
if (it != rkRaceMgr.m_RaceDataMap.end())
pRaceData = it->second;
if (!pRaceData)
continue;
CRaceData::TMotionModeDataIterator itor;
if (pRaceData->CreateMotionModeIterator(itor))
{
do
{
CRaceData::TMotionModeData* pMotionModeData = itor->second;
CRaceData::TMotionVectorMap::iterator itorMotion = pMotionModeData->MotionVectorMap.begin();
for (; itorMotion != pMotionModeData->MotionVectorMap.end(); ++itorMotion)
for (auto& itorMotion : pMotionModeData->MotionVectorMap)
{
const CRaceData::TMotionVector& c_rMotionVector = itorMotion->second;
CRaceData::TMotionVector::const_iterator it;
for (it = c_rMotionVector.begin(); it != c_rMotionVector.end(); ++it)
const CRaceData::TMotionVector& c_rMotionVector = itorMotion.second;
for (const auto& motion : c_rMotionVector)
{
CGraphicThing* pMotion = it->pMotion;
if (pMotion)
{
pMotion->AddReference();
}
if (motion.pMotion)
uniqueMotions.insert(motion.pMotion);
}
}
}
@@ -491,5 +515,31 @@ void CRaceManager::PreloadPlayerRaceMotions()
}
}
std::vector<CGraphicThing*> motionVec(uniqueMotions.begin(), uniqueMotions.end());
size_t total = motionVec.size();
if (total > 0) {
size_t threadCount = std::thread::hardware_concurrency();
if (threadCount == 0) threadCount = 4;
size_t chunkSize = (total + threadCount - 1) / threadCount;
std::vector<std::future<void>> motionFutures;
for (size_t i = 0; i < threadCount; ++i) {
size_t start = i * chunkSize;
size_t end = std::min(start + chunkSize, total);
if (start < end) {
motionFutures.push_back(std::async(std::launch::async, [start, end, &motionVec]() {
for (size_t k = start; k < end; ++k) {
motionVec[k]->AddReference();
}
}));
}
}
for (auto& f : motionFutures) f.get();
}
s_bPreloaded = true;
}