1 #ifndef MSP_GAME_OWNED_H_
2 #define MSP_GAME_OWNED_H_
5 #include "accessguard.h"
16 class Owned: public Handle<T>
21 template<typename P, typename... Args>
22 Owned(Handle<P>, Args &&...);
24 template<typename P, typename... Args>
25 Owned(P *parent, Args &&... args): Owned(Handle<P>::from_object(parent), std::forward<Args>(args)...) { }
27 Owned(Owned &&other): Handle<T>(other) { other.ptr = nullptr; }
28 Owned &operator=(Owned &&other);
29 ~Owned() { destroy(); }
33 static Stage &get_stage(O &);
40 template<typename P, typename... Args>
41 Owned<T>::Owned(Handle<P> parent, Args &&... args)
44 AccessGuard::get_instance().check<AccessGuard::Create>();
48 throw std::invalid_argument("Owned::Owned");
50 Stage &stage = get_stage(*parent);
51 Pool<T> &pool = stage.get_pools().get_pool<T>();
52 bool first_created = !pool.get_capacity();
53 this->ptr = pool.create(parent, std::forward<Args>(args)...);
54 if constexpr(std::is_base_of_v<Component, T>)
57 stage.get_reflector().get_or_create_class<T>().template set_polymorphic_base<Component>(**this);
58 parent->add_component(*this);
59 stage.get_event_source().emit<Events::ComponentCreated>(*this);
64 stage.get_reflector().get_or_create_class<T>().template set_polymorphic_base<Entity>(**this);
65 parent->add_child(*this);
66 stage.get_event_source().emit<Events::EntityCreated>(*this);
71 Owned<T> &Owned<T>::operator=(Owned &&other)
75 this->ptr = other.ptr;
83 Stage &Owned<T>::get_stage(O &obj)
85 if constexpr(std::is_base_of_v<Component, O>)
86 return get_stage(*obj.get_entity());
88 return obj.get_stage();
92 void Owned<T>::destroy()
99 AccessGuard::get_instance().check<AccessGuard::Destroy>();
102 Stage &stage = get_stage(*obj);
104 if constexpr(std::is_base_of_v<Component, T>)
106 stage.get_event_source().emit<Events::ComponentDestroyed>(*this);
107 obj->get_entity()->remove_component(*this);
109 else if(auto parent = obj->get_parent().get())
111 stage.get_event_source().emit<Events::EntityDestroyed>(*this);
112 parent->remove_child(*this);
115 Pool<T> &pool = stage.get_pools().get_pool<T>();
116 pool.destroy(this->ptr);
119 } // namespace Msp::Game