From c3ac50ad3e79b26d1d99bd222a7e43adb86c2c1e Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Wed, 26 Oct 2022 00:17:06 +0300 Subject: [PATCH] Make it possible to retrieve components and systems of a particular type --- source/game/entity.h | 15 ++++++++++++++- source/game/handle.h | 7 +++++++ source/game/stage.h | 16 ++++++++++++++-- 3 files changed, 35 insertions(+), 3 deletions(-) diff --git a/source/game/entity.h b/source/game/entity.h index c28cbe5..c4cf83c 100644 --- a/source/game/entity.h +++ b/source/game/entity.h @@ -36,6 +36,11 @@ public: void add_component(Handle); void remove_component(Handle); + template + Handle get_component(); + + Handle get_transform() const { return transform; } + void add_child(Handle); void remove_child(Handle); @@ -43,10 +48,18 @@ public: Handle get_root(); const std::vector> &get_children() const { return children; } Stage &get_stage(); - Handle get_transform() const { return transform; } }; +template +inline Handle Entity::get_component() +{ + for(Handle c: components) + if(Handle tc = dynamic_handle_cast(c)) + return tc; + return nullptr; +} + inline Handle Entity::get_root() { Handle e = Handle::from_object(this); diff --git a/source/game/handle.h b/source/game/handle.h index 2e544c7..b08bcf8 100644 --- a/source/game/handle.h +++ b/source/game/handle.h @@ -39,6 +39,13 @@ public: bool operator==(const Handle &other) const = default; }; +template + requires std::is_base_of_v +Handle dynamic_handle_cast(Handle h) +{ + return Handle::from_object(dynamic_cast(h.get())); +} + } // namespace Msp::Game #endif diff --git a/source/game/stage.h b/source/game/stage.h index 80e7a4b..d7793e2 100644 --- a/source/game/stage.h +++ b/source/game/stage.h @@ -45,22 +45,34 @@ public: const std::vector> &get_systems() const { return systems; } + template + T *get_system() const; + 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) { systems.emplace_back(std::make_unique(*this, std::forward(args)...)); return static_cast(*systems.back()); } +template +inline T *Stage::get_system() const +{ + for(const auto &s: systems) + if(T *ts = dynamic_cast(s.get())) + return ts; + return nullptr; +} + } // namespace Msp::Game #endif -- 2.43.0