finish ckgroup again
This commit is contained in:
parent
fd69914a25
commit
eea15c2028
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue
Block a user