diff options
author | Kelly Rauchenberger <fefferburbia@gmail.com> | 2018-05-14 18:40:54 -0400 |
---|---|---|
committer | Kelly Rauchenberger <fefferburbia@gmail.com> | 2018-05-17 15:39:39 -0400 |
commit | 5e48cf6333aca7af6854d79194f138d57ce0b5e1 (patch) | |
tree | b1703c6268b762a04a101f35188163fe2d9feb45 /src/systems | |
parent | 046ee24a341468e9b3ea2983a731dbce18b52ac6 (diff) | |
download | therapy-5e48cf6333aca7af6854d79194f138d57ce0b5e1.tar.gz therapy-5e48cf6333aca7af6854d79194f138d57ce0b5e1.tar.bz2 therapy-5e48cf6333aca7af6854d79194f138d57ce0b5e1.zip |
Specialized treatment of behavior scripts
The AutomatableComponent now links to the Runnable entity representing the behavior script. Also reordered the SystemManager and EntityManager members of the Game class such that the EntityManager is destroyed before the SystemManager is. This fixes a bug where the destruction of a component has some affect on the state of a system. Specifically, if the ScriptingSystem (and thus the Lua state) is destroyed before the EntityManager is and there are any Runnable entities, the game will crash when trying to destroy them.
Diffstat (limited to 'src/systems')
-rw-r--r-- | src/systems/realizing.cpp | 33 | ||||
-rw-r--r-- | src/systems/scripting.cpp | 70 | ||||
-rw-r--r-- | src/systems/scripting.h | 10 |
3 files changed, 76 insertions, 37 deletions
diff --git a/src/systems/realizing.cpp b/src/systems/realizing.cpp index 7f5aefb..baacf5a 100644 --- a/src/systems/realizing.cpp +++ b/src/systems/realizing.cpp | |||
@@ -12,6 +12,7 @@ | |||
12 | #include "components/ponderable.h" | 12 | #include "components/ponderable.h" |
13 | #include "components/transformable.h" | 13 | #include "components/transformable.h" |
14 | #include "components/prototypable.h" | 14 | #include "components/prototypable.h" |
15 | #include "components/automatable.h" | ||
15 | #include "systems/mapping.h" | 16 | #include "systems/mapping.h" |
16 | #include "systems/animating.h" | 17 | #include "systems/animating.h" |
17 | #include "systems/pondering.h" | 18 | #include "systems/pondering.h" |
@@ -223,7 +224,10 @@ RealizingSystem::RealizingSystem( | |||
223 | 224 | ||
224 | if (prototypeId == "movplat") | 225 | if (prototypeId == "movplat") |
225 | { | 226 | { |
226 | prototypable.hasBehavior = true; | 227 | auto& automatable = game_.getEntityManager(). |
228 | emplaceComponent<AutomatableComponent>(mapObject); | ||
229 | |||
230 | automatable.table = prototypeId; | ||
227 | } else if (prototypeId == "checkpoint") | 231 | } else if (prototypeId == "checkpoint") |
228 | { | 232 | { |
229 | auto& ponderable = game_.getEntityManager(). | 233 | auto& ponderable = game_.getEntityManager(). |
@@ -403,19 +407,9 @@ void RealizingSystem::enterActiveMap(id_type entity) | |||
403 | ponderable.active = true; | 407 | ponderable.active = true; |
404 | } | 408 | } |
405 | 409 | ||
406 | if (game_.getEntityManager().hasComponent<PrototypableComponent>(entity)) | 410 | if (game_.getEntityManager().hasComponent<AutomatableComponent>(entity)) |
407 | { | 411 | { |
408 | auto& prototypable = game_.getEntityManager(). | 412 | game_.getSystemManager().getSystem<ScriptingSystem>().startBehavior(entity); |
409 | getComponent<PrototypableComponent>(entity); | ||
410 | |||
411 | if (prototypable.hasBehavior) | ||
412 | { | ||
413 | auto& scripting = game_.getSystemManager().getSystem<ScriptingSystem>(); | ||
414 | |||
415 | prototypable.hasBehavior = true; | ||
416 | prototypable.runningBehavior = true; | ||
417 | prototypable.behaviorScript = scripting.runBehaviorScript(entity); | ||
418 | } | ||
419 | } | 413 | } |
420 | } | 414 | } |
421 | 415 | ||
@@ -437,17 +431,8 @@ void RealizingSystem::leaveActiveMap(id_type entity) | |||
437 | ponderable.active = false; | 431 | ponderable.active = false; |
438 | } | 432 | } |
439 | 433 | ||
440 | if (game_.getEntityManager().hasComponent<PrototypableComponent>(entity)) | 434 | if (game_.getEntityManager().hasComponent<AutomatableComponent>(entity)) |
441 | { | 435 | { |
442 | auto& prototypable = game_.getEntityManager(). | 436 | game_.getSystemManager().getSystem<ScriptingSystem>().stopBehavior(entity); |
443 | getComponent<PrototypableComponent>(entity); | ||
444 | |||
445 | if (prototypable.runningBehavior) | ||
446 | { | ||
447 | auto& scripting = game_.getSystemManager().getSystem<ScriptingSystem>(); | ||
448 | scripting.killScript(prototypable.behaviorScript); | ||
449 | |||
450 | prototypable.runningBehavior = false; | ||
451 | } | ||
452 | } | 437 | } |
453 | } | 438 | } |
diff --git a/src/systems/scripting.cpp b/src/systems/scripting.cpp index 57c3fd5..c423558 100644 --- a/src/systems/scripting.cpp +++ b/src/systems/scripting.cpp | |||
@@ -6,6 +6,7 @@ | |||
6 | #include "components/playable.h" | 6 | #include "components/playable.h" |
7 | #include "components/mappable.h" | 7 | #include "components/mappable.h" |
8 | #include "components/prototypable.h" | 8 | #include "components/prototypable.h" |
9 | #include "components/automatable.h" | ||
9 | #include "systems/realizing.h" | 10 | #include "systems/realizing.h" |
10 | #include "vector.h" | 11 | #include "vector.h" |
11 | 12 | ||
@@ -133,28 +134,34 @@ void ScriptingSystem::tick(double dt) | |||
133 | 134 | ||
134 | if (!*runnable.callable) | 135 | if (!*runnable.callable) |
135 | { | 136 | { |
136 | game_.getEntityManager().deleteEntity(entity); | 137 | killScript(entity); |
137 | } | 138 | } |
138 | } | 139 | } |
139 | } | 140 | } |
140 | 141 | ||
141 | void ScriptingSystem::killScript(id_type entity) | 142 | void ScriptingSystem::killScript(id_type entity) |
142 | { | 143 | { |
143 | if (game_.getEntityManager().hasComponent<RunnableComponent>(entity)) | 144 | auto& runnable = game_.getEntityManager(). |
145 | getComponent<RunnableComponent>(entity); | ||
146 | |||
147 | if (runnable.behavior) | ||
144 | { | 148 | { |
145 | game_.getEntityManager().deleteEntity(entity); | 149 | auto& automatable = game_.getEntityManager(). |
150 | getComponent<AutomatableComponent>(runnable.actor); | ||
151 | |||
152 | automatable.running = false; | ||
146 | } | 153 | } |
154 | |||
155 | game_.getEntityManager().deleteEntity(entity); | ||
147 | } | 156 | } |
148 | 157 | ||
149 | template <typename... Args> | 158 | template <typename... Args> |
150 | EntityManager::id_type ScriptingSystem::runScript( | 159 | sol::optional<EntityManager::id_type> ScriptingSystem::runScript( |
160 | std::string table, | ||
151 | std::string event, | 161 | std::string event, |
152 | id_type entity, | 162 | id_type entity, |
153 | Args&&... args) | 163 | Args&&... args) |
154 | { | 164 | { |
155 | auto& prototypable = game_.getEntityManager(). | ||
156 | getComponent<PrototypableComponent>(entity); | ||
157 | |||
158 | id_type script = game_.getEntityManager().emplaceEntity(); | 165 | id_type script = game_.getEntityManager().emplaceEntity(); |
159 | 166 | ||
160 | auto& runnable = game_.getEntityManager(). | 167 | auto& runnable = game_.getEntityManager(). |
@@ -171,7 +178,7 @@ EntityManager::id_type ScriptingSystem::runScript( | |||
171 | new sol::coroutine( | 178 | new sol::coroutine( |
172 | runnable.runner->state(). | 179 | runnable.runner->state(). |
173 | traverse_get<sol::function>( | 180 | traverse_get<sol::function>( |
174 | prototypable.prototypeId, | 181 | table, |
175 | event))); | 182 | event))); |
176 | 183 | ||
177 | if (!*runnable.callable) | 184 | if (!*runnable.callable) |
@@ -189,17 +196,58 @@ EntityManager::id_type ScriptingSystem::runScript( | |||
189 | throw std::runtime_error(e.what()); | 196 | throw std::runtime_error(e.what()); |
190 | } | 197 | } |
191 | 198 | ||
192 | return script; | 199 | if (*runnable.callable) |
200 | { | ||
201 | return { script }; | ||
202 | } else { | ||
203 | killScript(script); | ||
204 | |||
205 | return {}; | ||
206 | } | ||
207 | } | ||
208 | |||
209 | void ScriptingSystem::startBehavior(id_type entity) | ||
210 | { | ||
211 | auto& automatable = game_.getEntityManager(). | ||
212 | getComponent<AutomatableComponent>(entity); | ||
213 | |||
214 | sol::optional<id_type> script = | ||
215 | runScript( | ||
216 | automatable.table, | ||
217 | "Behavior", | ||
218 | entity); | ||
219 | |||
220 | if (script) | ||
221 | { | ||
222 | automatable.script = *script; | ||
223 | automatable.running = true; | ||
224 | |||
225 | auto& runnable = game_.getEntityManager(). | ||
226 | getComponent<RunnableComponent>(automatable.script); | ||
227 | |||
228 | runnable.behavior = true; | ||
229 | runnable.actor = entity; | ||
230 | } | ||
193 | } | 231 | } |
194 | 232 | ||
195 | EntityManager::id_type ScriptingSystem::runBehaviorScript(id_type entity) | 233 | void ScriptingSystem::stopBehavior(id_type entity) |
196 | { | 234 | { |
197 | return runScript("Behavior", entity); | 235 | auto& automatable = game_.getEntityManager(). |
236 | getComponent<AutomatableComponent>(entity); | ||
237 | |||
238 | if (automatable.running) | ||
239 | { | ||
240 | killScript(automatable.script); | ||
241 | } | ||
198 | } | 242 | } |
199 | 243 | ||
200 | void ScriptingSystem::onTouch(id_type entity, id_type player) | 244 | void ScriptingSystem::onTouch(id_type entity, id_type player) |
201 | { | 245 | { |
246 | auto& prototypable = game_.getEntityManager(). | ||
247 | getComponent<PrototypableComponent>(entity); | ||
248 | |||
202 | runScript( | 249 | runScript( |
250 | prototypable.prototypeId, | ||
203 | "OnTouch", | 251 | "OnTouch", |
204 | entity, | 252 | entity, |
205 | script_entity(player)); | 253 | script_entity(player)); |
diff --git a/src/systems/scripting.h b/src/systems/scripting.h index e330316..b119c3f 100644 --- a/src/systems/scripting.h +++ b/src/systems/scripting.h | |||
@@ -13,14 +13,20 @@ public: | |||
13 | 13 | ||
14 | void killScript(id_type entity); | 14 | void killScript(id_type entity); |
15 | 15 | ||
16 | id_type runBehaviorScript(id_type entity); | 16 | void startBehavior(id_type entity); |
17 | |||
18 | void stopBehavior(id_type entity); | ||
17 | 19 | ||
18 | void onTouch(id_type entity, id_type player); | 20 | void onTouch(id_type entity, id_type player); |
19 | 21 | ||
20 | private: | 22 | private: |
21 | 23 | ||
22 | template <typename... Args> | 24 | template <typename... Args> |
23 | id_type runScript(std::string event, id_type entity, Args&&... args); | 25 | sol::optional<id_type> runScript( |
26 | std::string table, | ||
27 | std::string event, | ||
28 | id_type entity, | ||
29 | Args&&... args); | ||
24 | 30 | ||
25 | sol::state engine_; | 31 | sol::state engine_; |
26 | }; | 32 | }; |