X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Fgame%2Fstage.h;h=0c2219bdc18b1d893851ed91467677c5a35fc4b1;hb=e4f03880d49bdbe0c7269be0f40f23b197bcea77;hp=060759696914264ce5c177c0d1674a154b253e52;hpb=248d62f7240d342982ade65a510be912b867fe49;p=libs%2Fgame.git diff --git a/source/game/stage.h b/source/game/stage.h index 0607596..0c2219b 100644 --- a/source/game/stage.h +++ b/source/game/stage.h @@ -2,27 +2,52 @@ #define MSP_GAME_STAGE_H_ #include +#include #include +#include "eventbus.h" +#include "events.h" +#include "eventsource.h" #include "handle.h" -#include "root.h" +#include "reflection.h" +#include "systemscheduler.h" namespace Msp::Game { +class Camera; +class Root; class System; class Stage { +public: + using EventSource = Game::EventSource; + private: + Reflection::Reflector &reflector; + DataFile::Collection &resources; PoolPool pools; - Root root; + EventBus event_bus; + EventSource event_source; + EventObserver event_observer; + /* Use unique_ptr because there's only one root per stage so it's pointless + to put it in a pool. */ + std::unique_ptr root; std::vector> systems; + SystemScheduler scheduler; + Handle active_camera; + bool pending_reschedule = false; public: - Stage(); + Stage(Reflection::Reflector &, DataFile::Collection &); ~Stage(); + Reflection::Reflector &get_reflector() const { return reflector; } + DataFile::Collection &get_resources() const { return resources; } PoolPool &get_pools() { return pools; } - Handle get_root() { return Handle::from_object(&root); } + EventBus &get_event_bus() { return event_bus; } + EventSource &get_event_source() { return event_source; } + Handle get_root() { return Handle::from_object(root.get()); } template void iterate_objects(const F &); @@ -30,22 +55,48 @@ public: template T &add_system(Args &&...); + void remove_system(System &); const std::vector> &get_systems() const { return systems; } + template + T *get_system() const; + + void set_active_camera(Handle); + Handle get_active_camera() const { return active_camera; } + + void synthesize_initial_events(EventObserver &); +private: + void synthesize_initial_events(Handle, EventObserver &); + +public: void tick(Time::TimeDelta); }; template -void Stage::iterate_objects(const F &func) +inline void Stage::iterate_objects(const F &func) { pools.get_pool().iterate_objects(func); } template -T &Stage::add_system(Args &&... args) +inline T &Stage::add_system(Args &&... args) +{ + // Ensure that a reflected class exists for scheduling + reflector.get_or_create_class(); + + auto &sys = systems.emplace_back(std::make_unique(*this, std::forward(args)...)); + scheduler.add_system(*sys); + pending_reschedule = true; + return static_cast(*sys); +} + +template +inline T *Stage::get_system() const { - systems.emplace_back(std::make_unique(*this, std::forward(args)...)); - return static_cast(*systems.back()); + for(const auto &s: systems) + if(T *ts = dynamic_cast(s.get())) + return ts; + return nullptr; } } // namespace Msp::Game