2023-08-31 21:54:25 +08:00
|
|
|
#include "CKGroup.hpp"
|
2023-09-01 12:19:06 +08:00
|
|
|
#include "../CKStateChunk.hpp"
|
|
|
|
#include "../CKContext.hpp"
|
2023-09-06 10:42:23 +08:00
|
|
|
#include "../MgrImpls/CKObjectManager.hpp"
|
2023-09-01 12:19:06 +08:00
|
|
|
#include <algorithm>
|
2023-08-31 21:54:25 +08:00
|
|
|
|
|
|
|
namespace LibCmo::CK2::ObjImpls {
|
|
|
|
|
2023-09-01 12:19:06 +08:00
|
|
|
CKGroup::CKGroup(CKContext* ctx, CK_ID ckid, CKSTRING name) :
|
|
|
|
CKBeObject(ctx, ckid, name),
|
|
|
|
m_ObjectArray(),
|
2023-09-16 22:38:21 +08:00
|
|
|
m_GroupIndex(m_Context->GetObjectManager()->AllocateGroupGlobalIndex()) {}
|
2023-09-01 12:19:06 +08:00
|
|
|
|
|
|
|
CKGroup::~CKGroup() {
|
2023-09-20 15:25:43 +08:00
|
|
|
// free self allocated id
|
2023-09-06 10:42:23 +08:00
|
|
|
m_Context->GetObjectManager()->FreeGroupGlobalIndex(m_GroupIndex);
|
2023-09-01 12:19:06 +08:00
|
|
|
}
|
|
|
|
|
2023-09-20 15:25:43 +08:00
|
|
|
void CKGroup::PreDelete() {
|
|
|
|
CKBeObject::PreDelete();
|
|
|
|
|
|
|
|
// unlink all grouped object
|
|
|
|
for (auto& ptr : m_ObjectArray) {
|
|
|
|
static_cast<CKBeObject*>(ptr)->ExplicitSetGroup(m_GroupIndex, false);
|
|
|
|
}
|
|
|
|
m_ObjectArray.clear();
|
|
|
|
}
|
|
|
|
|
|
|
|
void CKGroup::CheckPreDeletion() {
|
|
|
|
CKBeObject::CheckPreDeletion();
|
|
|
|
|
|
|
|
// remove self invalid object ptr
|
|
|
|
XContainer::NSXObjectPointerArray::PreDeletedCheck(m_ObjectArray, m_Context);
|
|
|
|
}
|
|
|
|
|
2023-08-31 21:54:25 +08:00
|
|
|
bool CKGroup::Save(CKStateChunk* chunk, CKFileVisitor* file, CKDWORD flags) {
|
2023-09-01 12:19:06 +08:00
|
|
|
bool suc = CKBeObject::Save(chunk, file, flags);
|
|
|
|
if (!suc) return false;
|
|
|
|
|
|
|
|
return true;
|
2023-08-31 21:54:25 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
bool CKGroup::Load(CKStateChunk* chunk, CKFileVisitor* file) {
|
2023-09-01 12:19:06 +08:00
|
|
|
bool suc = CKBeObject::Load(chunk, file);
|
|
|
|
if (!suc) return false;
|
|
|
|
|
2023-09-01 13:27:46 +08:00
|
|
|
// 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
|
2023-09-16 22:38:21 +08:00
|
|
|
beobj->ExplicitSetGroup(m_GroupIndex, true);
|
2023-09-01 13:27:46 +08:00
|
|
|
m_ObjectArray.emplace_back(beobj);
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2023-09-01 12:19:06 +08:00
|
|
|
return true;
|
2023-08-31 21:54:25 +08:00
|
|
|
}
|
|
|
|
|
2023-09-20 13:13:08 +08:00
|
|
|
void CKGroup::Show(CK_OBJECT_SHOWOPTION show) {
|
|
|
|
CKObject::Show(show);
|
|
|
|
|
|
|
|
// call Show for all sub object
|
|
|
|
for (auto& ptr : m_ObjectArray) {
|
|
|
|
if (ptr == nullptr) continue;
|
|
|
|
ptr->Show(show);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-09-16 22:38:21 +08:00
|
|
|
CKDWORD CKGroup::GetGroupIndex() {
|
2023-08-31 21:54:25 +08:00
|
|
|
return m_GroupIndex;
|
|
|
|
}
|
|
|
|
|
2023-09-01 12:19:06 +08:00
|
|
|
CKERROR CKGroup::AddObject(CKBeObject* o) {
|
|
|
|
if (o == nullptr || o == this || !CKIsChildClassOf(o->GetClassID(), CK_CLASSID::CKCID_BEOBJECT)) {
|
|
|
|
return CKERROR::CKERR_INVALIDPARAMETER;
|
|
|
|
}
|
|
|
|
if (o->IsInGroup(this)) {
|
|
|
|
return CKERROR::CKERR_ALREADYPRESENT;
|
|
|
|
}
|
|
|
|
|
|
|
|
// set object
|
2023-09-16 22:38:21 +08:00
|
|
|
o->ExplicitSetGroup(m_GroupIndex, true);
|
2023-09-01 12:19:06 +08:00
|
|
|
// set self
|
|
|
|
m_ObjectArray.emplace_back(o);
|
|
|
|
return CKERROR::CKERR_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
CKBeObject* CKGroup::RemoveObject(CKDWORD pos) {
|
|
|
|
// check pos
|
|
|
|
if (pos >= m_ObjectArray.size()) return nullptr;
|
|
|
|
|
|
|
|
auto it = m_ObjectArray.begin() + pos;
|
|
|
|
CKBeObject* obj = static_cast<CKBeObject*>(*it);
|
|
|
|
// set object
|
2023-09-16 22:38:21 +08:00
|
|
|
obj->ExplicitSetGroup(m_GroupIndex, false);
|
2023-09-01 12:19:06 +08:00
|
|
|
// remove self
|
|
|
|
m_ObjectArray.erase(it);
|
|
|
|
return obj;
|
|
|
|
}
|
|
|
|
|
|
|
|
void CKGroup::RemoveObject(CKBeObject* obj) {
|
|
|
|
// find first
|
|
|
|
auto finder = std::find(m_ObjectArray.begin(), m_ObjectArray.end(), static_cast<CKObject*>(obj));
|
|
|
|
if (finder != m_ObjectArray.end()) {
|
|
|
|
// set object
|
2023-09-16 22:38:21 +08:00
|
|
|
static_cast<CKBeObject*>(*finder)->ExplicitSetGroup(m_GroupIndex, false);
|
2023-09-01 12:19:06 +08:00
|
|
|
// remove self
|
|
|
|
m_ObjectArray.erase(finder);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void CKGroup::Clear() {
|
|
|
|
for (auto& beobj : m_ObjectArray) {
|
|
|
|
// set object
|
2023-09-16 22:38:21 +08:00
|
|
|
static_cast<CKBeObject*>(beobj)->ExplicitSetGroup(m_GroupIndex, false);
|
2023-09-01 12:19:06 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
m_ObjectArray.clear();
|
|
|
|
}
|
|
|
|
|
|
|
|
CKBeObject* CKGroup::GetObject(CKDWORD pos) {
|
|
|
|
if (pos >= m_ObjectArray.size()) return nullptr;
|
|
|
|
else return static_cast<CKBeObject*>(m_ObjectArray[pos]);
|
2023-08-31 21:54:25 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
CKDWORD CKGroup::GetObjectCount() {
|
2023-09-01 12:19:06 +08:00
|
|
|
return static_cast<CKDWORD>(m_ObjectArray.size());
|
2023-08-31 21:54:25 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|