X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Fgame%2Fowned.h;h=d6f9f17a9ce170d7456dbafe08b3e53fe1a29418;hb=f377d216dfc44e36da3697557f38dfedcbec45d1;hp=df3cd94f2fde19079742f1a317be059b576e672d;hpb=248d62f7240d342982ade65a510be912b867fe49;p=libs%2Fgame.git diff --git a/source/game/owned.h b/source/game/owned.h index df3cd94..d6f9f17 100644 --- a/source/game/owned.h +++ b/source/game/owned.h @@ -2,14 +2,15 @@ #define MSP_GAME_OWNED_H_ #include +#include "accessguard.h" +#include "events.h" #include "handle.h" +#include "stage.h" namespace Msp::Game { class Component; class Entity; -class Root; -class Stage; template class Owned: public Handle @@ -17,11 +18,15 @@ class Owned: public Handle public: Owned() = default; - template - Owned(Handle, Args &&...); + template + Owned(Handle

, Args &&...); - template - Owned(Entity &parent, Args &&... args): Owned(Handle::from_object(&parent), std::forward(args)...) { } + template + Owned(Owned

&p, Args &&... a): Owned(static_cast &>(p), std::forward(a)...) { } + + template + requires(!std::is_const_v

) + Owned(P &parent, Args &&... args): Owned(Handle

::from_object(&parent), std::forward(args)...) { } Owned(Owned &&other): Handle(other) { other.ptr = nullptr; } Owned &operator=(Owned &&other); @@ -36,21 +41,34 @@ private: template -template -Owned::Owned(Handle parent, Args &&... args) +template +Owned::Owned(Handle

parent, Args &&... args) { +#ifdef DEBUG + AccessGuard::get_instance().check(); +#endif + if(!parent) throw std::invalid_argument("Owned::Owned"); - using DependentEntity = std::conditional_t; - Handle dparent = parent; - - Pool &pool = get_stage(*dparent).get_pools().template get_pool(); + Stage &stage = get_stage(*parent); + Pool &pool = stage.get_pools().get_pool(); + bool first_created = !pool.get_capacity(); this->ptr = pool.create(parent, std::forward(args)...); if constexpr(std::is_base_of_v) - dparent->add_component(*this); + { + if(first_created) + stage.get_reflector().get_or_create_class().template set_polymorphic_base(**this); + parent->add_component(*this); + stage.get_event_source().emit(*this); + } else - dparent->add_child(*this); + { + if(first_created) + stage.get_reflector().get_or_create_class().template set_polymorphic_base(**this); + parent->add_child(*this); + stage.get_event_source().emit(*this); + } } template @@ -68,13 +86,10 @@ template template Stage &Owned::get_stage(O &obj) { - using DependentRoot = std::conditional_t; if constexpr(std::is_base_of_v) return get_stage(*obj.get_entity()); - else if constexpr(std::is_base_of_v) - return dynamic_cast(*obj.get_root()).get_stage(); else - return obj; + return obj.get_stage(); } template @@ -84,13 +99,24 @@ void Owned::destroy() if(!obj) return; - Pool &pool = get_stage(*obj).get_pools().template get_pool(); +#ifdef DEBUG + AccessGuard::get_instance().check(); +#endif + + Stage &stage = get_stage(*obj); if constexpr(std::is_base_of_v) + { + stage.get_event_source().emit(*this); obj->get_entity()->remove_component(*this); + } else if(auto parent = obj->get_parent().get()) + { + stage.get_event_source().emit(*this); parent->remove_child(*this); + } + Pool &pool = stage.get_pools().get_pool(); pool.destroy(this->ptr); }