finish ckgroup again

This commit is contained in:
yyc12345 2023-09-01 13:27:46 +08:00
parent fd69914a25
commit eea15c2028
8 changed files with 117 additions and 63 deletions

View File

@ -36,7 +36,7 @@ namespace LibCmo::CK2 {
#pragma region Objects Management
ObjImpls::CKObject* CKContext::CreateCKObject(CK_CLASSID cls, CKSTRING name,
ObjImpls::CKObject* CKContext::CreateObject(CK_CLASSID cls, CKSTRING name,
CK_OBJECTCREATION_OPTIONS options, CK_CREATIONMODE* res) {
// todo: Process paramter options and res
@ -66,13 +66,13 @@ namespace LibCmo::CK2 {
return obj;
}
ObjImpls::CKObject* CKContext::GetCKObject(CK_ID id) {
ObjImpls::CKObject* CKContext::GetObject(CK_ID id) {
if (id >= m_ObjectsList.size()) return nullptr;
return m_ObjectsList[id];
}
/**
* @brief The real CKObject destroy worker shared by CKContext::DestroyCKObject and CKContext::~CKContext
* @brief The real CKObject destroy worker shared by CKContext::DestroyObject and CKContext::~CKContext
* @param[in] ctx The CKContext
* @param[in] obj The CKObject need to be free.
*/
@ -88,7 +88,7 @@ namespace LibCmo::CK2 {
// free it and return its value
desc->ReleaseFct(ctx, obj);
}
void CKContext::DestroyCKObject(CK_ID id) {
void CKContext::DestroyObject(CK_ID id) {
if (id >= m_ObjectsList.size()) return;
// get object and free it

View File

@ -37,11 +37,11 @@ namespace LibCmo::CK2 {
* @remark CKObjects must be destroy with the DestroyObject method.
* @see CKObject, DestroyObject
*/
ObjImpls::CKObject* CreateCKObject(CK_CLASSID cls, CKSTRING name,
ObjImpls::CKObject* CreateObject(CK_CLASSID cls, CKSTRING name,
CK_OBJECTCREATION_OPTIONS options = CK_OBJECTCREATION_OPTIONS::CK_OBJECTCREATION_NONAMECHECK,
CK_CREATIONMODE* res = nullptr);
ObjImpls::CKObject* GetCKObject(CK_ID id);
void DestroyCKObject(CK_ID id);
ObjImpls::CKObject* GetObject(CK_ID id);
void DestroyObject(CK_ID id);
CKDWORD AllocateGroupGlobalIndex();
CKDWORD AllocateSceneGlobalIndex();

View File

@ -348,7 +348,7 @@ namespace LibCmo::CK2 {
if (obj.Data == nullptr) continue;
// create object and assign created obj ckid
obj.ObjPtr = m_Ctx->CreateCKObject(obj.ObjectCid, obj.Name.c_str());
obj.ObjPtr = m_Ctx->CreateObject(obj.ObjectCid, obj.Name.c_str());
if (obj.ObjPtr == nullptr) {
obj.CreatedObjectId = 0u;
} else {
@ -378,7 +378,7 @@ namespace LibCmo::CK2 {
obj.Data = nullptr;
} else {
// if failed, delete it
m_Ctx->DestroyCKObject(obj.ObjectId);
m_Ctx->DestroyObject(obj.ObjectId);
obj.ObjPtr = nullptr;
obj.CreatedObjectId = 0u;
}

View File

@ -111,23 +111,21 @@ namespace LibCmo::CK2 {
#pragma region Misc Funcs
const ChunkProfile CKStateChunk::GetStateChunkProfile() {
ChunkProfile profile;
return ChunkProfile {
.m_ClassId = this->m_ClassId,
.m_DataDwSize = this->m_DataDwSize,
.m_pData = this->m_pData,
profile.m_ClassId = this->m_ClassId;
profile.m_DataDwSize = this->m_DataDwSize;
profile.m_pData = this->m_pData;
.m_DataVersion = this->m_DataVersion,
.m_ChunkVersion = this->m_ChunkVersion,
profile.m_DataVersion = this->m_DataVersion;
profile.m_ChunkVersion = this->m_ChunkVersion;
.m_ObjectListSize = this->m_ObjectList.size(),
.m_ChunkListSize = this->m_ChunkList.size(),
.m_ManagerListSize = this->m_ManagerList.size(),
profile.m_ObjectListSize = this->m_ObjectList.size();
profile.m_ChunkListSize = this->m_ChunkList.size();
profile.m_ManagerListSize = this->m_ManagerList.size();
profile.m_BindFile = this->m_BindFile;
profile.m_BindContext = this->m_BindContext;
return profile;
.m_BindFile = this->m_BindFile,
.m_BindContext = this->m_BindContext,
};
}
void CKStateChunk::Clear(void) {
@ -773,7 +771,7 @@ namespace LibCmo::CK2 {
/* ========== Sequence Functions ==========*/
bool CKStateChunk::ReadObjectIDSequence(std::vector<CK_ID>* ls) {
bool CKStateChunk::ReadObjectIDSequence(XContainer::XArray<CK_ID>* ls) {
if (ls == nullptr) return false;
ls->clear();
@ -793,7 +791,7 @@ namespace LibCmo::CK2 {
return true;
}
bool CKStateChunk::ReadManagerIntSequence(CKGUID* guid, std::vector<CKINT>* ls) {
bool CKStateChunk::ReadManagerIntSequence(CKGUID* guid, XContainer::XArray<CKINT>* ls) {
if (guid == nullptr || ls == nullptr) return false;
// read count
@ -815,7 +813,7 @@ namespace LibCmo::CK2 {
return true;
}
bool CKStateChunk::ReadSubChunkSequence(std::vector<CKStateChunk*>* ls) {
bool CKStateChunk::ReadSubChunkSequence(XContainer::XArray<CKStateChunk*>* ls) {
if (ls == nullptr) return false;
// clear first
@ -848,17 +846,18 @@ namespace LibCmo::CK2 {
return true;
}
bool CKStateChunk::ReadObjectArray(std::vector<CK_ID>* ls) {
bool CKStateChunk::ReadXObjectArray(XContainer::XObjectArray* ls) {
if (ls == nullptr) return false;
ls->clear();
// read count
CKDWORD count;
if (!this->ReadStruct(count)) return false;
if (!count) return true; // 0 size array
if (count == 0) return true; // 0 size array
// old file size correction
if (this->m_ChunkVersion < CK_STATECHUNK_CHUNKVERSION::CHUNK_VERSION1) {
bool old_file = this->m_ChunkVersion < CK_STATECHUNK_CHUNKVERSION::CHUNK_VERSION1;
if (old_file) {
// skip 4. but I don't know why!!!
this->Skip(4);
if (!this->ReadStruct(count)) return false;
@ -874,21 +873,36 @@ namespace LibCmo::CK2 {
return false;
}
// remap id
if (this->m_BindFile != nullptr) {
if (cache < 0) {
id = 0u;
} else {
id = this->m_BindFile->GetFileObjectByIndex(cache)->CreatedObjectId;
}
} else {
// in old file or no bind file, the read data directly is CK_ID.
// in new file or has bind file, the read data is the index in FileObjects
if (old_file || this->m_BindFile == nullptr) {
id = static_cast<CK_ID>(cache);
} else {
if (cache < 0) id = 0;
else id = this->m_BindFile->GetFileObjectByIndex(cache)->CreatedObjectId;
}
}
return true;
}
bool CKStateChunk::ReadXObjectPointerArray(XContainer::XObjectPointerArray* ls) {
if (ls == nullptr) return false;
// very very similar to ReadXObjectArray
// we execute it first.
XContainer::XObjectArray idarr;
if (!ReadXObjectArray(idarr)) return false;
// then convert it to pointer list
ls->resize(idarr.size());
for (size_t i = 0; i < idarr.size(); ++i) {
(*ls)[i] = m_BindContext->GetObject(idarr[i]);
}
return true;
}
#pragma endregion

View File

@ -119,14 +119,14 @@ namespace LibCmo::CK2 {
/* ========== Basic Data Read Functions ==========*/
private:
/// <summary>
/// The base read function for all data.
/// <para>This function will check all read requirements.</para>
/// <para>If you have use this function or functions calling this function. You do not need check any reading requirements anymore</para>
/// </summary>
/// <param name="data_ptr">the pointer to data. must be allocated first.</param>
/// <param name="size_in_byte">the size of data in byte.</param>
/// <returns></returns>
/**
* @brief The base read function for all data.
* This function will check all read requirements.
* If you have use this function or functions calling this function. You do not need check any reading requirements anymore.
* @param data_ptr[out] the pointer to data. must be allocated first.
* @param size_in_byte[in] the size of data in byte.
* @return True if success.
*/
bool ReadByteData(void* data_ptr, CKDWORD size_in_byte);
public:
/// <summary>
@ -228,8 +228,8 @@ namespace LibCmo::CK2 {
/// </summary>
/// <param name="ls"></param>
/// <returns></returns>
bool ReadObjectIDSequence(std::vector<CK_ID>* ls);
inline bool ReadObjectIDSequence(std::vector<CK_ID>& ls) {
bool ReadObjectIDSequence(XContainer::XArray<CK_ID>* ls);
inline bool ReadObjectIDSequence(XContainer::XArray<CK_ID>& ls) {
return ReadObjectIDSequence(&ls);
}
@ -240,8 +240,8 @@ namespace LibCmo::CK2 {
/// <param name="guid"></param>
/// <param name="ls"></param>
/// <returns></returns>
bool ReadManagerIntSequence(CKGUID* guid, std::vector<CKINT>* ls);
inline bool ReadManagerIntSequence(CKGUID& guid, std::vector<CKINT>& ls) {
bool ReadManagerIntSequence(CKGUID* guid, XContainer::XArray<CKINT>* ls);
inline bool ReadManagerIntSequence(CKGUID& guid, XContainer::XArray<CKINT>& ls) {
return ReadManagerIntSequence(&guid, &ls);
}
@ -252,20 +252,31 @@ namespace LibCmo::CK2 {
/// </summary>
/// <param name="ls"></param>
/// <returns></returns>
bool ReadSubChunkSequence(std::vector<CKStateChunk*>* ls);
inline bool ReadSubChunkSequence(std::vector<CKStateChunk*>& ls) {
bool ReadSubChunkSequence(XContainer::XArray<CKStateChunk*>* ls);
inline bool ReadSubChunkSequence(XContainer::XArray<CKStateChunk*>& ls) {
return ReadSubChunkSequence(&ls);
}
/// <summary>
/// Read Object Array (actually still is CK_ID)
/// <para>ReadXObjectArray() and ReadObjectArray() redirect to this.</para>
/// </summary>
/// <param name="ls"></param>
/// <returns></returns>
bool ReadObjectArray(std::vector<CK_ID>* ls);
inline bool ReadObjectArray(std::vector<CK_ID>& ls) {
return ReadObjectArray(&ls);
/**
* @brief Read Object Array (actually still is CK_ID)
* @remark ReadObjectArray() and XObjectArray::Load redirect to this.
* @param ls The list
* @return True if success.
*/
bool ReadXObjectArray(XContainer::XObjectArray* ls);
inline bool ReadXObjectArray(XContainer::XObjectArray& ls) {
return ReadXObjectArray(&ls);
}
/**
* @brief Read Object Array (actually is CKObject*)
* @remark ReadXObjectArray() and XObjectPointerArray::Load redirect to this.
* @param ls The list
* @return True if success
*/
bool ReadXObjectPointerArray(XContainer::XObjectPointerArray* ls);
inline bool ReadXObjectPointerArray(XContainer::XObjectPointerArray& ls) {
return ReadXObjectPointerArray(&ls);
}
//int ReadInt();

View File

@ -1,6 +1,7 @@
#include "CKSceneObject.hpp"
#include "../CKStateChunk.hpp"
#include "CKBeObject.hpp"
#include "CKGroup.hpp"
namespace LibCmo::CK2::ObjImpls {
@ -19,7 +20,10 @@ namespace LibCmo::CK2::ObjImpls {
}
bool CKBeObject::IsInGroup(CKGroup* group) {
return false;
if (group == nullptr) return false;
CKDWORD idx = group->CKBeObject_GetGroupIndex();
if (idx >= m_Groups.size()) return false;
return m_Groups[idx];
}
void CKBeObject::CKGroup_SetGroups(CKDWORD pos, bool val) {

View File

@ -25,10 +25,35 @@ namespace LibCmo::CK2::ObjImpls {
bool suc = CKBeObject::Load(chunk, file);
if (!suc) return false;
// cleat self
this->Clear();
// get grouped objects
if (chunk->SeekIdentifier(CK_STATESAVEFLAGS_GROUP::CK_STATESAVE_GROUPALL)) {
XContainer::XObjectPointerArray ptrs;
chunk->ReadXObjectPointerArray(ptrs);
// filter pointer and check them type
for (auto& ptr : ptrs) {
// skip bad one
if (ptr == nullptr || ptr == this
|| !CKIsChildClassOf(ptr->GetClassID(), CK_CLASSID::CKCID_BEOBJECT)) {
continue;
}
CKBeObject* beobj = static_cast<CKBeObject*>(ptr);
if (beobj->IsInGroup(this)) continue;
// add good one
beobj->CKGroup_SetGroups(m_GroupIndex, true);
m_ObjectArray.emplace_back(beobj);
}
}
return true;
}
CKDWORD CKGroup::GetGroupIndex() {
CKDWORD CKGroup::CKBeObject_GetGroupIndex() {
return m_GroupIndex;
}

View File

@ -19,7 +19,7 @@ namespace LibCmo::CK2::ObjImpls {
virtual bool Load(CKStateChunk* chunk, CKFileVisitor* file) override;
//virtual void PostLoad() override;
CKDWORD GetGroupIndex();
CKDWORD CKBeObject_GetGroupIndex();
// ===== Insert =====
CKERROR AddObject(CKBeObject *o);