write shit

This commit is contained in:
yyc12345 2023-02-28 11:35:54 +08:00
parent 95cb1f7c30
commit 1a959a4c55
8 changed files with 149 additions and 21 deletions

View File

@ -37,17 +37,19 @@ namespace LibCmo::CK2 {
} }
CKFileObject::~CKFileObject() { CKFileObject::~CKFileObject() {
; if (Data != nullptr) delete Data;
} }
#pragma endregion #pragma endregion
#pragma region CKFileManagerData #pragma region CKFileManagerData
CKFileManagerData::CKFileManagerData() { CKFileManagerData::CKFileManagerData() :
Data(nullptr) {
} }
CKFileManagerData::~CKFileManagerData() { CKFileManagerData::~CKFileManagerData() {
if (Data != nullptr) delete Data;
} }
#pragma endregion #pragma endregion
@ -67,7 +69,7 @@ namespace LibCmo::CK2 {
#pragma region ShallowDocument #pragma region ShallowDocument
ShallowDocument::ShallowDocument() { ShallowDocument::ShallowDocument() {
this->m_IndexByClassId.resize(static_cast<size_t>(CK_CLASSID::CKCID_MAXCLASSID)); /*this->m_IndexByClassId.resize(static_cast<size_t>(CK_CLASSID::CKCID_MAXCLASSID));*/
} }
ShallowDocument::~ShallowDocument() { ShallowDocument::~ShallowDocument() {
@ -79,7 +81,7 @@ namespace LibCmo::CK2 {
#pragma region DeepDocument #pragma region DeepDocument
DeepDocument::DeepDocument() { DeepDocument::DeepDocument() {
this->m_IndexByClassId.resize(static_cast<size_t>(CK_CLASSID::CKCID_MAXCLASSID)); /*this->m_IndexByClassId.resize(static_cast<size_t>(CK_CLASSID::CKCID_MAXCLASSID));*/
} }
DeepDocument::~DeepDocument() { DeepDocument::~DeepDocument() {

View File

@ -137,7 +137,7 @@ namespace LibCmo::CK2 {
XArray<CKFileObject> m_FileObjects; XArray<CKFileObject> m_FileObjects;
XArray<CKFileManagerData> m_FileManagersData; XArray<CKFileManagerData> m_FileManagersData;
XClassArray<CKFilePluginDependencies> m_PluginDep; XClassArray<CKFilePluginDependencies> m_PluginDep;
XClassArray<XIntArray> m_IndexByClassId; /*XClassArray<XIntArray> m_IndexByClassId;*/
XClassArray<XString> m_IncludedFiles; XClassArray<XString> m_IncludedFiles;
private: private:
@ -155,7 +155,7 @@ namespace LibCmo::CK2 {
CKFileInfo m_FileInfo; CKFileInfo m_FileInfo;
XArray<CKObjectImplements::CKObject*> m_Objects; XArray<CKObjectImplements::CKObject*> m_Objects;
XClassArray<XIntArray> m_IndexByClassId; /*XClassArray<XIntArray> m_IndexByClassId;*/
XClassArray<XString> m_IncludedFiles; XClassArray<XString> m_IncludedFiles;
private: private:

View File

@ -1,6 +1,7 @@
#include "CKFile.hpp" #include "CKFile.hpp"
#include "CKGlobals.hpp" #include "CKGlobals.hpp"
#include "CKStateChunk.hpp" #include "CKStateChunk.hpp"
#include "CKObjects.hpp"
#include "VxMemoryMappedFile.hpp" #include "VxMemoryMappedFile.hpp"
#include "CKMinContext.hpp" #include "CKMinContext.hpp"
#include <memory> #include <memory>
@ -351,6 +352,65 @@ namespace LibCmo::CK2 {
} }
CKERROR CKFile::DeepLoad(CKSTRING u8_filename, CKFileData::DeepDocument** out_doc) { CKERROR CKFile::DeepLoad(CKSTRING u8_filename, CKFileData::DeepDocument** out_doc) {
// ========== prepare work ==========
// preset value
*out_doc = nullptr;
// get shallow document first
CKFileData::ShallowDocument* rawShallowDoc = nullptr;
CKERROR err = this->ShallowLoad(u8_filename, &rawShallowDoc);
if (rawShallowDoc == nullptr) return err;
std::unique_ptr<CKFileData::ShallowDocument> shallowDoc(rawShallowDoc);
if (err != CKERROR::CKERR_OK) return err;
// create deep document
std::unique_ptr<CKFileData::DeepDocument> deepDoc(new(std::nothrow) CKFileData::DeepDocument());
if (deepDoc == nullptr) return CKERROR::CKERR_OUTOFMEMORY;
// ========== create object first ==========
size_t index = 0u;
std::vector<CKObjectImplements::CKObject*> createdObjs(shallowDoc->m_FileObjects.size(), nullptr);
for (index = 0u; index < shallowDoc->m_FileObjects.size(); ++index) {
// todo: skip CK_LEVEL
// todo: resolve references
const auto& obj = shallowDoc->m_FileObjects[index];
if (obj.Data == nullptr) continue;
createdObjs[index] = m_MinCtx->CreateCKObject(obj.ObjectId, obj.ObjectCid, obj.Name.c_str());
}
// ========== CKStateChunk remap ==========
// todo: remap
// todo: CK_LEVEL special proc
// ========== consume Managers ==========
// todo...
// ========== analyze objects CKStateChunk ==========
for (index = 0u; index < shallowDoc->m_FileObjects.size(); ++index) {
const auto& obj = shallowDoc->m_FileObjects[index];
if (obj.Data == nullptr || createdObjs[index] == nullptr) continue;
// todo: special treat for CK_LEVEL
// try parsing data
CKERROR err = createdObjs[index]->Load(obj.Data, shallowDoc.get());
if (err != CKERROR::CKERR_OK) {
delete (createdObjs[index]);
createdObjs[index] = nullptr;
} else {
// add into result
deepDoc->m_Objects.push_back(createdObjs[index]);
}
}
// ========== finalize work ==========
// copy misc structure
deepDoc->m_IncludedFiles = shallowDoc->m_IncludedFiles;
deepDoc->m_SaveIDMax = shallowDoc->m_SaveIDMax;
deepDoc->m_FileInfo = shallowDoc->m_FileInfo;
// detach and return
*out_doc = deepDoc.release();
return CKERROR::CKERR_OK; return CKERROR::CKERR_OK;
} }

View File

@ -11,11 +11,13 @@ namespace LibCmo::CK2 {
static char g_UniqueFolder[] = "LibCmo"; static char g_UniqueFolder[] = "LibCmo";
#endif #endif
#pragma region Ctor Dtor
CKMinContext::CKMinContext() : CKMinContext::CKMinContext() :
m_NameEncoding(), m_NameEncodingToken(EncodingHelper::ENCODING_TOKEN_DEFAULT), m_NameEncoding(), m_NameEncodingToken(EncodingHelper::ENCODING_TOKEN_DEFAULT),
m_TempFolder(), m_TempFolder(),
m_PrintCallback(nullptr), m_PrintCallback(nullptr),
m_CKObjectMaxID(0u),
// register CKObjects // register CKObjects
m_ObjectsCreationMap{ m_ObjectsCreationMap{
{CK_CLASSID::CKCID_OBJECT, ([](CKMinContext* ctx, CK_ID id, CKSTRING name) ->CKObjectImplements::CKObject* { return new(std::nothrow) CKObjectImplements::CKObject(ctx, id, name); })}, {CK_CLASSID::CKCID_OBJECT, ([](CKMinContext* ctx, CK_ID id, CKSTRING name) ->CKObjectImplements::CKObject* { return new(std::nothrow) CKObjectImplements::CKObject(ctx, id, name); })},
@ -43,6 +45,10 @@ namespace LibCmo::CK2 {
} }
#pragma endregion
#pragma region Print
void CKMinContext::Printf(CKSTRING fmt, ...) { void CKMinContext::Printf(CKSTRING fmt, ...) {
if (m_PrintCallback == nullptr) return; if (m_PrintCallback == nullptr) return;
@ -65,6 +71,52 @@ namespace LibCmo::CK2 {
m_PrintCallback = cb; m_PrintCallback = cb;
} }
#pragma endregion
#pragma region Objects
CKObjectImplements::CKObject* CKMinContext::CreateCKObject(CK_ID id, CK_CLASSID cls, CKSTRING name) {
// pick creation function
const auto& creation = m_ObjectsCreationMap.find(cls);
if (creation == m_ObjectsCreationMap.end()) return nullptr;
// check ckid
if (m_ObjectsList.contains(id)) return nullptr;
// create it
return creation->second(this, id, name);
}
CKObjectImplements::CKObject* CKMinContext::GetCKObject(CK_ID id) {
const auto& probe = m_ObjectsList.find(id);
if (probe == m_ObjectsList.end()) return nullptr;
else return probe->second;
}
void CKMinContext::DestroyCKObject(CK_ID id) {
const auto& probe = m_ObjectsList.find(id);
if (probe != m_ObjectsList.end()) {
delete (probe->second);
m_ObjectsList.erase(probe);
}
}
CK_ID CKMinContext::GetObjectMaxID(void) {
return this->m_CKObjectMaxID;
}
void CKMinContext::SetObjectMaxID(CK_ID id) {
this->m_CKObjectMaxID = id;
}
#pragma endregion
#pragma region Managers
#pragma endregion
#pragma region Misc Funcs
void CKMinContext::GetUtf8String(std::string& native_name, std::string& u8_name) { void CKMinContext::GetUtf8String(std::string& native_name, std::string& u8_name) {
EncodingHelper::GetUtf8VirtoolsName(native_name, u8_name, this->m_NameEncodingToken); EncodingHelper::GetUtf8VirtoolsName(native_name, u8_name, this->m_NameEncodingToken);
} }
@ -95,4 +147,6 @@ namespace LibCmo::CK2 {
this->m_NameEncodingToken = EncodingHelper::CreateEncodingToken(this->m_NameEncoding); this->m_NameEncodingToken = EncodingHelper::CreateEncodingToken(this->m_NameEncoding);
} }
#pragma endregion
} }

View File

@ -22,11 +22,14 @@ namespace LibCmo::CK2 {
CKObjectImplements::CKObject* CreateCKObject(CK_ID id, CK_CLASSID cls, CKSTRING name); CKObjectImplements::CKObject* CreateCKObject(CK_ID id, CK_CLASSID cls, CKSTRING name);
CKObjectImplements::CKObject* GetCKObject(CK_ID id); CKObjectImplements::CKObject* GetCKObject(CK_ID id);
void DestroyCKObject(CKObjectImplements::CKObject* obj); void DestroyCKObject(CK_ID id);
CKManagerImplements::CKBaseManager* CreateCKManager(CKGUID guid); //CKManagerImplements::CKBaseManager* CreateCKManager(CKGUID guid);
CKManagerImplements::CKBaseManager* GetCKManager(CK_ID guid); //CKManagerImplements::CKBaseManager* GetCKManager(CK_ID guid);
void DestroyCKManager(CKManagerImplements::CKBaseManager* mgr); //void DestroyCKManager(CKManagerImplements::CKBaseManager* mgr);
CK_ID GetObjectMaxID(void);
void SetObjectMaxID(CK_ID id);
void GetUtf8String(std::string& native_name, std::string& u8_name); void GetUtf8String(std::string& native_name, std::string& u8_name);
void GetNativeString(std::string& u8_name, std::string& native_name); void GetNativeString(std::string& u8_name, std::string& native_name);
@ -45,6 +48,8 @@ namespace LibCmo::CK2 {
std::map<CK_CLASSID, std::function<CKObjectImplements::CKObject* (CKMinContext*, CK_ID, CKSTRING)>> m_ObjectsCreationMap; std::map<CK_CLASSID, std::function<CKObjectImplements::CKObject* (CKMinContext*, CK_ID, CKSTRING)>> m_ObjectsCreationMap;
std::map<CKGUID, std::function<CKManagerImplements::CKBaseManager* (CKMinContext*, CK_ID)>> m_ManagersCreationMap; std::map<CKGUID, std::function<CKManagerImplements::CKBaseManager* (CKMinContext*, CK_ID)>> m_ManagersCreationMap;
CK_ID m_CKObjectMaxID;
std::string m_NameEncoding; std::string m_NameEncoding;
EncodingHelper::ENCODING_TOKEN m_NameEncodingToken; EncodingHelper::ENCODING_TOKEN m_NameEncodingToken;
std::filesystem::path m_TempFolder; std::filesystem::path m_TempFolder;

View File

@ -4,7 +4,7 @@ namespace LibCmo::CK2::CKObjectImplements {
CKObject::CKObject(CKMinContext* ctx, CK_ID ckid, CKSTRING name) : CKObject::CKObject(CKMinContext* ctx, CK_ID ckid, CKSTRING name) :
m_ID(ckid), m_Context(ctx), m_ID(ckid), m_Context(ctx),
m_Name(name == nullptr ? "" : name), m_HasName(name != nullptr), m_Name(name == nullptr ? "" : name),
m_ObjectFlags(CK_OBJECT_FLAGS::CK_PARAMETERIN_DISABLED) { m_ObjectFlags(CK_OBJECT_FLAGS::CK_PARAMETERIN_DISABLED) {
; ;
} }
@ -13,6 +13,13 @@ namespace LibCmo::CK2::CKObjectImplements {
} }
CKERROR CKObject::Load(CKStateChunk* chunk, const CKFileData::ShallowDocument* doc) {
return CKERROR::CKERR_OK;
}
CKStateChunk* CKObject::Save(CKFileData::ShallowDocument* doc) {
return nullptr;
}
CKSceneObject::CKSceneObject(CKMinContext* ctx, CK_ID ckid, CKSTRING name) : CKObject(ctx, ckid, name) { CKSceneObject::CKSceneObject(CKMinContext* ctx, CK_ID ckid, CKSTRING name) : CKObject(ctx, ckid, name) {
} }
CKSceneObject::~CKSceneObject() { CKSceneObject::~CKSceneObject() {
@ -35,6 +42,11 @@ namespace LibCmo::CK2::CKObjectImplements {
CKTexture::CKTexture(CKMinContext* ctx, CK_ID ckid, CKSTRING name) : CKBeObject(ctx, ckid, name) { CKTexture::CKTexture(CKMinContext* ctx, CK_ID ckid, CKSTRING name) : CKBeObject(ctx, ckid, name) {
} }
CKTexture::~CKTexture() {
}
CKMaterial::CKMaterial(CKMinContext* ctx, CK_ID ckid, CKSTRING name) : CKBeObject(ctx, ckid, name) {
}
CKMaterial::~CKMaterial() { CKMaterial::~CKMaterial() {
} }

View File

@ -13,22 +13,17 @@ namespace LibCmo::CK2::CKObjectImplements {
virtual ~CKObject(); virtual ~CKObject();
CK_ID GetID(void) { return this->m_ID; } CK_ID GetID(void) { return this->m_ID; }
CKSTRING GetName(void) { return m_HasName ? this->m_Name.c_str() : nullptr; } CKSTRING GetName(void) { (this->m_Name.empty()) ? (nullptr) : (this->m_Name.c_str()); }
void SetName(CKSTRING u8_name) { void SetName(CKSTRING u8_name) { this->m_Name = (u8_name == nullptr ? "" : u8_name); }
this->m_HasName = u8_name != nullptr;
if (this->m_HasName) this->m_Name = u8_name;
else this->m_Name.clear();
}
CK_OBJECT_FLAGS GetObjectFlags(void) { return this->m_ObjectFlags; } CK_OBJECT_FLAGS GetObjectFlags(void) { return this->m_ObjectFlags; }
void SetObjectFlags(CK_OBJECT_FLAGS flags) { this->m_ObjectFlags = flags; } void SetObjectFlags(CK_OBJECT_FLAGS flags) { this->m_ObjectFlags = flags; }
virtual CK_CLASSID GetClassID(void) { return CK_CLASSID::CKCID_OBJECT; } virtual CK_CLASSID GetClassID(void) { return CK_CLASSID::CKCID_OBJECT; }
virtual CKERROR Load(CKStateChunk* chunk, CKFileData::ShallowDocument* doc); virtual CKERROR Load(CKStateChunk* chunk, const CKFileData::ShallowDocument* doc);
virtual CKStateChunk* Save(CKFileData::ShallowDocument* doc); virtual CKStateChunk* Save(CKFileData::ShallowDocument* doc);
protected: protected:
CK_ID m_ID; CK_ID m_ID;
std::string m_Name; std::string m_Name;
bool m_HasName;
CK_OBJECT_FLAGS m_ObjectFlags; CK_OBJECT_FLAGS m_ObjectFlags;
CKMinContext* m_Context; CKMinContext* m_Context;
}; };

View File

@ -17,8 +17,8 @@ int main(int argc, char* argv[]) {
vtctx.SetEncoding("850"); vtctx.SetEncoding("850");
LibCmo::CK2::CKFile vtfile(&vtctx); LibCmo::CK2::CKFile vtfile(&vtctx);
LibCmo::CK2::CKFileData::ShallowDocument* doc; LibCmo::CK2::CKFileData::DeepDocument* doc;
LibCmo::CK2::CKERROR err = vtfile.ShallowLoad("Language.old.nmo", &doc); LibCmo::CK2::CKERROR err = vtfile.DeepLoad("Language.old.nmo", &doc);
if (doc) if (doc)
Unvirt::StructFormatter::PrintCKFileInfo(doc->m_FileInfo); Unvirt::StructFormatter::PrintCKFileInfo(doc->m_FileInfo);