]> git.tdb.fi Git - libs/game.git/blob - source/game/stage.cpp
Enforce no creation or destruction of objects during tick
[libs/game.git] / source / game / stage.cpp
1 #include "stage.h"
2 #include "accessguard.h"
3 #include "camera.h"
4 #include "root.h"
5 #include "system.h"
6
7 using namespace std;
8
9 namespace Msp::Game {
10
11 Stage::Stage(DataFile::Collection &r):
12         resources(r),
13         event_source(event_bus),
14         event_observer(event_bus),
15         root(std::make_unique<Root>(*this))
16 {
17         event_observer.observe<Events::ComponentCreated>([this](auto &e){
18                 if(!active_camera)
19                         if(Handle<Camera> camera = dynamic_handle_cast<Camera>(e.component))
20                                 set_active_camera(camera);
21         });
22 }
23
24 // Hide unique_ptr destructors from the header
25 Stage::~Stage()
26 { }
27
28 void Stage::remove_system(System &s)
29 {
30         erase_if(systems, [&s](auto &p){ return p.get()==&s; });
31 }
32
33 void Stage::set_active_camera(Handle<Camera> c)
34 {
35         active_camera = c;
36         event_source.emit<Events::CameraChanged>(active_camera);
37 }
38
39 void Stage::synthesize_initial_events(EventObserver &target_observer)
40 {
41         synthesize_initial_events(Handle<Entity>::from_object(root.get()), target_observer);
42         if(active_camera)
43                 event_source.emit_to<Events::CameraChanged>(target_observer, active_camera);
44 }
45
46 void Stage::synthesize_initial_events(Handle<Entity> entity, EventObserver &target_observer)
47 {
48         for(Handle<Component> c: entity->get_components())
49                 event_source.emit_to<Events::ComponentCreated>(target_observer, c);
50         for(Handle<Entity> e: entity->get_children())
51                 synthesize_initial_events(e, target_observer);
52         event_source.emit_to<Events::EntityCreated>(target_observer, entity);
53 }
54
55 void Stage::tick(Time::TimeDelta dt)
56 {
57         {
58 #ifdef DEBUG
59                 AccessGuard::BlockForScope _block;;
60 #endif
61                 for(const auto &s: systems)
62                         s->tick(dt);
63         }
64
65         for(const auto &s: systems)
66                 s->deferred_tick();
67 }
68
69 } // namespace Msp::Game