write shit
This commit is contained in:
		| @ -38,6 +38,9 @@ namespace LibCmo::CK2 { | |||||||
|  |  | ||||||
| 		// put into slot | 		// put into slot | ||||||
| 		m_ObjectsList[decided_id] = obj; | 		m_ObjectsList[decided_id] = obj; | ||||||
|  | 		 | ||||||
|  | 		// set out variable | ||||||
|  | 		return obj; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	CKObject* CKContext::GetCKObject(CK_ID id) { | 	CKObject* CKContext::GetCKObject(CK_ID id) { | ||||||
|  | |||||||
| @ -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 |  | ||||||
|  |  | ||||||
|  |  | ||||||
| } |  | ||||||
| @ -1,7 +1,11 @@ | |||||||
| #pragma once | #pragma once | ||||||
|  |  | ||||||
| #include "CKDefines.hpp" | #include "../VTAll.hpp" | ||||||
| #include "CKEnums.hpp" |  | ||||||
|  | namespace LibCmo::XContainer { | ||||||
|  | 	using XIntArray = XArray<CK2::CKINT>; | ||||||
|  | 	using XFileObjectsTable = XHashTable<CK2::CK_ID, CK2::CKINT>; | ||||||
|  | } | ||||||
|  |  | ||||||
| namespace LibCmo::CK2 { | namespace LibCmo::CK2 { | ||||||
|  |  | ||||||
| @ -13,25 +17,31 @@ namespace LibCmo::CK2 { | |||||||
| 		size_t m_MemSize; | 		size_t m_MemSize; | ||||||
|  |  | ||||||
| 	public: | 	public: | ||||||
| 		CKBufferParser(void* ptr, size_t rsize, bool need_manual_free); | 		CKBufferParser(void* ptr, size_t rsize, bool need_manual_free) : | ||||||
| 		CKBufferParser(const CKBufferParser&) = delete; | 			m_MemBegin(static_cast<char*>(ptr)), | ||||||
| 		CKBufferParser& operator=(const CKBufferParser&) = delete; | 			m_MemPos(0u), m_MemSize(rsize), | ||||||
| 		~CKBufferParser(); | 			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); } | 		const void* GetPtr(void) { return (this->m_MemBegin + m_MemPos); } | ||||||
| 		inline void Read(void* data, size_t data_size) { | 		void Read(void* data, size_t data_size) { | ||||||
| 			std::memcpy(data, (this->m_MemBegin + m_MemPos), data_size); | 			std::memcpy(data, (this->m_MemBegin + m_MemPos), data_size); | ||||||
| 			this->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); | 			std::memcpy((this->m_MemBegin + m_MemPos), data, data_size); | ||||||
| 			this->m_MemPos += data_size; | 			this->m_MemPos += data_size; | ||||||
| 		} | 		} | ||||||
| 		inline void* GetBase(void) { return this->m_MemBegin; } | 		void* GetBase(void) { return this->m_MemBegin; } | ||||||
| 		inline size_t GetSize(void) { return this->m_MemSize; } | 		size_t GetSize(void) { return this->m_MemSize; } | ||||||
| 		inline size_t GetCursor(void) { return this->m_MemPos; } | 		size_t GetCursor(void) { return this->m_MemPos; } | ||||||
| 		inline void MoveCursor(size_t off) { this->m_MemPos += off; } | 		void MoveCursor(size_t off) { this->m_MemPos += off; } | ||||||
| 		inline void SetCursor(size_t off) { this->m_MemPos = off; } | 		void SetCursor(size_t off) { this->m_MemPos = off; } | ||||||
| 	}; | 	}; | ||||||
|  |  | ||||||
| #pragma pack(push) | #pragma pack(push) | ||||||
| @ -58,104 +68,110 @@ namespace LibCmo::CK2 { | |||||||
|  |  | ||||||
| 	class CKFileInfo { | 	class CKFileInfo { | ||||||
| 	public: | 	public: | ||||||
| 		CKFileInfo(); | 		CKFileInfo() : | ||||||
| 		CKFileInfo(const CKFileInfo&); | 			ProductVersion(0u), ProductBuild(0x01010000u), FileWriteMode(CK_FILE_WRITEMODE::CKFILE_UNCOMPRESSED), | ||||||
| 		CKFileInfo& operator=(const CKFileInfo&); | 			FileVersion(8u), CKVersion(CKVERSION), FileSize(0u), | ||||||
| 		~CKFileInfo(); | 			ObjectCount(0u), ManagerCount(0u), MaxIDSaved(0u), Crc(0u), | ||||||
|  | 			Hdr1PackSize(0u), Hdr1UnPackSize(0u), DataPackSize(0u), DataUnPackSize(0u) {} | ||||||
| 		CKDWORD ProductVersion;		// Virtools Version (Dev/Creation). (CK_VIRTOOLS_VERSION) | 		~CKFileInfo() {} | ||||||
| 		CKDWORD ProductBuild;		// Virtools Build Number. | 		LIBCMO_DEFAULT_COPY_MOVE(CKFileInfo); | ||||||
| 		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: |  | ||||||
|  |  | ||||||
|  | 		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 { | 	class CKFileObject { | ||||||
| 	public: | 	public: | ||||||
| 		CKFileObject(); | 		CKFileObject(); | ||||||
| 		CKFileObject(const CKFileObject&); | 		CKFileObject(const CKFileObject&); | ||||||
|  | 		CKFileObject(CKFileObject&&); | ||||||
| 		CKFileObject& operator=(const CKFileObject&); | 		CKFileObject& operator=(const CKFileObject&); | ||||||
|  | 		CKFileObject& operator=(CKFileObject&&); | ||||||
| 		~CKFileObject(); | 		~CKFileObject(); | ||||||
|  |  | ||||||
| 		CK_ID ObjectId;							// ID of the object being load/saved (as it will be/was saved in the file) | 		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_ID CreatedObjectId; ///< ID of the object being created | ||||||
| 		CK_CLASSID ObjectCid;					// Class Identifier of the object | 		CK_CLASSID ObjectCid; ///< Class Identifier of the object | ||||||
| 		CKObjectImplements::CKObject* ObjPtr;	// A pointer to the object itself (as CreatedObject when loading) | 		CKObject* ObjPtr; ///< A pointer to the object itself (as CreatedObject when loading) | ||||||
| 		std::string Name;						// Name of the Object | 		TypeHelper::MKString Name; ///< Name of the Object | ||||||
| 		CKStateChunk* Data;						// A CKStateChunk that contains object information | 		CKStateChunk* Data; ///< A CKStateChunk that contains object information | ||||||
| 		CKDWORD FileIndex;						// Position of the object data inside uncompressed file buffer | 		//CKINT PostPackSize; ///< When compressed chunk by chunk : size of Data after compression | ||||||
| 	private: | 		//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 { | 	class CKFileManagerData { | ||||||
| 	public: | 	public: | ||||||
| 		CKFileManagerData(); | 		CKFileManagerData(); | ||||||
| 		CKFileManagerData(const CKFileManagerData&); | 		CKFileManagerData(const CKFileManagerData&); | ||||||
|  | 		CKFileManagerData(CKFileManagerData&&); | ||||||
| 		CKFileManagerData& operator=(const CKFileManagerData&); | 		CKFileManagerData& operator=(const CKFileManagerData&); | ||||||
|  | 		CKFileManagerData& operator=(CKFileManagerData&&); | ||||||
| 		~CKFileManagerData(); | 		~CKFileManagerData(); | ||||||
|  |  | ||||||
| 		CKManagerImplements::CKBaseManager* MgrPtr; |  | ||||||
| 		CKStateChunk* Data; | 		CKStateChunk* Data; | ||||||
| 		CKGUID Manager; | 		CKGUID Manager; | ||||||
| 	private: |  | ||||||
|  |  | ||||||
| 	}; | 	}; | ||||||
|  |  | ||||||
| 	class CKFilePluginDependencies { | 	class CKFilePluginDependencies { | ||||||
| 	public: | 	public: | ||||||
| 		CKFilePluginDependencies(); | 		CKFilePluginDependencies() : | ||||||
| 		CKFilePluginDependencies(const CKFilePluginDependencies&); | 			m_PluginCategory(CK_PLUGIN_TYPE::CKPLUGIN_MANAGER_DLL), m_Guids() {} | ||||||
| 		CKFilePluginDependencies& operator=(const CKFilePluginDependencies&); | 		~CKFilePluginDependencies() {} | ||||||
| 		~CKFilePluginDependencies(); | 		LIBCMO_DEFAULT_COPY_MOVE(CKFilePluginDependencies); | ||||||
|  |  | ||||||
| 		CK_PLUGIN_TYPE m_PluginCategory; | 		CK_PLUGIN_TYPE m_PluginCategory; | ||||||
| 		XArray<CKGUID> m_Guids; | 		XContainer::XArray<CKGUID> m_Guids; | ||||||
| 	private: | 		XContainer::XBitArray ValidGuids; | ||||||
|  |  | ||||||
| 	}; |  | ||||||
|  |  | ||||||
| 	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: |  | ||||||
|  |  | ||||||
| 	}; | 	}; | ||||||
|  |  | ||||||
|  | 	/** | ||||||
|  | 	@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 { | 	class CKFile { | ||||||
| 	public: | 	public: | ||||||
| 		CKFile(CKMinContext* ctx); | 		CKFile(CKContext* ctx); | ||||||
| 		CKFile(const CKFile&) = delete; |  | ||||||
| 		CKFile& operator=(const CKFile&) = delete; |  | ||||||
| 		~CKFile(); | 		~CKFile(); | ||||||
|  | 		LIBCMO_DISABLE_COPY_MOVE(CKFile); | ||||||
|  |  | ||||||
|  | 		// ========== Reset CKFile ========== | ||||||
| 		void ClearData(void); | 		void ClearData(void); | ||||||
|  |  | ||||||
| 		CKERROR ShallowLoad(CKSTRING u8_filename, CKFileDocument** out_doc); | 		// ========== Loading ========== | ||||||
| 		CKERROR DeepLoad(CKSTRING u8_filename, CKFileDocument** out_doc); | 		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 Load(CKSTRING u8_filename, /*CKObjectArray list, */ CK_LOAD_FLAGS flags); | ||||||
| 		//CKERROR OpenFile(CKSTRING u8_filename, 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 LoadFileData(void/*CKObjectArray list*/); | ||||||
| 		//CKERROR FinishLoading(/*CKObjectArray list, */CK_LOAD_FLAGS flags); | 		//CKERROR FinishLoading(/*CKObjectArray list, */CK_LOAD_FLAGS flags); | ||||||
|  |  | ||||||
| 		//int32_t m_SaveIDMax; | 		CKINT m_SaveIDMax; // Maximum CK_ID found when saving or loading objects | ||||||
| 		//XArray<CKFileObject> m_FileObject; | 		XContainer::XArray<CKFileObject> m_FileObjects; // List of objects being saved / loaded | ||||||
| 		//XArray<CKFileManagerData> m_ManagersData; | 		XContainer::XArray<CKFileManagerData> m_ManagersData; // Manager Data loaded | ||||||
| 		//XClassArray<CKFilePluginDependencies> m_PluginDep; | 		XContainer::XArray<CKFilePluginDependencies> m_PluginsDep;	// Plugins dependencies for this file | ||||||
| 		//XClassArray<XIntArray> m_IndexByClassId; | 		// XContainer::XClassArray<XContainer::XIntArray> m_IndexByClassId; // List of index in the m_FileObjects table sorted by ClassID | ||||||
| 		//XClassArray<XString> m_IncludedFiles; | 		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; | 		//XContainer::XFileObjectsTable m_ObjectsHashTable; | ||||||
|  | 		//CKBOOL m_ReadFileDataDone; | ||||||
| 		//CK_LOAD_FLAGS m_Flags; | 		//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 | ||||||
| 		//bool m_ReadFileDataDone; | 		//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: | 	private: | ||||||
| 		// reader function and variables | 		// reader function and variables | ||||||
| 		CKERROR ReadFileHeader(CKBufferParser* ParserPtr, CKFileDocument* doc); | 		CKERROR ReadFileHeader(CKBufferParser* ParserPtr); | ||||||
| 		CKERROR ReadFileData(CKBufferParser* ParserPtr, CKFileDocument* doc); | 		CKERROR ReadFileData(CKBufferParser* ParserPtr); | ||||||
|  |  | ||||||
| 		// writer function and varibales | 		// writer function and varibales | ||||||
|  |  | ||||||
| 		// shared function and variables | 		// shared function and variables | ||||||
| 		CKMinContext* m_MinCtx; | 		bool mCanLoad; | ||||||
|  | 		CKContext* m_Ctx; | ||||||
| 	}; | 	}; | ||||||
|  |  | ||||||
| } | } | ||||||
|  | |||||||
							
								
								
									
										150
									
								
								LibCmo/CK2/CKFileOthers.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										150
									
								
								LibCmo/CK2/CKFileOthers.cpp
									
									
									
									
									
										Normal 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 | ||||||
