2 #include <msp/debug/demangle.h>
3 #include <msp/strings/format.h>
4 #include "accessguard.h"
13 Stage::Stage(Reflection::Reflector &f, DataFile::Collection &r):
16 event_source(event_bus),
17 event_observer(event_bus),
18 root(std::make_unique<Root>(*this)),
21 event_observer.observe<Events::ComponentCreated>([this](auto &e){
23 if(Handle<Camera> camera = dynamic_handle_cast<Camera>(e.component))
24 set_active_camera(camera);
28 // Hide unique_ptr destructors from the header
32 void Stage::remove_system(System &s)
34 scheduler.remove_system(s);
35 erase_if(systems, [&s](auto &p){ return p.get()==&s; });
36 pending_reschedule = true;
39 void Stage::set_active_camera(Handle<Camera> c)
42 event_source.emit<Events::CameraChanged>(active_camera);
45 void Stage::synthesize_initial_events(EventObserver &target_observer)
47 synthesize_initial_events(Handle<Entity>::from_object(root.get()), target_observer);
49 event_source.emit_to<Events::CameraChanged>(target_observer, active_camera);
52 void Stage::synthesize_initial_events(Handle<Entity> entity, EventObserver &target_observer)
54 for(Handle<Component> c: entity->get_components())
55 event_source.emit_to<Events::ComponentCreated>(target_observer, c);
56 for(Handle<Entity> e: entity->get_children())
57 synthesize_initial_events(e, target_observer);
58 event_source.emit_to<Events::EntityCreated>(target_observer, entity);
61 void Stage::tick(Time::TimeDelta dt)
63 if(pending_reschedule)
66 pending_reschedule = false;
71 AccessGuard::BlockForScope _block;
73 for(const SystemScheduler::Group &g: scheduler.get_groups())
74 for(System *s: g.systems)
76 System::Activator act(*s);
81 catch(const invalid_access &exc)
83 throw invalid_access(format("%s by %s", exc.what(), Debug::demangle(typeid(*s).name())));
88 for(const auto &s: systems)
92 } // namespace Msp::Game