finish manager split

This commit is contained in:
yyc12345 2023-09-06 10:42:23 +08:00
parent 2ec66131cf
commit a1acdf10c6
12 changed files with 146 additions and 82 deletions

View File

@ -8,18 +8,14 @@
namespace LibCmo::CK2 {
#if defined(LIBCMO_OS_WIN32)
static wchar_t g_UniqueFolder[] = L"LibCmo";
#else
static char g_UniqueFolder[] = "LibCmo";
#endif
#pragma region Ctor Dtor
CKContext::CKContext() :
// setup manager
m_ManagerList(),
m_ObjectManager(nullptr), m_PathManager(nullptr),
// setup object cache
m_ObjectCache(), m_ObjectPointerCache(),
// setup file save/load options
m_CompressionLevel(5),
m_FileWriteMode(CK_FILE_WRITEMODE::CKFILE_UNCOMPRESSED),
@ -27,15 +23,8 @@ namespace LibCmo::CK2 {
m_GlobalSoundsSaveOptions(CK_SOUND_SAVEOPTIONS::CKSOUND_EXTERNAL),
m_GlobalImagesSaveFormat(nullptr), // todo: setup save format
// misc init
m_NameEncoding(), m_TempFolder(),
m_OutputCallback(nullptr)
{
// preset for temp folder
// todo: add current CKContext pointer as the part of temp path.
// thus multiple CKContext can work.
m_TempFolder = std::filesystem::temp_directory_path();
m_TempFolder /= g_UniqueFolder;
std::filesystem::create_directory(m_TempFolder);
m_NameEncoding(),
m_OutputCallback(nullptr) {
// setup managers
m_ObjectManager = new MgrImpls::CKObjectManager(this);
@ -97,37 +86,35 @@ namespace LibCmo::CK2 {
return m_ObjectManager->DestroyObjects(obj_ids, Count);
}
ObjImpls::CKObject* GeneralPrevFinder(XContainer::XObjectPointerArray& objptrs, ObjImpls::CKObject* previous) {
auto finder = std::find(objptrs.begin(), objptrs.end(), previous);
if (finder == objptrs.end()) return nullptr;
++finder;
if (finder == objptrs.end()) return nullptr;
return *finder;
}
ObjImpls::CKObject* CKContext::GetObjectByName(CKSTRING name, ObjImpls::CKObject* previous) {
if (name == nullptr) return nullptr;
auto result = m_ObjectManager->GetObjectByNameAndClass(name, CK_CLASSID::CKCID_OBJECT, true);
auto finder = std::find(result.begin(), result.end(), previous);
if (finder == result.end()) return nullptr;
++finder;
if (finder == result.end()) return nullptr;
return *finder;
if (previous == nullptr) {
m_ObjectPointerCache = m_ObjectManager->GetObjectByNameAndClass(name, CK_CLASSID::CKCID_OBJECT, true);
}
return GeneralPrevFinder(m_ObjectPointerCache, previous);
}
ObjImpls::CKObject* CKContext::GetObjectByNameAndClass(CKSTRING name, CK_CLASSID cid, ObjImpls::CKObject* previous) {
if (name == nullptr) return nullptr;
auto result = m_ObjectManager->GetObjectByNameAndClass(name, cid, false);
auto finder = std::find(result.begin(), result.end(), previous);
if (finder == result.end()) return nullptr;
++finder;
if (finder == result.end()) return nullptr;
return *finder;
if (previous == nullptr) {
m_ObjectPointerCache = m_ObjectManager->GetObjectByNameAndClass(name, cid, false);
}
return GeneralPrevFinder(m_ObjectPointerCache, previous);
}
ObjImpls::CKObject* CKContext::GetObjectByNameAndParentClass(CKSTRING name, CK_CLASSID pcid, ObjImpls::CKObject* previous) {
if (name == nullptr) return nullptr;
auto result = m_ObjectManager->GetObjectByNameAndClass(name, pcid, true);
auto finder = std::find(result.begin(), result.end(), previous);
if (finder == result.end()) return nullptr;
++finder;
if (finder == result.end()) return nullptr;
return *finder;
if (previous == nullptr) {
m_ObjectPointerCache = m_ObjectManager->GetObjectByNameAndClass(name, pcid, true);
}
return GeneralPrevFinder(m_ObjectPointerCache, previous);
}
const XContainer::XObjectPointerArray CKContext::GetObjectListByType(CK_CLASSID cid, bool derived) {
@ -136,11 +123,17 @@ namespace LibCmo::CK2 {
CKDWORD CKContext::GetObjectsCountByClassID(CK_CLASSID cid) {
auto result = m_ObjectManager->GetObjectByNameAndClass(nullptr, cid, false);
return static_cast<CKDWORD>(result.size());
m_ObjectCache.clear();
for (auto& obj : result) {
m_ObjectCache.emplace_back(obj->GetID());
}
return static_cast<CKDWORD>(m_ObjectCache.size());
}
CK_ID* CKContext::GetObjectsListByClassID(CK_CLASSID cid) {
// todo: impl internal buffer
return m_ObjectCache.data();
}
#pragma endregion
@ -278,24 +271,6 @@ namespace LibCmo::CK2 {
#pragma endregion
#pragma region Temp IO utilities
void CKContext::SetTempPath(CKSTRING u8_temp) {
EncodingHelper::U8PathToStdPath(this->m_TempFolder, u8_temp);
}
std::string CKContext::GetTempFilePath(CKSTRING u8_filename) {
std::filesystem::path stdfilename;
EncodingHelper::U8PathToStdPath(stdfilename, u8_filename);
auto realfile = this->m_TempFolder / stdfilename;
std::string result;
EncodingHelper::StdPathToU8Path(result, realfile);
return result;
}
#pragma endregion
#pragma region Encoding utilities
void CKContext::GetUtf8String(const std::string& native_name, std::string& u8_name) {

View File

@ -1,7 +1,6 @@
#pragma once
#include "../VTAll.hpp"
#include <filesystem>
#include <map>
#include <deque>
#include <functional>
@ -46,11 +45,15 @@ namespace LibCmo::CK2 {
ObjImpls::CKObject* GetObjectByName(CKSTRING name, ObjImpls::CKObject *previous = nullptr);
ObjImpls::CKObject* GetObjectByNameAndClass(CKSTRING name, CK_CLASSID cid, ObjImpls::CKObject *previous = nullptr);
ObjImpls::CKObject* GetObjectByNameAndParentClass(CKSTRING name, CK_CLASSID pcid, ObjImpls::CKObject* previous);
ObjImpls::CKObject* GetObjectByNameAndParentClass(CKSTRING name, CK_CLASSID pcid, ObjImpls::CKObject* previous = nullptr);
const XContainer::XObjectPointerArray GetObjectListByType(CK_CLASSID cid, bool derived);
CKDWORD GetObjectsCountByClassID(CK_CLASSID cid);
CK_ID* GetObjectsListByClassID(CK_CLASSID cid);
protected:
XContainer::XObjectPointerArray m_ObjectPointerCache;
XContainer::XObjectArray m_ObjectCache;
// ========== Common Managers ==========
public:
MgrImpls::CKObjectManager* GetObjectManager();
@ -104,14 +107,6 @@ namespace LibCmo::CK2 {
protected:
std::vector<EncodingHelper::ENCODING_TOKEN> m_NameEncoding;
// ========== Temp IO utilities ==========
public:
void SetTempPath(CKSTRING u8_temp);
std::string GetTempFilePath(CKSTRING u8_filename);
protected:
std::filesystem::path m_TempFolder;
// ========== Print utilities ==========
public:
using OutputCallback = std::function<void(CKSTRING)>;

View File

@ -1,6 +1,7 @@
#include "CKFile.hpp"
#include "CKStateChunk.hpp"
#include "ObjImpls/CKObject.hpp"
#include "MgrImpls/CKPathManager.hpp"
#include "../VxMath/VxMemoryMappedFile.hpp"
#include "CKContext.hpp"
#include <memory>
@ -313,7 +314,7 @@ namespace LibCmo::CK2 {
parser->Read(&filebodylen, sizeof(CKDWORD));
// read file body
std::string tempfilename = m_Ctx->GetTempFilePath(file.c_str());
std::string tempfilename = m_Ctx->GetPathManager()->GetTempFilePath(file.c_str());
FILE* fp = EncodingHelper::U8FOpen(tempfilename.c_str(), "wb");
if (fp != nullptr) {
std::fwrite(parser->GetPtr(), sizeof(char), filebodylen, fp);

View File

@ -3,6 +3,7 @@
#include "CKStateChunk.hpp"
#include "ObjImpls/CKObject.hpp"
#include "MgrImpls/CKBaseManager.hpp"
#include "MgrImpls/CKPathManager.hpp"
#include "../VxMath/VxMemoryMappedFile.hpp"
#include <memory>
@ -315,7 +316,7 @@ namespace LibCmo::CK2 {
std::fwrite(name_conv.data(), sizeof(char), filenamelen, fs);
// try mapping file.
std::string tempfilename = m_Ctx->GetTempFilePath(fentry.c_str());
std::string tempfilename = m_Ctx->GetPathManager()->GetTempFilePath(fentry.c_str());
std::unique_ptr<VxMath::VxMemoryMappedFile> mappedFile(new VxMath::VxMemoryMappedFile(tempfilename.c_str()));
if (mappedFile->IsValid()) {
// write file length

View File

@ -143,6 +143,8 @@ namespace LibCmo::CK2::MgrImpls {
}
}
}
return result;
}
CKDWORD CKObjectManager::AllocateGroupGlobalIndex(ObjImpls::CKObject* group) {

View File

@ -40,6 +40,13 @@ namespace LibCmo::CK2::MgrImpls {
// ========== Objects Access ==========
/**
* @brief General object list query.
* @param name nullptr if no requirement.
* @param cid the class id
* @param derived whether considering derived class
* @return the result pointer list.
*/
XContainer::XObjectPointerArray GetObjectByNameAndClass(
CKSTRING name, CK_CLASSID cid, bool derived);

View File

@ -2,5 +2,49 @@
namespace LibCmo::CK2::MgrImpls {
#if defined(LIBCMO_OS_WIN32)
static wchar_t g_UniqueFolder[] = L"LibCmo";
#else
static char g_UniqueFolder[] = "LibCmo";
#endif
CKPathManager::CKPathManager(CKContext* ctx) :
CKBaseManager(ctx, PATH_MANAGER_GUID, "Path Manager"),
m_TempFolder() {
// preset for temp folder
// todo: add current CKContext pointer as the part of temp path.
// thus multiple CKContext can work.
m_TempFolder = std::filesystem::temp_directory_path();
m_TempFolder /= g_UniqueFolder;
std::filesystem::create_directories(m_TempFolder);
}
CKPathManager::~CKPathManager() {}
void CKPathManager::SetTempFolder(CKSTRING u8_temp) {
EncodingHelper::U8PathToStdPath(this->m_TempFolder, u8_temp);
}
std::string CKPathManager::GetTempFolder() {
std::string result;
EncodingHelper::StdPathToU8Path(result, this->m_TempFolder);
return result;
}
std::string CKPathManager::GetTempFilePath(CKSTRING u8_filename) {
std::filesystem::path stdfilename;
EncodingHelper::U8PathToStdPath(stdfilename, u8_filename);
auto realfile = this->m_TempFolder / stdfilename;
std::string result;
EncodingHelper::StdPathToU8Path(result, realfile);
return result;
}
bool CKPathManager::ResolveFileName(std::string& u8_filename) {
// todo: finish resolve file name
return false;
}
}

View File

@ -2,18 +2,42 @@
#include "../../VTAll.hpp"
#include "CKBaseManager.hpp"
#include <filesystem>
namespace LibCmo::CK2::MgrImpls {
class CKPathManager : public CKBaseManager {
public:
CKPathManager(CKContext* ctx) :
CKBaseManager(ctx, PATH_MANAGER_GUID, "Path Manager") {}
virtual ~CKPathManager() {}
CKPathManager(CKContext* ctx);
virtual ~CKPathManager();
LIBCMO_DISABLE_COPY_MOVE(CKPathManager);
protected:
/**
* @brief Set the temp folder of current context.
* @param u8_temp
*/
void SetTempFolder(CKSTRING u8_temp);
/**
* @brief Get current temp folder.
* @return
*/
std::string GetTempFolder();
/**
* @brief Get the path of temp file.
* @param u8_filename The relative path of file.
* @return The path of given path based on temp folder.
*/
std::string GetTempFilePath(CKSTRING u8_filename);
/**
* @brief Finds a file in the paths
* @param u8_filename[inout] The given file path. overwritten by the final path if success.
* @return true if success
*/
bool ResolveFileName(std::string& u8_filename);
protected:
std::filesystem::path m_TempFolder;
};
}

View File

@ -1,10 +1,25 @@
#include "CKSceneObject.hpp"
#include "../CKStateChunk.hpp"
#include "../CKContext.hpp"
#include "../MgrImpls/CKObjectManager.hpp"
#include "CKBeObject.hpp"
#include "CKGroup.hpp"
namespace LibCmo::CK2::ObjImpls {
CKBeObject::CKBeObject(CKContext* ctx, CK_ID ckid, CKSTRING name) :
CKSceneObject(ctx, ckid, name) {}
CKBeObject::~CKBeObject() {
// remove self from all group
for (size_t i = 0; i < m_Groups.size(); ++i) {
if (m_Groups[i]) {
CKGroup* group = static_cast<CKGroup*>(m_Context->GetObjectManager()->GetGroupByGlobalIndex(static_cast<CKDWORD>(i)));
group->RemoveObject(this);
}
}
}
bool CKBeObject::Save(CKStateChunk* chunk, CKFileVisitor* file, CKDWORD flags) {
bool suc = CKSceneObject::Save(chunk, file, flags);
if (!suc) return false;

View File

@ -7,10 +7,8 @@ namespace LibCmo::CK2::ObjImpls {
class CKBeObject : public CKSceneObject {
public:
CKBeObject(CKContext* ctx, CK_ID ckid, CKSTRING name) :
CKSceneObject(ctx, ckid, name)
{}
virtual ~CKBeObject() {}
CKBeObject(CKContext* ctx, CK_ID ckid, CKSTRING name);
virtual ~CKBeObject();
LIBCMO_DISABLE_COPY_MOVE(CKBeObject);
virtual CK_CLASSID GetClassID(void) override {

View File

@ -1,6 +1,7 @@
#include "CKGroup.hpp"
#include "../CKStateChunk.hpp"
#include "../CKContext.hpp"
#include "../MgrImpls/CKObjectManager.hpp"
#include <algorithm>
namespace LibCmo::CK2::ObjImpls {
@ -8,10 +9,10 @@ namespace LibCmo::CK2::ObjImpls {
CKGroup::CKGroup(CKContext* ctx, CK_ID ckid, CKSTRING name) :
CKBeObject(ctx, ckid, name),
m_ObjectArray(),
m_GroupIndex(m_Context->AllocateGroupGlobalIndex()) {}
m_GroupIndex(m_Context->GetObjectManager()->AllocateGroupGlobalIndex(this)) {}
CKGroup::~CKGroup() {
m_Context->FreeGroupGlobalIndex(m_GroupIndex);
m_Context->GetObjectManager()->FreeGroupGlobalIndex(m_GroupIndex);
}
bool CKGroup::Save(CKStateChunk* chunk, CKFileVisitor* file, CKDWORD flags) {

View File

@ -11,6 +11,7 @@
#undef GetObject
#undef GetClassName
#undef LoadImage
#undef GetTempPath
#else
#include <iconv.h>
#endif