|  |  | ||||||
|  |  | ||||||
|  | } | ||||||
| @ -1,9 +1,8 @@ | |||||||
| #include "CKFile.hpp" | #include "CKFile.hpp" | ||||||
| #include "CKGlobals.hpp" |  | ||||||
| #include "CKStateChunk.hpp" | #include "CKStateChunk.hpp" | ||||||
| #include "CKObjects.hpp" | #include "CKObjectImplements/CKObject.hpp" | ||||||
| #include "VxMemoryMappedFile.hpp" | #include "../VxMath/VxMemoryMappedFile.hpp" | ||||||
| #include "CKMinContext.hpp" | #include "CKContext.hpp" | ||||||
| #include <memory> | #include <memory> | ||||||
|  |  | ||||||
| namespace LibCmo::CK2 { | namespace LibCmo::CK2 { | ||||||
| @ -15,7 +14,7 @@ namespace LibCmo::CK2 { | |||||||
| 	* No need to support them. | 	* No need to support them. | ||||||
| 	*/ | 	*/ | ||||||
|  |  | ||||||
| 	CKERROR CKFile::ShallowLoad(CKSTRING u8_filename, CKFileDocument** out_doc) { | 	CKERROR CKFile::ShallowLoad(CKSTRING u8_filename) { | ||||||
| 		// preset value | 		// preset value | ||||||
| 		*out_doc = nullptr; | 		*out_doc = nullptr; | ||||||
|  |  | ||||||
|  | |||||||
| @ -1,6 +1,6 @@ | |||||||
| #include "CKFile.hpp" | #include "CKFile.hpp" | ||||||
|  |  | ||||||
| namespace LibCmo { | namespace LibCmo::CK2 { | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  | |||||||
| @ -1,27 +1,21 @@ | |||||||
| #include "../CKManagers.hpp" | #include "CKBaseManager.hpp" | ||||||
|  |  | ||||||
| namespace LibCmo::CK2::CKManagerImplements { | namespace LibCmo::CK2 { | ||||||
|  | 	// todo: this file maybe not used anymore. if more manager added. i think this file can be removed. | ||||||
| 	CKBaseManager::CKBaseManager(CKMinContext* ctx, CK_ID ckid) { | 	 | ||||||
|  | 	//CKERROR CKBaseManager::LoadData(CKStateChunk* statechunk, CKFileDocument* doc) { | ||||||
| 	} | 	//	return CKERROR::CKERR_OK; | ||||||
| 	CKBaseManager::~CKBaseManager() { | 	//} | ||||||
|  | 	//CKStateChunk* CKBaseManager::SaveData(CKFileDocument* doc) { | ||||||
| 	} | 	//	return nullptr; | ||||||
|  | 	//} | ||||||
| 	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() { | ||||||
|  |  | ||||||
| 	} | 	//} | ||||||
|  |  | ||||||
| } | } | ||||||
|  | |||||||
| @ -1,33 +1,106 @@ | |||||||
| #pragma once | #pragma once | ||||||
|  |  | ||||||
| #include "CKDefines.hpp" | #include "../../VTAll.hpp" | ||||||
| #include "CKEnums.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 { | 	class CKBaseManager { | ||||||
| 	public: | 	public: | ||||||
| 		CKBaseManager(CKContext* ctx, CK_ID ckid); | 		CKBaseManager(CKContext* ctx, CKGUID guid, CKSTRING name) : | ||||||
| 		CKBaseManager(const CKBaseManager&) = delete; | 			m_ManagerGuid(guid), | ||||||
| 		CKBaseManager& operator=(const CKBaseManager&) = delete; | 			m_ManagerName(name), | ||||||
| 		virtual ~CKBaseManager(); | 			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 { | 	//class CKAttributeManager : public CKBaseManager { | ||||||
| 	public: | 	//public: | ||||||
| 		CKAttributeManager(CKContext* ctx, CK_ID ckid); | 	//	CKAttributeManager(CKContext* ctx, CK_ID ckid); | ||||||
| 		CKAttributeManager(const CKAttributeManager&) = delete; | 	//	CKAttributeManager(const CKAttributeManager&) = delete; | ||||||
| 		CKAttributeManager& operator=(const CKAttributeManager&) = delete; | 	//	CKAttributeManager& operator=(const CKAttributeManager&) = delete; | ||||||
| 		virtual ~CKAttributeManager(); | 	//	virtual ~CKAttributeManager(); | ||||||
|  |  | ||||||
| 	private: | 	//private: | ||||||
|  |  | ||||||
| 	}; | 	//}; | ||||||
|  |  | ||||||
| } | } | ||||||
|  | |||||||
| @ -9,7 +9,7 @@ namespace LibCmo::CK2 { | |||||||
| 	public: | 	public: | ||||||
| 		CKObject(CKContext* ctx, CK_ID ckid, CKSTRING name) : | 		CKObject(CKContext* ctx, CK_ID ckid, CKSTRING name) : | ||||||
| 			m_ID(ckid), | 			m_ID(ckid), | ||||||
| 			m_HasName(name != nullptr ? CKTRUE : CKFALSE), m_Name(name != nullptr ? name : ""), | 			m_Name(name), | ||||||
| 			m_Context(ctx), | 			m_Context(ctx), | ||||||
| 			m_ObjectFlags(CK_OBJECT_FLAGS::CK_PARAMETERIN_DISABLED) | 			m_ObjectFlags(CK_OBJECT_FLAGS::CK_PARAMETERIN_DISABLED) | ||||||
| 		{} | 		{} | ||||||
| @ -20,17 +20,10 @@ namespace LibCmo::CK2 { | |||||||
| 			return m_ID; | 			return m_ID; | ||||||
| 		} | 		} | ||||||
| 		CKSTRING GetName(void) { | 		CKSTRING GetName(void) { | ||||||
| 			if (m_HasName) return m_Name.c_str(); | 			return m_Name.c_str(); | ||||||
| 			else return nullptr; |  | ||||||
| 		} | 		} | ||||||
| 		void SetName(CKSTRING u8_name) { | 		void SetName(CKSTRING u8_name) { | ||||||
| 			if (u8_name == nullptr) { | 			m_Name = u8_name; | ||||||
| 				m_HasName = false; |  | ||||||
| 				m_Name.clear(); |  | ||||||
| 			} else { |  | ||||||
| 				m_HasName = true; |  | ||||||
| 				m_Name = u8_name; |  | ||||||
| 			} |  | ||||||
| 		} | 		} | ||||||
| 		CK_OBJECT_FLAGS GetObjectFlags(void) { | 		CK_OBJECT_FLAGS GetObjectFlags(void) { | ||||||
| 			return m_ObjectFlags; | 			return m_ObjectFlags; | ||||||
| @ -53,8 +46,7 @@ namespace LibCmo::CK2 { | |||||||
|  |  | ||||||
| 	private: | 	private: | ||||||
| 		CK_ID m_ID; | 		CK_ID m_ID; | ||||||
| 		CKBOOL m_HasName; | 		TypeHelper::MKString m_Name; | ||||||
| 		std::string m_Name; |  | ||||||
| 		CK_OBJECT_FLAGS m_ObjectFlags; | 		CK_OBJECT_FLAGS m_ObjectFlags; | ||||||
| 		CKContext* m_Context; | 		CKContext* m_Context; | ||||||
| 	}; | 	}; | ||||||
|  | |||||||
| @ -175,7 +175,7 @@ | |||||||
|     </Link> |     </Link> | ||||||
|   </ItemDefinitionGroup> |   </ItemDefinitionGroup> | ||||||
|   <ItemGroup> |   <ItemGroup> | ||||||
|     <ClCompile Include="CK2\CKFile.cpp" /> |     <ClCompile Include="CK2\CKFileOthers.cpp" /> | ||||||
|     <ClCompile Include="CK2\CKFileWriter.cpp" /> |     <ClCompile Include="CK2\CKFileWriter.cpp" /> | ||||||
|     <ClCompile Include="CK2\CKGlobals.cpp" /> |     <ClCompile Include="CK2\CKGlobals.cpp" /> | ||||||
|     <ClCompile Include="CK2\CKManagerImplements\CKBaseManager.cpp" /> |     <ClCompile Include="CK2\CKManagerImplements\CKBaseManager.cpp" /> | ||||||
|  | |||||||
| @ -60,7 +60,7 @@ | |||||||
|     <ClCompile Include="VxMath\VxMemoryMappedFile.cpp"> |     <ClCompile Include="VxMath\VxMemoryMappedFile.cpp"> | ||||||
|       <Filter>Sources\VxMath</Filter> |       <Filter>Sources\VxMath</Filter> | ||||||
|     </ClCompile> |     </ClCompile> | ||||||
|     <ClCompile Include="CK2\CKFile.cpp"> |     <ClCompile Include="CK2\CKFileOthers.cpp"> | ||||||
|       <Filter>Sources\CK2</Filter> |       <Filter>Sources\CK2</Filter> | ||||||
|     </ClCompile> |     </ClCompile> | ||||||
|     <ClCompile Include="CK2\CKFileReader.cpp"> |     <ClCompile Include="CK2\CKFileReader.cpp"> | ||||||
|  | |||||||
| @ -2,9 +2,6 @@ | |||||||
|  |  | ||||||
| namespace LibCmo { | namespace LibCmo { | ||||||
|  |  | ||||||
| 	void SystemPanic(const char* reason) { |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	namespace StreamHelper { | 	namespace StreamHelper { | ||||||
|  |  | ||||||
| 		static constexpr const size_t CHUNK_SIZE = 10240; | 		static constexpr const size_t CHUNK_SIZE = 10240; | ||||||
|  | |||||||
| @ -48,6 +48,7 @@ | |||||||
| #include <cinttypes> | #include <cinttypes> | ||||||
| #include <cstdint> | #include <cstdint> | ||||||
| #include <initializer_list> | #include <initializer_list> | ||||||
|  | #include <string> | ||||||
|  |  | ||||||
| #pragma region Batch Ctor operator= Operations | #pragma region Batch Ctor operator= Operations | ||||||
|  |  | ||||||
| @ -57,40 +58,97 @@ | |||||||
|     CLSNAME& operator=(const CLSNAME&) = delete; \ |     CLSNAME& operator=(const CLSNAME&) = delete; \ | ||||||
|     CLSNAME& operator=(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 | #pragma endregion | ||||||
|  |  | ||||||
| namespace LibCmo { | namespace LibCmo { | ||||||
|  |  | ||||||
|     namespace EnumsHelper { | 	namespace TypeHelper { | ||||||
|         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) { | 		 * @brief HybridString is a compatible type. | ||||||
|             return static_cast<TEnum>(~(static_cast<std::underlying_type_t<TEnum>>(e))); | 		 * 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> | 			MKString(const char* cstr) : m_HasStr(cstr != nullptr), m_Str(m_HasStr ? cstr : "") {} | ||||||
|         inline TEnum Rm(TEnum& e1, TEnum e2) { | 			MKString& operator=(const char* cstr) { | ||||||
|             e1 = static_cast<TEnum>(static_cast<std::underlying_type_t<TEnum>>(e1) & static_cast<std::underlying_type_t<TEnum>>(Inv(e2))); | 				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> | 			MKString(const MKString& rhs) : m_HasStr(rhs.m_HasStr), m_Str(rhs.m_Str) {} | ||||||
|         inline TEnum Add(TEnum& e1, TEnum e2) { | 			MKString(MKString&& rhs) noexcept : m_HasStr(rhs.m_HasStr), m_Str(std::move(rhs.m_Str)) { | ||||||
|             e1 = static_cast<TEnum>(static_cast<std::underlying_type_t<TEnum>>(e1) | static_cast<std::underlying_type_t<TEnum>>(e2)); | 				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> | 			const char* c_str() const { | ||||||
|         inline bool Has(TEnum e, TEnum probe) { | 				return m_HasStr ? m_Str.c_str() : nullptr; | ||||||
|             return static_cast<bool>(static_cast<std::underlying_type_t<TEnum>>(e) & static_cast<std::underlying_type_t<TEnum>>(probe)); | 			} | ||||||
|         } | 		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 { | 	namespace StreamHelper { | ||||||
|  |  | ||||||
|  | |||||||
| @ -28,43 +28,22 @@ namespace LibCmo::XContainer { | |||||||
| 	/** | 	/** | ||||||
| 	@brief Class representation of an array. | 	@brief Class representation of an array. | ||||||
| 	@tparam T Element Type. | 	@tparam T Element Type. | ||||||
| 	@remark This class now use std::vector<T>. | 	@remark  | ||||||
| 	@see XClassArray, XSArray | 	+ This class now use std::vector<T>. | ||||||
|  | 	+ XSArray, XClassArray now redirect to this. | ||||||
| 	*/ | 	*/ | ||||||
| 	template<typename T> | 	template<typename T> | ||||||
| 	using XArray = std::vector<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. | 	@brief Container class for CKObject Id's. | ||||||
| 	@remark | 	@remark | ||||||
| 	+ This class use the template container XArray to contain object CK_ID's. | 	+ 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. | 	+ 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. | 	@todo May independ this class to implement the functions introduced in remarks. | ||||||
| 	@see XObjectPointerArray, CKObjectArray |  | ||||||
| 	*/ | 	*/ | ||||||
| 	using XObjectArray = XArray<CK2::CK_ID>; | 	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. | 	@brief Container class for CKObject pointers. | ||||||
| @ -72,15 +51,11 @@ namespace LibCmo::XContainer { | |||||||
| 	+ Exactly same as XObjectArray class, but uses XArray (Pre-allocated items) | 	+ Exactly same as XObjectArray class, but uses XArray (Pre-allocated items) | ||||||
| 	for storing pointers, and not IDs (more efficient to retrieve the objects). | 	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. | 	+ 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. | 	@todo May independ this class to implement the functions introduced in remarks. | ||||||
| 	@see XObjectArray, CKObjectArray | 	@see XObjectArray, CKObjectArray | ||||||
| 	*/ | 	*/ | ||||||
| 	using XObjectPointerArray = XArray<CK2::CKObject*>; | 	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. | 	@brief Class representation of an Hash Table container. | ||||||
| @ -88,24 +63,12 @@ namespace LibCmo::XContainer { | |||||||
| 	@tparam T The type of element to insert | 	@tparam T The type of element to insert | ||||||
| 	@tparam H The hash function to hash the key | 	@tparam H The hash function to hash the key | ||||||
| 	@tparam Eq The equal function to 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>> | 	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>; | 	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>; |  | ||||||
|  |  | ||||||
|  |  | ||||||
| } | } | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user