diff options
Diffstat (limited to 'source/GameObject.cpp')
-rw-r--r-- | source/GameObject.cpp | 136 |
1 files changed, 136 insertions, 0 deletions
diff --git a/source/GameObject.cpp b/source/GameObject.cpp new file mode 100644 index 0000000..bbddb20 --- /dev/null +++ b/source/GameObject.cpp @@ -0,0 +1,136 @@ +#include "GameObject.hpp" + +#include "World.hpp" + +void GameObject::FreeRecursive(GameObject* obj) { + auto gomm = obj->GetMemoryManagement(); + bool freeSelf = gomm != Tags::GOMM_SelfAndAllChildren; + bool freeChildren = gomm != Tags::GOMM_SelfAndAllChildren && gomm != Tags::GOMM_AllChildren; + + if (freeChildren) { + for (auto child : obj->GetChildren()) { + FreeRecursive(obj); + } + } + if (freeSelf) { + delete obj; + } +} + +GameObject::GameObject(GameWorld* world) + : mWorld{ world } { +} + +GameObject::~GameObject() { + RemoveAllChildren(); + if (mParent) { + mParent->RemoveChild(this); + // NOTE: from this point on, mParent will be nullptr + } +} + +GameWorld* GameObject::GetWorld() const { + return mWorld; +} + +GameObject* GameObject::GetParent() const { + return mParent; +} + +const PodVector<GameObject*>& GameObject::GetChildren() const { + return mChildren; +} + +namespace ProjectBrussel_UNITY_ID { +bool ValidateGameObjectChild(GameObject* parent, GameObject* child) { + return parent->GetWorld() == child->GetWorld(); +} +} // namespace ProjectBrussel_UNITY_ID + +void GameObject::AddChild(GameObject* child) { + if (child->mParent) { + return; + } + if (!ProjectBrussel_UNITY_ID::ValidateGameObjectChild(this, child)) { + return; + } + + mChildren.push_back(child); + child->SetParent(this); +} + +GameObject* GameObject::RemoveChild(int index) { + if (index < 0 || index >= mChildren.size()) { + return nullptr; + } + + auto it = mChildren.begin() + index; + auto child = *it; + + // cancelUpdate(ret); + + std::swap(*it, mChildren.back()); + mChildren.pop_back(); + child->SetParent(nullptr); + return child; +} + +GameObject* GameObject::RemoveChild(GameObject* child) { + if (child) { + for (auto it = mChildren.begin(); it != mChildren.end(); ++it) { + if (*it == child) { + // cancelUpdate(child); + + std::swap(*it, mChildren.back()); + mChildren.pop_back(); + child->SetParent(nullptr); + return child; + } + } + } + return nullptr; +} + +PodVector<GameObject*> GameObject::RemoveAllChildren() { + for (auto& child : mChildren) { + child->SetParent(nullptr); + } + + auto result = std::move(mChildren); + // Moving from STL object leaves it in a valid but _unspecified_ state, call std::vector::clear() to guarantee it's empty + // NOTE: even though we have the source code of PodVector<T>, we still do this to follow convention + mChildren.clear(); + return result; +} + +Tags::GameObjectMemoryManagement GameObject::GetMemoryManagement() const { + return Tags::GOMM_None; +}; + +Tags::GameObjectType GameObject::GetTypeTag() const { + return Tags::GOT_Generic; +} + +const Material* GameObject::GetMeshMaterial() const { + return nullptr; +} + +const Mesh* GameObject::GetMesh() const { + return nullptr; +} + +void GameObject::Awaken() { +} + +void GameObject::Resleep() { +} + +void GameObject::Update() { +} + +void GameObject::SetParent(GameObject* parent) { + if (mParent != parent) { + mParent = parent; + // needUpdate(); + } +} |