split CKContext work
This commit is contained in:
@ -2,6 +2,28 @@
|
||||
|
||||
#include "../../VTAll.hpp"
|
||||
|
||||
/**
|
||||
CKBaseManager virtual functions implementations help
|
||||
All virtual functions is not supported except we implemented.
|
||||
|
||||
Read/Write functions:
|
||||
- SaveData()
|
||||
- LoadData()
|
||||
|
||||
Clear functions:
|
||||
- PreClearAll()
|
||||
- PostClearAll()
|
||||
|
||||
Delete functions:
|
||||
- SequenceToBeDeleted()
|
||||
- SequenceDeleted()
|
||||
|
||||
Moved functions
|
||||
- OnCKInit(): Implement in ctor
|
||||
- OnCKEnd(): Implement in dtor
|
||||
|
||||
*/
|
||||
|
||||
namespace LibCmo::CK2::MgrImpls {
|
||||
|
||||
/**
|
||||
@ -16,8 +38,7 @@ namespace LibCmo::CK2::MgrImpls {
|
||||
CKBaseManager(CKContext* ctx, CKGUID guid, CKSTRING name) :
|
||||
m_ManagerGuid(guid),
|
||||
m_ManagerName(name),
|
||||
m_Context(ctx)
|
||||
{}
|
||||
m_Context(ctx) {}
|
||||
virtual ~CKBaseManager() {}
|
||||
LIBCMO_DISABLE_COPY_MOVE(CKBaseManager);
|
||||
|
||||
@ -37,8 +58,8 @@ namespace LibCmo::CK2::MgrImpls {
|
||||
```
|
||||
@see CKContext::RegisterNewManager, GetName
|
||||
*/
|
||||
CKGUID GetGuid() {
|
||||
return m_ManagerGuid;
|
||||
CKGUID GetGuid() {
|
||||
return m_ManagerGuid;
|
||||
}
|
||||
/**
|
||||
@brief Acces to Manager name
|
||||
@ -55,14 +76,14 @@ namespace LibCmo::CK2::MgrImpls {
|
||||
}
|
||||
```
|
||||
*/
|
||||
CKSTRING GetName() {
|
||||
return m_ManagerName.c_str();
|
||||
CKSTRING GetName() {
|
||||
return m_ManagerName.toCKSTRING();
|
||||
}
|
||||
|
||||
/**
|
||||
@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.
|
||||
@return This function should return true or false 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
|
||||
@ -70,21 +91,68 @@ namespace LibCmo::CK2::MgrImpls {
|
||||
@see CKStateChunk, LoadData
|
||||
*/
|
||||
virtual bool SaveData(CKStateChunk* chunk, CKFileVisitor* SavedFile) {
|
||||
return true;
|
||||
return false; // default value is false to indicate this manager do not need save any data.
|
||||
}
|
||||
/**
|
||||
@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.
|
||||
@return CKERR_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, CKFileVisitor* LoadedFile) {
|
||||
return CKERROR::CKERR_OK;
|
||||
return CKERROR::CKERR_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Called at the beginning of a CKContext::ClearAll operation.
|
||||
@return CK_OK if successful or an error code otherwise.
|
||||
@remark
|
||||
+ You can override this function to add specific processing at the beginning of a CKContext::ClearAll operation.
|
||||
+ You must override GetValidFunctionsMask and return a value including
|
||||
CKMANAGER_FUNC_PreClearAll for this function to get called.
|
||||
@see Main Virtools Events, PostClearAll, CKContext::ClearAll
|
||||
*/
|
||||
virtual CKERROR PreClearAll() { return CKERROR::CKERR_OK; }
|
||||
/**
|
||||
@brief Called at the end of a CKContext::ClearAll operation.
|
||||
@return CKERR_OK if successful or an error code otherwise.
|
||||
@remark
|
||||
+ You can override this function to add specific processing at the end of a CKContext::ClearAll operation.
|
||||
+ You must override GetValidFunctionsMask and return a value including
|
||||
CKMANAGER_FUNC_PostClearAll for this function to get called.
|
||||
@see Main Virtools Events, PreClearAll, CKContext::ClearAll
|
||||
*/
|
||||
virtual CKERROR PostClearAll() { return CKERROR::CKERR_OK; }
|
||||
|
||||
/**
|
||||
@brief Called just before objects are deleted.
|
||||
@return CK_OK if successful or an error code otherwise.
|
||||
@param objids[in] A pointer to a list of CK_ID of the objects being deleted.
|
||||
@param count[in] number of objects in objids list.
|
||||
@remark
|
||||
+ You can override this function if you need to add specific processing before objects are deleted.
|
||||
+ You must override GetValidFunctionsMask and return a value including
|
||||
CKMANAGER_FUNC_OnSequenceToBeDeleted for this function to get called.
|
||||
@see Main Virtools Events, CKContext::DestroyObjects, SequenceDeleted
|
||||
*/
|
||||
virtual CKERROR SequenceToBeDeleted(const CK_ID* objids, CKDWORD count) { return CKERROR::CKERR_OK; }
|
||||
/**
|
||||
@brief Called after objects have been deleted.
|
||||
@return CK_OK if successful or an error code otherwise.
|
||||
@param objids[in] A pointer to a list of CK_ID of the objects being deleted.
|
||||
@param count[in] number of objects in objids list.
|
||||
@remark
|
||||
+ You can override this function if you need to add specific processing after objects have been deleted.
|
||||
+ You must override GetValidFunctionsMask and return a value including
|
||||
CKMANAGER_FUNC_OnSequenceDeleted for this function to get called.
|
||||
@see Main Virtools Events, CKContext::DestroyObjects, SequenceToBeDeleted
|
||||
*/
|
||||
virtual CKERROR SequenceDeleted(const CK_ID* objids, CKDWORD count) { return CKERROR::CKERR_OK; }
|
||||
|
||||
|
||||
protected:
|
||||
CKGUID m_ManagerGuid; ///> Manager GUID
|
||||
TypeHelper::MKString m_ManagerName; ///> Manager Name
|
||||
|
196
LibCmo/CK2/MgrImpls/CKObjectManager.cpp
Normal file
196
LibCmo/CK2/MgrImpls/CKObjectManager.cpp
Normal file
@ -0,0 +1,196 @@
|
||||
#include "CKObjectManager.hpp"
|
||||
#include "../ObjImpls/CKObject.hpp"
|
||||
|
||||
namespace LibCmo::CK2::MgrImpls {
|
||||
|
||||
CKObjectManager::CKObjectManager(CKContext* ctx) :
|
||||
CKBaseManager(ctx, OBJECT_MANAGER_GUID, "Object Manager"),
|
||||
m_ObjectsList(), m_ReturnedObjectOffsets(), m_ObjectCount(0),
|
||||
m_GroupGlobalIndex(), m_SceneGlobalIndex(),
|
||||
m_ObjectsListByClass(CKGetClassCount()) {}
|
||||
|
||||
CKObjectManager::~CKObjectManager() {
|
||||
DestroyAllObjects();
|
||||
}
|
||||
|
||||
ObjImpls::CKObject* CKObjectManager::CreateObject(CK_CLASSID cls, CKSTRING name,
|
||||
CK_OBJECTCREATION_OPTIONS options, CK_CREATIONMODE* res) {
|
||||
// todo: Process paramter options and res
|
||||
|
||||
// get description first
|
||||
const CKClassDesc* desc = CKGetClassDesc(cls);
|
||||
if (desc == nullptr) return nullptr;
|
||||
|
||||
// allocate a CK_ID first
|
||||
CKDWORD decided_off;
|
||||
if (this->m_ReturnedObjectOffsets.empty()) {
|
||||
// create new CK_ID.
|
||||
decided_off = static_cast<CKDWORD>(m_ObjectsList.size());
|
||||
m_ObjectsList.resize(decided_off + 1);
|
||||
} else {
|
||||
// use returned CK_ID.
|
||||
decided_off = m_ReturnedObjectOffsets.back();
|
||||
m_ReturnedObjectOffsets.pop_back();
|
||||
}
|
||||
|
||||
// create one
|
||||
ObjImpls::CKObject* obj = desc->CreationFct(m_Context, Offset2Id(decided_off), name);
|
||||
|
||||
// put into slot and inc count
|
||||
m_ObjectsList[decided_off] = obj;
|
||||
++m_ObjectCount;
|
||||
|
||||
// set out variable
|
||||
return obj;
|
||||
}
|
||||
|
||||
ObjImpls::CKObject* CKObjectManager::GetObject(CK_ID id) {
|
||||
CKDWORD off = Id2Offset(id);
|
||||
if (off >= m_ObjectsList.size()) return nullptr;
|
||||
return m_ObjectsList[off];
|
||||
}
|
||||
|
||||
CKDWORD CKObjectManager::GetObjectCount() {
|
||||
return m_ObjectCount;
|
||||
}
|
||||
|
||||
void CKObjectManager::InternalDestroy(ObjImpls::CKObject* obj) {
|
||||
// find desc by classid
|
||||
// if really we can not find it, we only can delete it directly.
|
||||
const CKClassDesc* desc = CKGetClassDesc(obj->GetClassID());
|
||||
if (desc == nullptr) {
|
||||
delete obj;
|
||||
return;
|
||||
}
|
||||
|
||||
// free it
|
||||
desc->ReleaseFct(m_Context, obj);
|
||||
}
|
||||
|
||||
void CKObjectManager::DestroyObject(CK_ID id) {
|
||||
CKDWORD off = Id2Offset(id);
|
||||
if (off >= m_ObjectsList.size()) return;
|
||||
|
||||
// get object and free it
|
||||
ObjImpls::CKObject* obj = m_ObjectsList[off];
|
||||
if (obj == nullptr) return;
|
||||
InternalDestroy(obj);
|
||||
|
||||
// return its allocated id.
|
||||
// and dec count
|
||||
m_ObjectsList[off] = nullptr;
|
||||
m_ReturnedObjectOffsets.emplace_back(off);
|
||||
--m_ObjectCount;
|
||||
|
||||
}
|
||||
|
||||
void CKObjectManager::DestroyAllObjects() {
|
||||
// free all created objects
|
||||
for (auto& ptr : m_ObjectsList) {
|
||||
if (ptr != nullptr) {
|
||||
InternalDestroy(ptr);
|
||||
}
|
||||
}
|
||||
// restore returned object list
|
||||
m_ReturnedObjectOffsets.clear();
|
||||
// empty object list
|
||||
m_ObjectsList.clear();
|
||||
// reset count
|
||||
m_ObjectCount = 0;
|
||||
|
||||
// clear obj by class list
|
||||
for (auto& ls : m_ObjectsListByClass) {
|
||||
ls.clear();
|
||||
}
|
||||
|
||||
// clear group and scene global index at the same time
|
||||
m_SceneGlobalIndex.clear();
|
||||
m_GroupGlobalIndex.clear();
|
||||
}
|
||||
|
||||
XContainer::XObjectPointerArray CKObjectManager::GetObjectByNameAndClass(CKSTRING name, CK_CLASSID cid, bool derived) {
|
||||
XContainer::XObjectPointerArray result;
|
||||
|
||||
for (size_t i = 0; i < m_ObjectsListByClass.size(); ++i) {
|
||||
// check class id first
|
||||
if (derived) {
|
||||
if (!CKIsChildClassOf(static_cast<CK_CLASSID>(i), cid)) continue;
|
||||
} else {
|
||||
if (static_cast<CK_CLASSID>(i) != cid) continue;
|
||||
}
|
||||
|
||||
// iterate all sub object and check name
|
||||
for (const auto& objoff : m_ObjectsListByClass[i]) {
|
||||
ObjImpls::CKObject* obj = m_ObjectsList[objoff];
|
||||
|
||||
if (name == nullptr) {
|
||||
// directly add
|
||||
result.emplace_back(obj);
|
||||
} else {
|
||||
// check name
|
||||
if (CKStrEqual(name, obj->GetName())) {
|
||||
result.emplace_back(obj);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CKDWORD CKObjectManager::AllocateGroupGlobalIndex(ObjImpls::CKObject* group) {
|
||||
// try find first nullptr position
|
||||
CKDWORD index = 0;
|
||||
for (const auto& ptr : m_GroupGlobalIndex) {
|
||||
if (ptr == nullptr) break;
|
||||
++index;
|
||||
}
|
||||
// resize array for new position
|
||||
if (index == m_GroupGlobalIndex.size()) {
|
||||
m_GroupGlobalIndex.resize(m_GroupGlobalIndex.size() + 1);
|
||||
}
|
||||
|
||||
// set to occupy
|
||||
m_GroupGlobalIndex[index] = group;
|
||||
return index;
|
||||
}
|
||||
|
||||
CKDWORD CKObjectManager::AllocateSceneGlobalIndex(ObjImpls::CKObject* scene) {
|
||||
// same as group
|
||||
CKDWORD index = 0;
|
||||
for (const auto& ptr : m_SceneGlobalIndex) {
|
||||
if (ptr == nullptr) break;
|
||||
++index;
|
||||
}
|
||||
// resize array for new position
|
||||
if (index == m_SceneGlobalIndex.size()) {
|
||||
m_SceneGlobalIndex.resize(m_SceneGlobalIndex.size() + 1);
|
||||
}
|
||||
|
||||
// set to occupy
|
||||
m_SceneGlobalIndex[index] = scene;
|
||||
return index;
|
||||
}
|
||||
|
||||
ObjImpls::CKObject* CKObjectManager::GetGroupByGlobalIndex(CKDWORD index) {
|
||||
if (index >= m_GroupGlobalIndex.size()) return nullptr;
|
||||
else return m_GroupGlobalIndex[index];
|
||||
}
|
||||
|
||||
ObjImpls::CKObject* CKObjectManager::GetSceneByGlobalIndex(CKDWORD index) {
|
||||
if (index >= m_SceneGlobalIndex.size()) return nullptr;
|
||||
else return m_SceneGlobalIndex[index];
|
||||
}
|
||||
|
||||
void CKObjectManager::FreeGroupGlobalIndex(CKDWORD id) {
|
||||
// check position
|
||||
if (id >= m_GroupGlobalIndex.size()) return;
|
||||
// set value
|
||||
m_GroupGlobalIndex[id] = nullptr;
|
||||
}
|
||||
|
||||
void CKObjectManager::FreeSceneGlobalIndex(CKDWORD id) {
|
||||
// same as group
|
||||
if (id >= m_SceneGlobalIndex.size()) return;
|
||||
m_SceneGlobalIndex[id] = nullptr;
|
||||
}
|
||||
|
||||
}
|
81
LibCmo/CK2/MgrImpls/CKObjectManager.hpp
Normal file
81
LibCmo/CK2/MgrImpls/CKObjectManager.hpp
Normal file
@ -0,0 +1,81 @@
|
||||
#pragma once
|
||||
|
||||
#include "../../VTAll.hpp"
|
||||
#include "CKBaseManager.hpp"
|
||||
#include <deque>
|
||||
|
||||
namespace LibCmo::CK2::MgrImpls {
|
||||
|
||||
class CKObjectManager : public CKBaseManager {
|
||||
public:
|
||||
CKObjectManager(CKContext* ctx);
|
||||
virtual ~CKObjectManager();
|
||||
LIBCMO_DISABLE_COPY_MOVE(CKObjectManager);
|
||||
|
||||
// ========== Objects Management ==========
|
||||
|
||||
/**
|
||||
* @brief Creates a CKObject or derived class instance.
|
||||
* @param[in] cls Class Identifier (CK_CLASSID) of the object to create.
|
||||
* @param[in] name The name of this object.
|
||||
* @param[in] options Tell CKContext how to create this object when conflict happended.
|
||||
* @param[out] res The value indicate the real method how this object created.
|
||||
* @return A pointer to the newly created object.
|
||||
* @remark CKObjects must be destroy with the DestroyObject method.
|
||||
* @see CKObject, DestroyObject
|
||||
*/
|
||||
ObjImpls::CKObject* CreateObject(CK_CLASSID cls, CKSTRING name,
|
||||
CK_OBJECTCREATION_OPTIONS options = CK_OBJECTCREATION_OPTIONS::CK_OBJECTCREATION_NONAMECHECK,
|
||||
CK_CREATIONMODE* res = nullptr);
|
||||
// todo: implement CopyObject by CKClassDesc
|
||||
//ObjImpls::CKObject* CopyObject(ObjImpls::CKObject *src,
|
||||
// CKDependencies* Dependencies = nullptr,
|
||||
// CKSTRING AppendName = nullptr,
|
||||
// CK_OBJECTCREATION_OPTIONS Options = CK_OBJECTCREATION_OPTIONS::CK_OBJECTCREATION_NONAMECHECK);
|
||||
|
||||
ObjImpls::CKObject* GetObject(CK_ID id);
|
||||
CKDWORD GetObjectCount();
|
||||
void DestroyObject(CK_ID id);
|
||||
void DestroyAllObjects();
|
||||
|
||||
// ========== Objects Access ==========
|
||||
|
||||
XContainer::XObjectPointerArray GetObjectByNameAndClass(
|
||||
CKSTRING name, CK_CLASSID cid, bool derived);
|
||||
|
||||
// ========== Special Functions ==========
|
||||
|
||||
CKDWORD AllocateGroupGlobalIndex(ObjImpls::CKObject* group);
|
||||
CKDWORD AllocateSceneGlobalIndex(ObjImpls::CKObject* scene);
|
||||
ObjImpls::CKObject* GetGroupByGlobalIndex(CKDWORD index);
|
||||
ObjImpls::CKObject* GetSceneByGlobalIndex(CKDWORD index);
|
||||
void FreeGroupGlobalIndex(CKDWORD id);
|
||||
void FreeSceneGlobalIndex(CKDWORD id);
|
||||
|
||||
protected:
|
||||
/**
|
||||
* The global offset of created CK_ID.
|
||||
* The value close to zero may cause some issue.
|
||||
* So we add a static offset to every created CK_ID.
|
||||
*/
|
||||
const CK_ID c_ObjectIdOffset = 61u;
|
||||
CKDWORD Id2Offset(CK_ID id) { return static_cast<CKDWORD>(id - c_ObjectIdOffset); }
|
||||
CK_ID Offset2Id(CKDWORD off) { return static_cast<CK_ID>(off + c_ObjectIdOffset); }
|
||||
|
||||
/**
|
||||
* @brief The real CKObject destroy worker shared by CKObjectManager::DestroyObject and CKObjectManager::~CKObjectManager
|
||||
* @param[in] obj The CKObject need to be free.
|
||||
*/
|
||||
void InternalDestroy(ObjImpls::CKObject* obj);
|
||||
|
||||
CKDWORD m_ObjectCount;
|
||||
XContainer::XObjectPointerArray m_ObjectsList;
|
||||
XContainer::XArray<XContainer::XArray<CKDWORD>> m_ObjectsListByClass;
|
||||
std::deque<CKDWORD> m_ReturnedObjectOffsets;
|
||||
|
||||
XContainer::XObjectPointerArray m_GroupGlobalIndex;
|
||||
XContainer::XObjectPointerArray m_SceneGlobalIndex;
|
||||
|
||||
};
|
||||
|
||||
}
|
6
LibCmo/CK2/MgrImpls/CKPathManager.cpp
Normal file
6
LibCmo/CK2/MgrImpls/CKPathManager.cpp
Normal file
@ -0,0 +1,6 @@
|
||||
#include "CKPathManager.hpp"
|
||||
|
||||
namespace LibCmo::CK2::MgrImpls {
|
||||
|
||||
}
|
||||
|
19
LibCmo/CK2/MgrImpls/CKPathManager.hpp
Normal file
19
LibCmo/CK2/MgrImpls/CKPathManager.hpp
Normal file
@ -0,0 +1,19 @@
|
||||
#pragma once
|
||||
|
||||
#include "../../VTAll.hpp"
|
||||
#include "CKBaseManager.hpp"
|
||||
|
||||
namespace LibCmo::CK2::MgrImpls {
|
||||
|
||||
class CKPathManager : public CKBaseManager {
|
||||
public:
|
||||
CKPathManager(CKContext* ctx) :
|
||||
CKBaseManager(ctx, PATH_MANAGER_GUID, "Path Manager") {}
|
||||
virtual ~CKPathManager() {}
|
||||
LIBCMO_DISABLE_COPY_MOVE(CKPathManager);
|
||||
|
||||
protected:
|
||||
|
||||
};
|
||||
|
||||
}
|
Reference in New Issue
Block a user