write shit

This commit is contained in:
yyc12345 2023-08-25 17:35:45 +08:00
parent ad9d0cadce
commit c8c2c6e20b
14 changed files with 472 additions and 411 deletions

View File

@ -38,6 +38,9 @@ namespace LibCmo::CK2 {
// put into slot
m_ObjectsList[decided_id] = obj;
// set out variable
return obj;
}
CKObject* CKContext::GetCKObject(CK_ID id) {

View File

@ -1,188 +0,0 @@
#include "CKFile.hpp"
#include "CKStateChunk.hpp"
#include "CKMinContext.hpp"
#include <cstdarg>
namespace LibCmo::CK2 {
#pragma region CKBufferParser
CKBufferParser::CKBufferParser(void* ptr, size_t rsize, bool need_manual_free) :
m_MemBegin(static_cast<char*>(ptr)),
m_MemPos(0u), m_MemSize(rsize),
m_NeedManualFree(need_manual_free) {
;
}
CKBufferParser::~CKBufferParser() {
if (this->m_NeedManualFree) delete[](this->m_MemBegin);
}
#pragma endregion
#pragma region CKFileInfo
CKFileInfo::CKFileInfo() :
ProductVersion(0u), ProductBuild(0x01010000u), FileWriteMode(CK_FILE_WRITEMODE::CKFILE_UNCOMPRESSED),
FileVersion(8u), CKVersion(CKVERSION), FileSize(0u),
ObjectCount(0u), ManagerCount(0u), MaxIDSaved(0u), Crc(0u),
Hdr1PackSize(0u), Hdr1UnPackSize(0u), DataPackSize(0u), DataUnPackSize(0u) {
}
CKFileInfo::CKFileInfo(const CKFileInfo& rhs) :
ProductVersion(rhs.ProductVersion), ProductBuild(rhs.ProductBuild), FileWriteMode(rhs.FileWriteMode),
FileVersion(rhs.FileVersion), CKVersion(rhs.CKVersion), FileSize(rhs.FileSize),
ObjectCount(rhs.ObjectCount), ManagerCount(rhs.ManagerCount), MaxIDSaved(rhs.MaxIDSaved), Crc(rhs.Crc),
Hdr1PackSize(rhs.Hdr1PackSize), Hdr1UnPackSize(rhs.Hdr1UnPackSize),
DataPackSize(rhs.DataPackSize), DataUnPackSize(rhs.DataUnPackSize) {
}
CKFileInfo& CKFileInfo::operator=(const CKFileInfo& rhs) {
this->ProductVersion = rhs.ProductVersion;
this->ProductBuild = rhs.ProductBuild;
this->FileWriteMode = rhs.FileWriteMode;
this->FileVersion = rhs.FileVersion;
this->CKVersion = rhs.CKVersion;
this->FileSize = rhs.FileSize;
this->ObjectCount = rhs.ObjectCount;
this->ManagerCount = rhs.ManagerCount;
this->MaxIDSaved = rhs.MaxIDSaved;
this->Crc = rhs.Crc;
this->Hdr1PackSize = rhs.Hdr1PackSize;
this->Hdr1UnPackSize = rhs.Hdr1UnPackSize;
this->DataPackSize = rhs.DataPackSize;
this->DataUnPackSize = rhs.DataUnPackSize;
return *this;
}
CKFileInfo::~CKFileInfo() {
}
#pragma endregion
#pragma region CKFileObject
CKFileObject::CKFileObject() :
ObjectId(0u), CreatedObject(0u), ObjectCid(CK_CLASSID::CKCID_OBJECT), Name(),
ObjPtr(nullptr), Data(nullptr), FileIndex(0u) {
}
CKFileObject::CKFileObject(const CKFileObject& rhs) :
ObjectId(rhs.ObjectId), CreatedObject(rhs.CreatedObject), ObjectCid(rhs.ObjectCid), Name(rhs.Name),
ObjPtr(rhs.ObjPtr), Data(rhs.Data), FileIndex(rhs.FileIndex) {
// CKObject is managed by CKMinContext, so we just copy its pointer.
// however, we need copy CKStateChunk.
if (this->Data != nullptr) {
this->Data = new(std::nothrow) CKStateChunk(*(rhs.Data));
}
}
CKFileObject& CKFileObject::operator=(const CKFileObject& rhs) {
this->ObjectId = rhs.ObjectId;
this->CreatedObject = rhs.CreatedObject;
this->ObjectCid = rhs.ObjectCid;
this->Name = rhs.Name;
this->FileIndex = rhs.FileIndex;
// CKObject is managed by CKMinContext, so we just copy its pointer.
this->ObjPtr = rhs.ObjPtr;
// however, we need copy CKStateChunk.
this->Data = rhs.Data;
if (this->Data != nullptr) {
this->Data = new(std::nothrow) CKStateChunk(*(rhs.Data));
}
return *this;
}
CKFileObject::~CKFileObject() {
if (Data != nullptr) delete Data;
}
#pragma endregion
#pragma region CKFileManagerData
CKFileManagerData::CKFileManagerData() :
MgrPtr(nullptr), Data(nullptr), Manager(0u, 0u) {
}
CKFileManagerData::CKFileManagerData(const CKFileManagerData& rhs) :
MgrPtr(rhs.MgrPtr), Data(rhs.Data), Manager(rhs.Manager) {
if (this->Data != nullptr) {
this->Data = new(std::nothrow) CKStateChunk(*(rhs.Data));
}
}
CKFileManagerData& CKFileManagerData::operator=(const CKFileManagerData& rhs) {
this->Manager = rhs.Manager;
this->MgrPtr = rhs.MgrPtr;
this->Data = rhs.Data;
if (this->Data != nullptr) {
this->Data = new(std::nothrow) CKStateChunk(*(rhs.Data));
}
return *this;
}
CKFileManagerData::~CKFileManagerData() {
if (Data != nullptr) delete Data;
}
#pragma endregion
#pragma region CKFilePluginDependencies
CKFilePluginDependencies::CKFilePluginDependencies() :
m_PluginCategory(CK_PLUGIN_TYPE::CKPLUGIN_MANAGER_DLL), m_Guids() {
}
CKFilePluginDependencies::CKFilePluginDependencies(const CKFilePluginDependencies& rhs) :
m_PluginCategory(rhs.m_PluginCategory), m_Guids(rhs.m_Guids) {
}
CKFilePluginDependencies& CKFilePluginDependencies::operator=(const CKFilePluginDependencies& rhs) {
this->m_PluginCategory = rhs.m_PluginCategory;
this->m_Guids = rhs.m_Guids;
return *this;
}
CKFilePluginDependencies::~CKFilePluginDependencies() {
}
#pragma endregion
#pragma region ShallowDocument
CKFileDocument::CKFileDocument() {
/*this->m_IndexByClassId.resize(static_cast<size_t>(CK_CLASSID::CKCID_MAXCLASSID));*/
}
CKFileDocument::~CKFileDocument() {
}
#pragma endregion
#pragma region CKFile Misc
CKFile::CKFile(CKMinContext* ctx) :
m_MinCtx(ctx) {
;
}
CKFile::~CKFile() {
}
#pragma endregion
}

View File

@ -1,7 +1,11 @@
#pragma once
#include "CKDefines.hpp"
#include "CKEnums.hpp"
#include "../VTAll.hpp"
namespace LibCmo::XContainer {
using XIntArray = XArray<CK2::CKINT>;
using XFileObjectsTable = XHashTable<CK2::CK_ID, CK2::CKINT>;
}
namespace LibCmo::CK2 {
@ -13,25 +17,31 @@ namespace LibCmo::CK2 {
size_t m_MemSize;
public:
CKBufferParser(void* ptr, size_t rsize, bool need_manual_free);
CKBufferParser(const CKBufferParser&) = delete;
CKBufferParser& operator=(const CKBufferParser&) = delete;
~CKBufferParser();
CKBufferParser(void* ptr, size_t rsize, bool need_manual_free) :
m_MemBegin(static_cast<char*>(ptr)),
m_MemPos(0u), m_MemSize(rsize),
m_NeedManualFree(need_manual_free) {
;
}
~CKBufferParser() {
if (this->m_NeedManualFree) delete[](this->m_MemBegin);
}
LIBCMO_DISABLE_COPY_MOVE(CKBufferParser);
inline const void* GetPtr(void) { return (this->m_MemBegin + m_MemPos); }
inline void Read(void* data, size_t data_size) {
const void* GetPtr(void) { return (this->m_MemBegin + m_MemPos); }
void Read(void* data, size_t data_size) {
std::memcpy(data, (this->m_MemBegin + m_MemPos), data_size);
this->m_MemPos += data_size;
}
inline void Write(const void* data, size_t data_size) {
void Write(const void* data, size_t data_size) {
std::memcpy((this->m_MemBegin + m_MemPos), data, data_size);
this->m_MemPos += data_size;
}
inline void* GetBase(void) { return this->m_MemBegin; }
inline size_t GetSize(void) { return this->m_MemSize; }
inline size_t GetCursor(void) { return this->m_MemPos; }
inline void MoveCursor(size_t off) { this->m_MemPos += off; }
inline void SetCursor(size_t off) { this->m_MemPos = off; }
void* GetBase(void) { return this->m_MemBegin; }
size_t GetSize(void) { return this->m_MemSize; }
size_t GetCursor(void) { return this->m_MemPos; }
void MoveCursor(size_t off) { this->m_MemPos += off; }
void SetCursor(size_t off) { this->m_MemPos = off; }
};
#pragma pack(push)
@ -58,104 +68,110 @@ namespace LibCmo::CK2 {
class CKFileInfo {
public:
CKFileInfo();
CKFileInfo(const CKFileInfo&);
CKFileInfo& operator=(const CKFileInfo&);
~CKFileInfo();
CKDWORD ProductVersion; // Virtools Version (Dev/Creation). (CK_VIRTOOLS_VERSION)
CKDWORD ProductBuild; // Virtools Build Number.
CK_FILE_WRITEMODE FileWriteMode; // Options used to save this file. (CK_FILE_WRITEMODE)
CKDWORD FileVersion; // Version of file format when file was saved.
CKDWORD CKVersion; // Version of CK when file was saved.
size_t FileSize; // Size of file in bytes.
CKDWORD ObjectCount; // Number of objects stored in the file.
CKDWORD ManagerCount; // Number of managers which saved data in the file.
CKDWORD MaxIDSaved; // Maximum Object identifier saved
CKDWORD Crc; // Crc of data
CKDWORD Hdr1PackSize; // Reserved
CKDWORD Hdr1UnPackSize; // Reserved
CKDWORD DataPackSize; // Reserved
CKDWORD DataUnPackSize; // Reserved
private:
CKFileInfo() :
ProductVersion(0u), ProductBuild(0x01010000u), FileWriteMode(CK_FILE_WRITEMODE::CKFILE_UNCOMPRESSED),
FileVersion(8u), CKVersion(CKVERSION), FileSize(0u),
ObjectCount(0u), ManagerCount(0u), MaxIDSaved(0u), Crc(0u),
Hdr1PackSize(0u), Hdr1UnPackSize(0u), DataPackSize(0u), DataUnPackSize(0u) {}
~CKFileInfo() {}
LIBCMO_DEFAULT_COPY_MOVE(CKFileInfo);
CKDWORD ProductVersion; ///< Virtools Version (Dev/Creation). (CK_VIRTOOLS_VERSION)
CKDWORD ProductBuild; ///< Virtools Build Number.
CK_FILE_WRITEMODE FileWriteMode; ///< Options used to save this file. (CK_FILE_WRITEMODE)
CKDWORD FileVersion; ///< Version of file format when file was saved.
CKDWORD CKVersion; ///< Version of CK when file was saved.
CKDWORD FileSize; ///< Size of file in bytes.
CKDWORD ObjectCount; ///< Number of objects stored in the file.
CKDWORD ManagerCount; ///< Number of managers which saved data in the file.
CKDWORD MaxIDSaved; ///< Maximum Object identifier saved
CKDWORD Crc; ///< Crc of data
CKDWORD Hdr1PackSize; ///< Reserved
CKDWORD Hdr1UnPackSize; ///< Reserved
CKDWORD DataPackSize; ///< Reserved
CKDWORD DataUnPackSize; ///< Reserved
};
class CKFileObject {
public:
CKFileObject();
CKFileObject(const CKFileObject&);
CKFileObject(CKFileObject&&);
CKFileObject& operator=(const CKFileObject&);
CKFileObject& operator=(CKFileObject&&);
~CKFileObject();
CK_ID ObjectId; // ID of the object being load/saved (as it will be/was saved in the file)
CK_ID CreatedObject; // ID of the object being created
CK_CLASSID ObjectCid; // Class Identifier of the object
CKObjectImplements::CKObject* ObjPtr; // A pointer to the object itself (as CreatedObject when loading)
std::string Name; // Name of the Object
CKStateChunk* Data; // A CKStateChunk that contains object information
CKDWORD FileIndex; // Position of the object data inside uncompressed file buffer
private:
CK_ID ObjectId; ///< ID of the object being load/saved (as it will be/was saved in the file)
CK_ID CreatedObjectId; ///< ID of the object being created
CK_CLASSID ObjectCid; ///< Class Identifier of the object
CKObject* ObjPtr; ///< A pointer to the object itself (as CreatedObject when loading)
TypeHelper::MKString Name; ///< Name of the Object
CKStateChunk* Data; ///< A CKStateChunk that contains object information
//CKINT PostPackSize; ///< When compressed chunk by chunk : size of Data after compression
//CKINT PrePackSize; ///< When compressed chunk by chunk : size of Data before compression
CK_FO_OPTIONS Options; ///< When loading an object it may be renamed , use to replace another object
CKINT FileIndex; ///< Position of the object data inside uncompressed file buffer
CKDWORD SaveFlags; ///< Flags used when this object was saved.
};
class CKFileManagerData {
public:
CKFileManagerData();
CKFileManagerData(const CKFileManagerData&);
CKFileManagerData(CKFileManagerData&&);
CKFileManagerData& operator=(const CKFileManagerData&);
CKFileManagerData& operator=(CKFileManagerData&&);
~CKFileManagerData();
CKManagerImplements::CKBaseManager* MgrPtr;
CKStateChunk* Data;
CKGUID Manager;
private:
};
class CKFilePluginDependencies {
public:
CKFilePluginDependencies();
CKFilePluginDependencies(const CKFilePluginDependencies&);
CKFilePluginDependencies& operator=(const CKFilePluginDependencies&);
~CKFilePluginDependencies();
CKFilePluginDependencies() :
m_PluginCategory(CK_PLUGIN_TYPE::CKPLUGIN_MANAGER_DLL), m_Guids() {}
~CKFilePluginDependencies() {}
LIBCMO_DEFAULT_COPY_MOVE(CKFilePluginDependencies);
CK_PLUGIN_TYPE m_PluginCategory;
XArray<CKGUID> m_Guids;
private:
};
class CKFileDocument {
public:
CKFileDocument();
~CKFileDocument();
int32_t m_SaveIDMax;
CKFileInfo m_FileInfo;
XArray<CKFileObject> m_FileObjects;
XArray<CKFileManagerData> m_FileManagersData;
XClassArray<CKFilePluginDependencies> m_PluginDep;
/*XClassArray<XIntArray> m_IndexByClassId;*/
XClassArray<XString> m_IncludedFiles;
private:
XContainer::XArray<CKGUID> m_Guids;
XContainer::XBitArray ValidGuids;
};
/**
@brief CKFile provides functions to save/load files in Virtools format.
@remark
+ Use CKFile just like a normal C++ class with passing CKCotext pointer.
+ Once created a CKFile can be used to save one or more objects to disk.
+ Only can load objects when this CKFile is empty. Use ClearData() to clear any existed CKFile.
+ In any case, CKFile can run Save(). So you can create a CKFile, add some obejcts and save it.
Or you can load a file by CKFile and add/modify something then save it.
*/
class CKFile {
public:
CKFile(CKMinContext* ctx);
CKFile(const CKFile&) = delete;
CKFile& operator=(const CKFile&) = delete;
CKFile(CKContext* ctx);
~CKFile();
LIBCMO_DISABLE_COPY_MOVE(CKFile);
// ========== Reset CKFile ==========
void ClearData(void);
CKERROR ShallowLoad(CKSTRING u8_filename, CKFileDocument** out_doc);
CKERROR DeepLoad(CKSTRING u8_filename, CKFileDocument** out_doc);
// ========== Loading ==========
CKERROR ShallowLoad(CKSTRING u8_filename);
CKERROR DeepLoad(CKSTRING u8_filename);
CKERROR Save(CKSTRING u8_filename, CKFileDocument* in_doc);
// ========== Loading Result ==========
const XContainer::XArray<CKFileObject>& GetFileObjects();
const XContainer::XArray<XContainer::XString>& GetIncludedFiles();
// ========== Saving Preparing ==========
CKBOOL AddSavedObject(CKObject* obj, CKDWORD flags = CK_STATESAVE_ALL);
CKBOOL AddSavedObjects(CKObjectArray* objarray, CKDWORD flags = CK_STATESAVE_ALL);
CKBOOL AddSavedFile(CKSTRING u8FileName);
// ========== Saving ==========
CKERROR Save(CKSTRING u8_filename);
//CKERROR Load(CKSTRING u8_filename, /*CKObjectArray list, */ CK_LOAD_FLAGS flags);
//CKERROR OpenFile(CKSTRING u8_filename, CK_LOAD_FLAGS flags);
@ -165,29 +181,33 @@ namespace LibCmo::CK2 {
//CKERROR LoadFileData(void/*CKObjectArray list*/);
//CKERROR FinishLoading(/*CKObjectArray list, */CK_LOAD_FLAGS flags);
//int32_t m_SaveIDMax;
//XArray<CKFileObject> m_FileObject;
//XArray<CKFileManagerData> m_ManagersData;
//XClassArray<CKFilePluginDependencies> m_PluginDep;
//XClassArray<XIntArray> m_IndexByClassId;
//XClassArray<XString> m_IncludedFiles;
CKINT m_SaveIDMax; // Maximum CK_ID found when saving or loading objects
XContainer::XArray<CKFileObject> m_FileObjects; // List of objects being saved / loaded
XContainer::XArray<CKFileManagerData> m_ManagersData; // Manager Data loaded
XContainer::XArray<CKFilePluginDependencies> m_PluginsDep; // Plugins dependencies for this file
// XContainer::XClassArray<XContainer::XIntArray> m_IndexByClassId; // List of index in the m_FileObjects table sorted by ClassID
XContainer::XArray<XContainer::XString> m_IncludedFiles; // List of files that should be inserted in the CMO file.
CKFileInfo m_FileInfo; // Headers summary
//CKFileInfo m_FileInfo;
//CK_LOAD_FLAGS m_Flags;
//bool m_ReadFileDataDone;
//XContainer::XFileObjectsTable m_ObjectsHashTable;
//CKBOOL m_ReadFileDataDone;
//CKBOOL m_SceneSaved;
//XContainer::XIntArray m_DuplicateNameFounds; // A List of file object index for which a existing object with the same name has been
// // found, this list is build if the load option contains CK_LOAD_AUTOMATICMODE or CK_LOAD_DODIALOG
//XContainer::XBitArray m_AlreadySavedMask; // BitArray of IDs already saved {secret}
//XContainer::XBitArray m_AlreadyReferencedMask; // BitArray of IDs already referenced {secret}
//XContainer::XObjectPointerArray m_ReferencedObjects;
private:
// reader function and variables
CKERROR ReadFileHeader(CKBufferParser* ParserPtr, CKFileDocument* doc);
CKERROR ReadFileData(CKBufferParser* ParserPtr, CKFileDocument* doc);
CKERROR ReadFileHeader(CKBufferParser* ParserPtr);
CKERROR ReadFileData(CKBufferParser* ParserPtr);
// writer function and varibales
// shared function and variables
CKMinContext* m_MinCtx;
bool mCanLoad;
CKContext* m_Ctx;
};
}

150
LibCmo/CK2/CKFileOthers.cpp Normal file
View File

@ -0,0 +1,150 @@
#include "CKFile.hpp"
#include "CKStateChunk.hpp"
#include <cstdarg>
namespace LibCmo::CK2 {
#pragma region CKFileObject
// CKObject is managed by CKMinContext,
// so we do not considering its memory leak
// however, we need process CKStateChunk.
CKFileObject::CKFileObject() :
ObjectId(0u), CreatedObjectId(0u), ObjectCid(CK_CLASSID::CKCID_OBJECT),
ObjPtr(nullptr), Name(), Data(nullptr), Options(CK_FO_OPTIONS::CK_FO_DEFAULT),
FileIndex(0u), SaveFlags(0u) {}
CKFileObject::CKFileObject(const CKFileObject& rhs) :
ObjectId(rhs.ObjectId), CreatedObjectId(rhs.CreatedObjectId), ObjectCid(rhs.ObjectCid),
ObjPtr(rhs.ObjPtr), Name(rhs.Name), Data(rhs.Data), Options(rhs.Options),
FileIndex(rhs.FileIndex), SaveFlags(0u) {
if (this->Data != nullptr) {
this->Data = new CKStateChunk(*(rhs.Data));
}
}
CKFileObject::CKFileObject(CKFileObject&& rhs) :
ObjectId(rhs.ObjectId), CreatedObjectId(rhs.CreatedObjectId), ObjectCid(rhs.ObjectCid),
ObjPtr(rhs.ObjPtr), Name(rhs.Name), Data(rhs.Data), Options(rhs.Options),
FileIndex(rhs.FileIndex), SaveFlags(0u) {
rhs.Data = nullptr;
}
CKFileObject& CKFileObject::operator=(const CKFileObject& rhs) {
this->ObjectId = rhs.ObjectId;
this->CreatedObjectId = rhs.CreatedObjectId;
this->ObjectCid = rhs.ObjectCid;
this->ObjPtr = rhs.ObjPtr;
this->Name = rhs.Name;
this->Data = rhs.Data;
if (this->Data != nullptr) {
this->Data = new CKStateChunk(*(rhs.Data));
}
this->Options = rhs.Options;
this->FileIndex = rhs.FileIndex;
this->SaveFlags = rhs.SaveFlags;
return *this;
}
CKFileObject& CKFileObject::operator=(CKFileObject&& rhs) {
this->ObjectId = rhs.ObjectId;
this->CreatedObjectId = rhs.CreatedObjectId;
this->ObjectCid = rhs.ObjectCid;
this->ObjPtr = rhs.ObjPtr;
this->Name = rhs.Name;
this->Data = rhs.Data;
rhs.Data = nullptr;
this->Options = rhs.Options;
this->FileIndex = rhs.FileIndex;
this->SaveFlags = rhs.SaveFlags;
}
CKFileObject::~CKFileObject() {
if (Data != nullptr) delete Data;
}
#pragma endregion
#pragma region CKFileManagerData
CKFileManagerData::CKFileManagerData() :
Data(nullptr), Manager(0u, 0u) {}
CKFileManagerData::CKFileManagerData(const CKFileManagerData& rhs) :
Data(rhs.Data), Manager(rhs.Manager) {
if (this->Data != nullptr) {
this->Data = new CKStateChunk(*(rhs.Data));
}
}
CKFileManagerData::CKFileManagerData(CKFileManagerData&& rhs) :
Data(rhs.Data), Manager(rhs.Manager) {
rhs.Data = nullptr;
}
CKFileManagerData& CKFileManagerData::operator=(const CKFileManagerData& rhs) {
this->Manager = rhs.Manager;
this->Data = rhs.Data;
if (this->Data != nullptr) {
this->Data = new CKStateChunk(*(rhs.Data));
}
return *this;
}
CKFileManagerData& CKFileManagerData::operator=(CKFileManagerData&& rhs) {
this->Manager = rhs.Manager;
this->Data = rhs.Data;
rhs.Data = nullptr;
}
CKFileManagerData::~CKFileManagerData() {
if (Data != nullptr) delete Data;
}
#pragma endregion
#pragma region CKFilePluginDependencies
CKFilePluginDependencies::CKFilePluginDependencies() :
m_PluginCategory(CK_PLUGIN_TYPE::CKPLUGIN_MANAGER_DLL), m_Guids() {}
CKFilePluginDependencies::CKFilePluginDependencies(const CKFilePluginDependencies& rhs) :
m_PluginCategory(rhs.m_PluginCategory), m_Guids(rhs.m_Guids) {}
CKFilePluginDependencies& CKFilePluginDependencies::operator=(const CKFilePluginDependencies& rhs) {
this->m_PluginCategory = rhs.m_PluginCategory;
this->m_Guids = rhs.m_Guids;
return *this;
}
CKFilePluginDependencies::~CKFilePluginDependencies() {}
#pragma endregion
#pragma region CKFile Misc
CKFile::CKFile(CKContext* ctx) :
m_Ctx(ctx) {
;
}
CKFile::~CKFile() {}
#pragma endregion
}

View File

@ -1,9 +1,8 @@
#include "CKFile.hpp"
#include "CKGlobals.hpp"
#include "CKStateChunk.hpp"
#include "CKObjects.hpp"
#include "VxMemoryMappedFile.hpp"
#include "CKMinContext.hpp"
#include "CKObjectImplements/CKObject.hpp"
#include "../VxMath/VxMemoryMappedFile.hpp"
#include "CKContext.hpp"
#include <memory>
namespace LibCmo::CK2 {
@ -15,7 +14,7 @@ namespace LibCmo::CK2 {
* No need to support them.
*/
CKERROR CKFile::ShallowLoad(CKSTRING u8_filename, CKFileDocument** out_doc) {
CKERROR CKFile::ShallowLoad(CKSTRING u8_filename) {
// preset value
*out_doc = nullptr;

View File

@ -1,6 +1,6 @@
#include "CKFile.hpp"
namespace LibCmo {
namespace LibCmo::CK2 {

View File

@ -1,27 +1,21 @@
#include "../CKManagers.hpp"
#include "CKBaseManager.hpp"
namespace LibCmo::CK2::CKManagerImplements {
CKBaseManager::CKBaseManager(CKMinContext* ctx, CK_ID ckid) {
}
CKBaseManager::~CKBaseManager() {
}
CKERROR CKBaseManager::LoadData(CKStateChunk* statechunk, CKFileDocument* doc) {
return CKERROR::CKERR_OK;
}
CKStateChunk* CKBaseManager::SaveData(CKFileDocument* doc) {
return nullptr;
}
namespace LibCmo::CK2 {
// todo: this file maybe not used anymore. if more manager added. i think this file can be removed.
//CKERROR CKBaseManager::LoadData(CKStateChunk* statechunk, CKFileDocument* doc) {
// return CKERROR::CKERR_OK;
//}
//CKStateChunk* CKBaseManager::SaveData(CKFileDocument* doc) {
// return nullptr;
//}
CKAttributeManager::CKAttributeManager(CKMinContext* ctx, CK_ID ckid) : CKBaseManager(ctx, ckid) {
//CKAttributeManager::CKAttributeManager(CKMinContext* ctx, CK_ID ckid) : CKBaseManager(ctx, ckid) {
}
CKAttributeManager::~CKAttributeManager() {
//}
//CKAttributeManager::~CKAttributeManager() {
}
//}
}

View File

@ -1,33 +1,106 @@
#pragma once
#include "CKDefines.hpp"
#include "CKEnums.hpp"
#include "../../VTAll.hpp"
namespace LibCmo::CK2::CKManagerImplements {
namespace LibCmo::CK2 {
/**
@brief Base Class for managers.
@remark
+ This class provides virtual methods that can be override by any managers. Any manager that inherits from CKBaseManager can override function to do some processing.
+ The instances of managers may be retrieved through the global function CKContext::GetManagerByGuid()
+ Some default managers implemented in Virtools can be accessed directly: See Managers Access
*/
class CKBaseManager {
public:
CKBaseManager(CKContext* ctx, CK_ID ckid);
CKBaseManager(const CKBaseManager&) = delete;
CKBaseManager& operator=(const CKBaseManager&) = delete;
virtual ~CKBaseManager();
CKBaseManager(CKContext* ctx, CKGUID guid, CKSTRING name) :
m_ManagerGuid(guid),
m_ManagerName(name),
m_Context(ctx)
{}
virtual ~CKBaseManager() {}
LIBCMO_DISABLE_COPY_MOVE(CKBaseManager);
virtual CKERROR LoadData(CKStateChunk* statechunk, CKFileDocument* doc);
virtual CKStateChunk* SaveData(CKFileDocument* doc);
/**
@brief Acces to Manager GUID
@return CKGUID of this manager.
@remark
+ Each Manager is given an unique GUID. When creating a new manager it should
assign itself a GUID and name before registering itsef.
```
CKAttributeManager::CKAttributeManager(CKContext *Context) : CKBaseManager(Context, ATTRIBUTE_MANAGER_GUID, "Attribute Manager")
{
// ....
// ....
Context->RegisterNewManager(this);
}
```
@see CKContext::RegisterNewManager, GetName
*/
CKGUID GetGuid() {
return m_ManagerGuid;
}
/**
@brief Acces to Manager name
@return Name of this manager.
@remark
+ Each Manager is given an unique GUID. When creating a new manager it should
assign itself a GUID and name before registering itsef.
```
CKAttributeManager::CKAttributeManager(CKContext *Context) : CKBaseManager(Context, ATTRIBUTE_MANAGER_GUID, "Attribute Manager")
{
// ....
// ....
Context->RegisterNewManager(this);
}
```
*/
CKSTRING GetName() {
return m_ManagerName.c_str();
}
private:
/**
@brief Called to save manager data.
@param SavedFile A pointer to the CKFile being saved.
@return This function should return a valid CKStateChunk that contain data to save or NULL if there is nothing to save.
@remark
+ During a save operation, each manager is given the opportunity to save its data in the file.
+ The file being saved is given for information only and must not be modified. It can be used to decide whether it is worth saving
data for your manager.
@see CKStateChunk, LoadData
*/
virtual CKStateChunk* SaveData(CKFile* SavedFile) {
return nullptr;
}
/**
@brief Called to load manager data.
@param chunk A pointer to a CKStateChunk that was saved in the file.
@param LoadedFile A pointer to the CKFile being loaded.
@return CK_OK if successful or an error code otherwise.
@remark
+ During a load operation, each manager is automatically called if there was a chunk saved in the file with SaveData.
@see CKStateChunk, SaveData
*/
virtual CKERROR LoadData(CKStateChunk* chunk, CKFile* LoadedFile) {
return CKERROR::CKERR_OK;
}
protected:
CKGUID m_ManagerGuid; ///> Manager GUID
TypeHelper::MKString m_ManagerName; ///> Manager Name
CKContext* m_Context; ///> A pointer to the CKContext on which this manager is valid.
};
class CKAttributeManager : public CKBaseManager {
public:
CKAttributeManager(CKContext* ctx, CK_ID ckid);
CKAttributeManager(const CKAttributeManager&) = delete;
CKAttributeManager& operator=(const CKAttributeManager&) = delete;
virtual ~CKAttributeManager();
//class CKAttributeManager : public CKBaseManager {
//public:
// CKAttributeManager(CKContext* ctx, CK_ID ckid);
// CKAttributeManager(const CKAttributeManager&) = delete;
// CKAttributeManager& operator=(const CKAttributeManager&) = delete;
// virtual ~CKAttributeManager();
private:
//private:
};
//};
}

View File

@ -9,7 +9,7 @@ namespace LibCmo::CK2 {
public:
CKObject(CKContext* ctx, CK_ID ckid, CKSTRING name) :
m_ID(ckid),
m_HasName(name != nullptr ? CKTRUE : CKFALSE), m_Name(name != nullptr ? name : ""),
m_Name(name),
m_Context(ctx),
m_ObjectFlags(CK_OBJECT_FLAGS::CK_PARAMETERIN_DISABLED)
{}
@ -20,17 +20,10 @@ namespace LibCmo::CK2 {
return m_ID;
}
CKSTRING GetName(void) {
if (m_HasName) return m_Name.c_str();
else return nullptr;
return m_Name.c_str();
}
void SetName(CKSTRING u8_name) {
if (u8_name == nullptr) {
m_HasName = false;
m_Name.clear();
} else {
m_HasName = true;
m_Name = u8_name;
}
m_Name = u8_name;
}
CK_OBJECT_FLAGS GetObjectFlags(void) {
return m_ObjectFlags;
@ -53,8 +46,7 @@ namespace LibCmo::CK2 {
private:
CK_ID m_ID;
CKBOOL m_HasName;
std::string m_Name;
TypeHelper::MKString m_Name;
CK_OBJECT_FLAGS m_ObjectFlags;
CKContext* m_Context;
};

View File

@ -175,7 +175,7 @@
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="CK2\CKFile.cpp" />
<ClCompile Include="CK2\CKFileOthers.cpp" />
<ClCompile Include="CK2\CKFileWriter.cpp" />
<ClCompile Include="CK2\CKGlobals.cpp" />
<ClCompile Include="CK2\CKManagerImplements\CKBaseManager.cpp" />

View File

@ -60,7 +60,7 @@
<ClCompile Include="VxMath\VxMemoryMappedFile.cpp">
<Filter>Sources\VxMath</Filter>
</ClCompile>
<ClCompile Include="CK2\CKFile.cpp">
<ClCompile Include="CK2\CKFileOthers.cpp">
<Filter>Sources\CK2</Filter>
</ClCompile>
<ClCompile Include="CK2\CKFileReader.cpp">

View File

@ -2,9 +2,6 @@
namespace LibCmo {
void SystemPanic(const char* reason) {
}
namespace StreamHelper {
static constexpr const size_t CHUNK_SIZE = 10240;

View File

@ -48,6 +48,7 @@
#include <cinttypes>
#include <cstdint>
#include <initializer_list>
#include <string>
#pragma region Batch Ctor operator= Operations
@ -57,40 +58,97 @@
CLSNAME& operator=(const CLSNAME&) = delete; \
CLSNAME& operator=(CLSNAME&&) = delete;
#define LIBCMO_DEFAULT_COPY_MOVE(CLSNAME) \
CLSNAME(const CLSNAME&) = default; \
CLSNAME(CLSNAME&&) = default; \
CLSNAME& operator=(const CLSNAME&) = default; \
CLSNAME& operator=(CLSNAME&&) = default;
#pragma endregion
namespace LibCmo {
namespace EnumsHelper {
template<typename TEnum, std::enable_if_t<std::is_enum_v<TEnum>, int> = 0>
inline TEnum Merge(std::initializer_list<TEnum> il) {
std::underlying_type_t<TEnum> result = 0;
for (auto it = il.begin(); it != il.end(); ++it) {
result |= static_cast<std::underlying_type_t<TEnum>>(*it);
}
return static_cast<TEnum>(result);
}
namespace TypeHelper {
template<typename TEnum, std::enable_if_t<std::is_enum_v<TEnum>, int> = 0>
inline TEnum Inv(TEnum e) {
return static_cast<TEnum>(~(static_cast<std::underlying_type_t<TEnum>>(e)));
}
/**
* @brief HybridString is a compatible type.
* In some original Virtools case, we need CKSTRING to hold string.
* But CKSTRING is just a pointer and it is very cause memory leak.
* So I invent this. It like CKSTRING but will free memory automatically.
* And it is safe in CKSTRING copying.
* It operate like std::string. Have a function called c_str() to create usable CKSTRING.
* We call it as MKString. (memory-safe CKSTRING.) :pu: =.=
*/
class MKString {
public:
MKString() : m_HasStr(false), m_Str() {}
~MKString() {}
template<typename TEnum, std::enable_if_t<std::is_enum_v<TEnum>, int> = 0>
inline TEnum Rm(TEnum& e1, TEnum e2) {
e1 = static_cast<TEnum>(static_cast<std::underlying_type_t<TEnum>>(e1) & static_cast<std::underlying_type_t<TEnum>>(Inv(e2)));
}
MKString(const char* cstr) : m_HasStr(cstr != nullptr), m_Str(m_HasStr ? cstr : "") {}
MKString& operator=(const char* cstr) {
m_HasStr = cstr != nullptr;
m_Str = m_HasStr ? cstr : "";
}
MKString(const std::string& cstr) : m_HasStr(true), m_Str(cstr) {}
MKString& operator=(const std::string& cstr) {
m_HasStr = true;
m_Str = cstr;
}
template<typename TEnum, std::enable_if_t<std::is_enum_v<TEnum>, int> = 0>
inline TEnum Add(TEnum& e1, TEnum e2) {
e1 = static_cast<TEnum>(static_cast<std::underlying_type_t<TEnum>>(e1) | static_cast<std::underlying_type_t<TEnum>>(e2));
}
MKString(const MKString& rhs) : m_HasStr(rhs.m_HasStr), m_Str(rhs.m_Str) {}
MKString(MKString&& rhs) noexcept : m_HasStr(rhs.m_HasStr), m_Str(std::move(rhs.m_Str)) {
rhs.m_HasStr = false;
}
MKString& operator=(const MKString& rhs) {
m_HasStr = rhs.m_HasStr;
m_Str = rhs.m_Str;
}
MKString& operator=(MKString&& rhs) noexcept {
m_HasStr = rhs.m_HasStr;
m_Str = std::move(rhs.m_Str);
rhs.m_HasStr = false;
}
template<typename TEnum, std::enable_if_t<std::is_enum_v<TEnum>, int> = 0>
inline bool Has(TEnum e, TEnum probe) {
return static_cast<bool>(static_cast<std::underlying_type_t<TEnum>>(e) & static_cast<std::underlying_type_t<TEnum>>(probe));
}
}
const char* c_str() const {
return m_HasStr ? m_Str.c_str() : nullptr;
}
private:
bool m_HasStr;
std::string m_Str;
};
}
namespace EnumsHelper {
template<typename TEnum, std::enable_if_t<std::is_enum_v<TEnum>, int> = 0>
inline TEnum Merge(std::initializer_list<TEnum> il) {
std::underlying_type_t<TEnum> result = 0;
for (auto it = il.begin(); it != il.end(); ++it) {
result |= static_cast<std::underlying_type_t<TEnum>>(*it);
}
return static_cast<TEnum>(result);
}
template<typename TEnum, std::enable_if_t<std::is_enum_v<TEnum>, int> = 0>
inline TEnum Inv(TEnum e) {
return static_cast<TEnum>(~(static_cast<std::underlying_type_t<TEnum>>(e)));
}
template<typename TEnum, std::enable_if_t<std::is_enum_v<TEnum>, int> = 0>
inline TEnum Rm(TEnum& e1, TEnum e2) {
e1 = static_cast<TEnum>(static_cast<std::underlying_type_t<TEnum>>(e1) & static_cast<std::underlying_type_t<TEnum>>(Inv(e2)));
}
template<typename TEnum, std::enable_if_t<std::is_enum_v<TEnum>, int> = 0>
inline TEnum Add(TEnum& e1, TEnum e2) {
e1 = static_cast<TEnum>(static_cast<std::underlying_type_t<TEnum>>(e1) | static_cast<std::underlying_type_t<TEnum>>(e2));
}
template<typename TEnum, std::enable_if_t<std::is_enum_v<TEnum>, int> = 0>
inline bool Has(TEnum e, TEnum probe) {
return static_cast<bool>(static_cast<std::underlying_type_t<TEnum>>(e) & static_cast<std::underlying_type_t<TEnum>>(probe));
}
}
namespace StreamHelper {

View File

@ -28,43 +28,22 @@ namespace LibCmo::XContainer {
/**
@brief Class representation of an array.
@tparam T Element Type.
@remark This class now use std::vector<T>.
@see XClassArray, XSArray
@remark
+ This class now use std::vector<T>.
+ XSArray, XClassArray now redirect to this.
*/
template<typename T>
using XArray = std::vector<T>;
/**
@brief Class representation of an array.
@tparam T Element Type.
@details Equivalent to XArray becasue memory reducing is useless.
@see XArray
*/
template<typename T>
using XSArray = XArray<T>;
/**
@brief Class representation of an array.
@tparam T Element Type.
@details Equivalent to XArray because std::vector<T> can fufill the requirements.
@see XArray
*/
template<typename T>
using XClassArray = XArray<T>;
/**
@brief Container class for CKObject Id's.
@remark
+ This class use the template container XArray to contain object CK_ID's.
+ Supports for Check, Load, Save, Add, Remove, Find functions in the Object CK_ID array.
+ XSObjectArray now redirect to this.
@todo May independ this class to implement the functions introduced in remarks.
@see XObjectPointerArray, CKObjectArray
*/
using XObjectArray = XArray<CK2::CK_ID>;
/**
@brief Container class for CKObject Id's
@details Equivalent to XObjectArray becasue memory reducing is useless.
@see XObjectArray
*/
using XSObjectArray = XObjectArray;
/**
@brief Container class for CKObject pointers.
@ -72,15 +51,11 @@ namespace LibCmo::XContainer {
+ Exactly same as XObjectArray class, but uses XArray (Pre-allocated items)
for storing pointers, and not IDs (more efficient to retrieve the objects).
+ Supports for Check, Load, Save, Add, Remove, Find functions in the CKObject Pointer array.
+ XSObjectPointerArray now redirect to this.
@todo May independ this class to implement the functions introduced in remarks.
@see XObjectArray, CKObjectArray
*/
using XObjectPointerArray = XArray<CK2::CKObject*>;
/**
@brief Container class for CKObject pointers.
@details Equivalent to XObjectPointerArray becasue memory reducing is useless.s
*/
using XSObjectPointerArray = XObjectPointerArray;
/**
@brief Class representation of an Hash Table container.
@ -88,24 +63,12 @@ namespace LibCmo::XContainer {
@tparam T The type of element to insert
@tparam H The hash function to hash the key
@tparam Eq The equal function to the key
@remark This class now use std::unordered_map<T>.
@remark
+ This class now use std::unordered_map<T>.
+ XNHashTable, XSHashTable now redirect to this.
*/
template<class K, class T, class H = std::hash<K>, class Eq = std::equal_to<K>>
using XHashTable = std::unordered_map<K, T, H, Eq>;
/**
@copydoc XHashTable
@details Equivalent to XHashTable
@see XHashTable
*/
template<class K, class T, class H = std::hash<K>, class Eq = std::equal_to<K>>
using XNHashTable = XHashTable<K, T, H, Eq>;
/**
@copydoc XHashTable
@details Equivalent to XHashTable because static allocation is useless.
@see XHashTable
*/
template<class K, class T, class H = std::hash<K>, class Eq = std::equal_to<K>>
using XSHashTable = XHashTable<K, T, H, Eq>;
}