aboutsummaryrefslogtreecommitdiff
path: root/source/GameObject.cpp
blob: bbddb20944da0c22004237eea57863f757b5ab9d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
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();
	}
}