A reimplementation of Mario Kart Wii's physics engine in C++
Loading...
Searching...
No Matches
SceneManager.cc
1#include "SceneManager.hh"
2
3#include "egg/core/ExpHeap.hh"
4
5namespace EGG {
6
7/*------------*
8 Lifecycle
9 *------------*/
10
12SceneManager::SceneManager(SceneCreator *creator) {
13 m_creator = creator;
14 m_currentScene = nullptr;
15}
16
17SceneManager::~SceneManager() = default;
18
19/*----------*
20 Virtual
21 *----------*/
22
24void SceneManager::calc() {
25 calcCurrentScene();
26}
27
29void SceneManager::calcCurrentScene() {
30 if (!m_currentScene) {
31 return;
32 }
33
34 m_currentScene->calc();
35}
36
37/*----------*
38 Methods
39 *----------*/
40
42void SceneManager::createChildScene(int id, Scene *parent) {
43 outgoingParentScene(parent);
44 setNextSceneId(id);
45 setupNextSceneId();
46 createScene(id, parent);
47}
48
50void SceneManager::createScene(int id, Scene *parent) {
51 Heap *parentHeap = parent ? parent->heap() : s_rootHeap;
52
53 // We need to preserve the locked status to reinstate it later
54 bool locked = parentHeap->tstDisableAllocation();
55 if (locked) {
56 parentHeap->enableAllocation();
57 }
58
59 ExpHeap *newHeap = ExpHeap::create(-1, parentHeap, s_heapOptionFlg);
60 s_heapForCreateScene = newHeap;
61
62 if (locked) {
63 parentHeap->disableAllocation();
64 }
65
66 newHeap->becomeCurrentHeap();
67 newHeap->setName("DefaultSceneHeap");
68
69 Scene *newScene = m_creator->create(id);
70
71 if (parent) {
72 parent->setChild(newScene);
73 }
74
75 m_currentScene = newScene;
76 newScene->setId(id);
77 newScene->setParent(parent);
78 newScene->setSceneMgr(this);
79 newScene->enter();
80}
81
83void SceneManager::destroyScene(Scene *scene) {
84 scene->exit();
85 if (scene->child()) {
86 destroyScene(scene->child());
87 }
88
89 Scene *parent = scene->parent();
90 m_creator->destroy(scene->id());
91
92 // ADDED: The original library does not actually delete the scene, but we run into leaks
93 // So, we delete the scene that's provided to the function
94 auto *heap = scene->heap();
95 delete scene;
96
97 m_currentScene = nullptr;
98
99 if (parent) {
100 parent->setChild(nullptr);
101 m_currentScene = parent;
102 }
103
104 heap->destroy();
105 Heap *parentHeap = parent ? parent->heap() : s_rootHeap;
106 parentHeap->becomeCurrentHeap();
107}
108
110void SceneManager::changeScene(int nextSceneId) {
111 while (m_currentScene) {
112 destroyCurrentSceneNoIncoming(true);
113 }
114
115 changeSiblingScene(nextSceneId);
116}
117
119void SceneManager::changeSiblingScene(int nextSceneId) {
120 setNextSceneId(nextSceneId);
121 changeSiblingScene();
122}
123
125void SceneManager::changeSiblingScene() {
126 Scene *parentScene = m_currentScene ? m_currentScene->parent() : nullptr;
127
128 if (m_currentScene) {
129 destroyScene(m_currentScene);
130 m_currentScene = nullptr;
131 }
132
133 int nextSceneId = m_nextSceneId;
134 setupNextSceneId();
135 createScene(nextSceneId, parentScene);
136}
137
139void SceneManager::incomingCurrentScene() {
140 if (!m_currentScene) {
141 return;
142 }
143
144 m_currentScene->incoming_childDestroy();
145}
146
148void SceneManager::outgoingParentScene(Scene *parent) {
149 parent->outgoing_childCreate();
150}
151
153void SceneManager::reinitCurrentScene() {
154 if (!m_currentScene) {
155 return;
156 }
157
158 m_currentScene->reinit();
159}
160
162bool SceneManager::destroyCurrentSceneNoIncoming(bool destroyRootIfNoParent) {
163 if (!m_currentScene) {
164 return false;
165 }
166
167 Scene *parent = m_currentScene->parent();
168 if (parent) {
169 destroyScene(parent->child());
170 setNextSceneId(parent->id());
171 setupNextSceneId();
172 return true;
173 } else {
174 if (destroyRootIfNoParent) {
175 destroyScene(m_currentScene);
176 setNextSceneId(-1);
177 setupNextSceneId();
178 }
179 return false;
180 }
181}
182
184bool SceneManager::destroyToSelectSceneId(int id) {
185 Scene *parent = findParentScene(id);
186 if (!parent) {
187 return false;
188 }
189
190 while (parent->id() != currentSceneId()) {
191 destroyCurrentSceneNoIncoming(false);
192 }
193 incomingCurrentScene();
194 return true;
195}
196
198Scene *SceneManager::findParentScene(int id) const {
199 Scene *scene = m_currentScene->parent();
200 for (; scene; scene = scene->parent()) {
201 if (scene->id() == id) {
202 break;
203 }
204 }
205
206 return scene;
207}
208
210void SceneManager::setupNextSceneId() {
211 m_prevSceneId = m_currentSceneId;
212 m_currentSceneId = m_nextSceneId;
213 m_nextSceneId = -1;
214}
215
216Heap *SceneManager::s_heapForCreateScene = nullptr;
217u16 SceneManager::s_heapOptionFlg = 2;
218
219Heap *SceneManager::s_rootHeap = nullptr;
220
221} // namespace EGG
EGG core library.
Definition Archive.cc:6
Pertains to scene handling.
Definition GameScene.cc:8