diff --git a/CodeGen/VectorGen/README.md b/CodeGen/VectorGen/README.md index 2c03b04..407da5c 100644 --- a/CodeGen/VectorGen/README.md +++ b/CodeGen/VectorGen/README.md @@ -1,3 +1,3 @@ # Vector Generator -Vector types (LibCmo::Vector3 and etc) and Vector-like types (LibCmo::Color and etc) nearly have similar declaration except slight differences (basically is the count of factors). Manually writing these declarations is boring and easy to cause potential invisible bugs. So we use a Python script to generate these declarations batchly to prevent any defects indroduced above. +Vector types (LibCmo::VxMath::VxVector3 and etc) and Vector-like types (LibCmo::VxMath::VxColor and etc) nearly have similar declaration except slight differences (basically is the count of factors). Manually writing these declarations is boring and easy to cause potential invisible bugs. So we use a Python script to generate these declarations batchly to prevent any defects indroduced above. diff --git a/LibCmo/CK2/ObjImpls/CKTargetCamera.cpp b/LibCmo/CK2/ObjImpls/CKTargetCamera.cpp index a03a53e..4f68a2e 100644 --- a/LibCmo/CK2/ObjImpls/CKTargetCamera.cpp +++ b/LibCmo/CK2/ObjImpls/CKTargetCamera.cpp @@ -1,6 +1,91 @@ #include "CKTargetCamera.hpp" #include "../CKStateChunk.hpp" +#include "../CKContext.hpp" namespace LibCmo::CK2::ObjImpls { + // MARK: THIS CODE IS BARELY FULL COPY OF CKTargetLight. + // Please sync them if you modify one of them! + + CKTargetCamera::CKTargetCamera(CKContext* ctx, CK_ID ckid, CKSTRING name) : + CKCamera(ctx, ckid, name), m_Target3dEntity(0) {} + + CKTargetCamera::~CKTargetCamera() {} + + void CKTargetCamera::PreDelete() { + // Remove associated target + SetTarget(nullptr); + } + + void CKTargetCamera::CheckPostDeletion() { + CKCamera::CheckPostDeletion(); + + // Remove target if is not existing. + CKObject* target = m_Context->GetObject(m_Target3dEntity); + if (target == nullptr) { + m_Target3dEntity = 0; + } + } + + bool CKTargetCamera::Save(CKStateChunk* chunk, CKFileVisitor* file, CKDWORD flags) { + bool suc = CKCamera::Save(chunk, file, flags); + if (!suc) return false; + + // Save target + { + chunk->WriteIdentifier(CK_STATESAVEFLAGS_CAMERA::CK_STATESAVE_TCAMERATARGET); + CKObject* target = m_Context->GetObject(m_Target3dEntity); + chunk->WriteObjectPointer(target); + } + + chunk->SetClassId(CK_CLASSID::CKCID_TARGETCAMERA); + return true; + } + + bool CKTargetCamera::Load(CKStateChunk* chunk, CKFileVisitor* file) { + bool suc = CKCamera::Load(chunk, file); + if (!suc) return false; + + // Read target + if (chunk->SeekIdentifier(CK_STATESAVEFLAGS_CAMERA::CK_STATESAVE_TCAMERATARGET)) { + chunk->ReadObjectID(m_Target3dEntity); + } + + return true; + } + + CK3dEntity* CKTargetCamera::GetTarget() const { + return static_cast(m_Context->GetObject(m_Target3dEntity)); + } + + void CKTargetCamera::SetTarget(CK3dEntity* target) { + // The target can not be self. + if (target == this) return; + + // First remove current target + CK3dEntity* old_target = static_cast(m_Context->GetObject(m_Target3dEntity)); + if (old_target != nullptr) { + CK_3DENTITY_FLAGS old_target_flags = old_target->GetEntityFlags(); + YYCC::EnumHelper::Remove(old_target_flags, CK_3DENTITY_FLAGS::CK_3DENTITY_TARGETCAMERA); + YYCC::EnumHelper::Add(old_target_flags, CK_3DENTITY_FLAGS::CK_3DENTITY_FRAME); + old_target->SetEntityFlags(old_target_flags); + } + + // Then add specified target + if (target != nullptr) { + CK_3DENTITY_FLAGS new_target_flags = target->GetEntityFlags(); + YYCC::EnumHelper::Add(new_target_flags, CK_3DENTITY_FLAGS::CK_3DENTITY_TARGETCAMERA); + YYCC::EnumHelper::Remove(new_target_flags, CK_3DENTITY_FLAGS::CK_3DENTITY_FRAME); + target->SetEntityFlags(new_target_flags); + } + + // Get CK_ID of new target + CK_ID target_id = 0; + if (target != nullptr) + target_id = target->GetID(); + + // Assign target id. + m_Target3dEntity = target_id; + } + } diff --git a/LibCmo/CK2/ObjImpls/CKTargetCamera.hpp b/LibCmo/CK2/ObjImpls/CKTargetCamera.hpp index 4dfbdff..6bdb72b 100644 --- a/LibCmo/CK2/ObjImpls/CKTargetCamera.hpp +++ b/LibCmo/CK2/ObjImpls/CKTargetCamera.hpp @@ -15,15 +15,16 @@ namespace LibCmo::CK2::ObjImpls { return CK_CLASSID::CKCID_TARGETCAMERA; } - virtual void CheckPreDeletion() override; + virtual void PreDelete() override; + virtual void CheckPostDeletion() override; // 2 RW funcions virtual bool Save(CKStateChunk* chunk, CKFileVisitor* file, CKDWORD flags) override; virtual bool Load(CKStateChunk* chunk, CKFileVisitor* file) override; - virtual CK3dEntity* GetTarget() const; - virtual void SetTarget(CK3dEntity* target); + virtual CK3dEntity* GetTarget() const override; + virtual void SetTarget(CK3dEntity* target) override; protected: CK_ID m_Target3dEntity; diff --git a/LibCmo/CK2/ObjImpls/CKTargetLight.cpp b/LibCmo/CK2/ObjImpls/CKTargetLight.cpp index a8a2f49..6b05e7e 100644 --- a/LibCmo/CK2/ObjImpls/CKTargetLight.cpp +++ b/LibCmo/CK2/ObjImpls/CKTargetLight.cpp @@ -1,6 +1,95 @@ #include "CKTargetLight.hpp" #include "../CKStateChunk.hpp" +#include "../CKContext.hpp" namespace LibCmo::CK2::ObjImpls { + + // MARK: THIS CODE IS BARELY FULL COPY OF CKTargetCamera. + // Please sync them if you modify one of them! + + CKTargetLight::CKTargetLight(CKContext* ctx, CK_ID ckid, CKSTRING name) : + CKLight(ctx, ckid, name), m_Target3dEntity(0) {} + + CKTargetLight::~CKTargetLight() {} + + void CKTargetLight::PreDelete() { + // MARK: In original code, there is no such override. + // Following statement is written in a function called "vector deleting destructor". + // Idk what it is. There is no resetting target code in its dtor and elsewhere. + // I think this is crucial, so I add this overload as my understandings. + + // Remove associated target + SetTarget(nullptr); + } + + void CKTargetLight::CheckPostDeletion() { + CKLight::CheckPostDeletion(); + + // Remove target if is not existing. + CKObject* target = m_Context->GetObject(m_Target3dEntity); + if (target == nullptr) { + m_Target3dEntity = 0; + } + } + + bool CKTargetLight::Save(CKStateChunk* chunk, CKFileVisitor* file, CKDWORD flags) { + bool suc = CKLight::Save(chunk, file, flags); + if (!suc) return false; + + // Save target + { + chunk->WriteIdentifier(CK_STATESAVEFLAGS_LIGHT::CK_STATESAVE_TLIGHTTARGET); + CKObject* target = m_Context->GetObject(m_Target3dEntity); + chunk->WriteObjectPointer(target); + } + + chunk->SetClassId(CK_CLASSID::CKCID_TARGETLIGHT); + return true; + } + + bool CKTargetLight::Load(CKStateChunk* chunk, CKFileVisitor* file) { + bool suc = CKLight::Load(chunk, file); + if (!suc) return false; + + // Read target + if (chunk->SeekIdentifier(CK_STATESAVEFLAGS_LIGHT::CK_STATESAVE_TLIGHTTARGET)) { + chunk->ReadObjectID(m_Target3dEntity); + } + + return true; + } + + CK3dEntity* CKTargetLight::GetTarget() const { + return static_cast(m_Context->GetObject(m_Target3dEntity)); + } + void CKTargetLight::SetTarget(CK3dEntity* target) { + // The target can not be self. + if (target == this) return; + + // First remove current target + CK3dEntity* old_target = static_cast(m_Context->GetObject(m_Target3dEntity)); + if (old_target != nullptr) { + CK_3DENTITY_FLAGS old_target_flags = old_target->GetEntityFlags(); + YYCC::EnumHelper::Remove(old_target_flags, CK_3DENTITY_FLAGS::CK_3DENTITY_TARGETLIGHT); + YYCC::EnumHelper::Add(old_target_flags, CK_3DENTITY_FLAGS::CK_3DENTITY_FRAME); + old_target->SetEntityFlags(old_target_flags); + } + + // Then add specified target + if (target != nullptr) { + CK_3DENTITY_FLAGS new_target_flags = target->GetEntityFlags(); + YYCC::EnumHelper::Add(new_target_flags, CK_3DENTITY_FLAGS::CK_3DENTITY_TARGETLIGHT); + YYCC::EnumHelper::Remove(new_target_flags, CK_3DENTITY_FLAGS::CK_3DENTITY_FRAME); + target->SetEntityFlags(new_target_flags); + } + + // Get CK_ID of new target + CK_ID target_id = 0; + if (target != nullptr) + target_id = target->GetID(); + + // Assign target id. + m_Target3dEntity = target_id; + } } diff --git a/LibCmo/CK2/ObjImpls/CKTargetLight.hpp b/LibCmo/CK2/ObjImpls/CKTargetLight.hpp index f43f66d..72ef4ce 100644 --- a/LibCmo/CK2/ObjImpls/CKTargetLight.hpp +++ b/LibCmo/CK2/ObjImpls/CKTargetLight.hpp @@ -15,15 +15,16 @@ namespace LibCmo::CK2::ObjImpls { return CK_CLASSID::CKCID_TARGETLIGHT; } - virtual void CheckPreDeletion() override; + virtual void PreDelete() override; + virtual void CheckPostDeletion() override; // 2 RW funcions virtual bool Save(CKStateChunk* chunk, CKFileVisitor* file, CKDWORD flags) override; virtual bool Load(CKStateChunk* chunk, CKFileVisitor* file) override; - virtual CK3dEntity* GetTarget() const; - virtual void SetTarget(CK3dEntity* target); + virtual CK3dEntity* GetTarget() const override; + virtual void SetTarget(CK3dEntity* target) override; protected: CK_ID m_Target3dEntity;