X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Fgame%2Fowned.h;h=a30f040d58269019cd3634159100e7d2f8a976c3;hb=c71b8c2151e097f435c8f76ffa123cc71f9d12ec;hp=e20ff775b61ed557201f4af40bb9244912d8452e;hpb=b644c89c81d89f60a0d82fe208fc76ce1c278a4c;p=libs%2Fgame.git diff --git a/source/game/owned.h b/source/game/owned.h index e20ff77..a30f040 100644 --- a/source/game/owned.h +++ b/source/game/owned.h @@ -2,6 +2,8 @@ #define MSP_GAME_OWNED_H_ #include +#include "accessguard.h" +#include "events.h" #include "handle.h" #include "stage.h" @@ -20,13 +22,26 @@ public: Owned(Handle

, Args &&...); template - Owned(P &parent, Args &&... args): Owned(Handle

::from_object(&parent), std::forward(args)...) { } + 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); + + template + requires std::is_base_of_v + Owned(Owned &&other): Handle(other) { other.ptr = nullptr; } + + Owned &operator=(Owned &&other) { assign(std::move(other)); return *this; } + + template + requires std::is_base_of_v + Owned &operator=(Owned &&other) { assign(std::move(other)); return *this; } + ~Owned() { destroy(); } private: + template + void assign(Owned &&); + template static Stage &get_stage(O &); @@ -38,26 +53,41 @@ template template Owned::Owned(Handle

parent, Args &&... args) { +#ifdef DEBUG + AccessGuard::get_instance().check(); +#endif + if(!parent) throw std::invalid_argument("Owned::Owned"); - Pool &pool = get_stage(*parent).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) + { + 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 + { + 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 -Owned &Owned::operator=(Owned &&other) +template +void Owned::assign(Owned &&other) { destroy(); this->ptr = other.ptr; other.ptr = nullptr; - - return *this; } template @@ -77,13 +107,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); }