X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Fgame%2Fstage.cpp;h=3888410a43c8bc976034b753693b56ab35f16d72;hb=e4f03880d49bdbe0c7269be0f40f23b197bcea77;hp=a616d5a94da775ebd61da5171e9b4baf2435215d;hpb=c7d0e1aff305778f97974b329826628966380158;p=libs%2Fgame.git diff --git a/source/game/stage.cpp b/source/game/stage.cpp index a616d5a..3888410 100644 --- a/source/game/stage.cpp +++ b/source/game/stage.cpp @@ -1,25 +1,92 @@ #include "stage.h" +#include +#include +#include "accessguard.h" +#include "camera.h" #include "root.h" #include "system.h" +using namespace std; + namespace Msp::Game { -Stage::Stage(): - root(std::make_unique(*this)) -{ } +Stage::Stage(Reflection::Reflector &f, DataFile::Collection &r): + reflector(f), + resources(r), + event_source(event_bus), + event_observer(event_bus), + root(std::make_unique(*this)), + scheduler(reflector) +{ + event_observer.observe([this](auto &e){ + if(!active_camera) + if(Handle camera = dynamic_handle_cast(e.component)) + set_active_camera(camera); + }); +} // Hide unique_ptr destructors from the header Stage::~Stage() { } +void Stage::remove_system(System &s) +{ + scheduler.remove_system(s); + erase_if(systems, [&s](auto &p){ return p.get()==&s; }); + pending_reschedule = true; +} + +void Stage::set_active_camera(Handle c) +{ + active_camera = c; + event_source.emit(active_camera); +} + +void Stage::synthesize_initial_events(EventObserver &target_observer) +{ + synthesize_initial_events(Handle::from_object(root.get()), target_observer); + if(active_camera) + event_source.emit_to(target_observer, active_camera); +} + +void Stage::synthesize_initial_events(Handle entity, EventObserver &target_observer) +{ + for(Handle c: entity->get_components()) + event_source.emit_to(target_observer, c); + for(Handle e: entity->get_children()) + synthesize_initial_events(e, target_observer); + event_source.emit_to(target_observer, entity); +} + void Stage::tick(Time::TimeDelta dt) { + if(pending_reschedule) + { + scheduler.schedule(); + pending_reschedule = false; + } + + { +#ifdef DEBUG + AccessGuard::BlockForScope _block; +#endif + for(const SystemScheduler::Group &g: scheduler.get_groups()) + for(System *s: g.systems) + { + System::Activator act(*s); + try + { + s->tick(dt); + } + catch(const invalid_access &exc) + { + throw invalid_access(format("%s by %s", exc.what(), Debug::demangle(typeid(*s).name()))); + } + } + } + for(const auto &s: systems) - s->pre_tick(); - for(const auto &s: systems) - s->tick(dt); - for(const auto &s: systems) - s->post_tick(); + s->deferred_tick(); } } // namespace Msp::Game