aboutsummaryrefslogtreecommitdiff
path: root/source/GameObject.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'source/GameObject.cpp')
-rw-r--r--source/GameObject.cpp136
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();
+ }
+}