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; }
30 requires std::is_base_of_v<T, U>
31 Owned(Owned<U> &&other): Handle<T>(other) { other.ptr = nullptr; }
33 Owned &operator=(Owned &&other) { assign(std::move(other)); return *this; }
36 requires std::is_base_of_v<T, U>
37 Owned &operator=(Owned<U> &&other) { assign(std::move(other)); return *this; }
39 ~Owned() { destroy(); }
43 void assign(Owned<U> &&);
46 static Stage &get_stage(O &);
53 template<typename P, typename... Args>
54 Owned<T>::Owned(Handle<P> parent, Args &&... args)
57 AccessGuard::get_instance().check<AccessGuard::Create>();
61 throw std::invalid_argument("Owned::Owned");
63 Stage &stage = get_stage(*parent);
64 Pool<T> &pool = stage.get_pools().get_pool<T>();
65 bool first_created = !pool.get_capacity();
66 this->ptr = pool.create(parent, std::forward<Args>(args)...);
67 if constexpr(std::is_base_of_v<Component, T>)
70 stage.get_reflector().get_or_create_class<T>().template set_polymorphic_base<Component>(**this);
71 parent->add_component(*this);
72 stage.get_event_source().emit<Events::ComponentCreated>(*this);
77 stage.get_reflector().get_or_create_class<T>().template set_polymorphic_base<Entity>(**this);
78 parent->add_child(*this);
79 stage.get_event_source().emit<Events::EntityCreated>(*this);
85 void Owned<T>::assign(Owned<U> &&other)
89 this->ptr = other.ptr;
95 Stage &Owned<T>::get_stage(O &obj)
97 if constexpr(std::is_base_of_v<Component, O>)
98 return get_stage(*obj.get_entity());
100 return obj.get_stage();
104 void Owned<T>::destroy()
106 T *obj = this->get();
111 AccessGuard::get_instance().check<AccessGuard::Destroy>();
114 Stage &stage = get_stage(*obj);
116 if constexpr(std::is_base_of_v<Component, T>)
118 stage.get_event_source().emit<Events::ComponentDestroyed>(*this);
119 obj->get_entity()->remove_component(*this);
121 else if(auto parent = obj->get_parent().get())
123 stage.get_event_source().emit<Events::EntityDestroyed>(*this);
124 parent->remove_child(*this);
127 Pool<T> &pool = stage.get_pools().get_pool<T>();
128 pool.destroy(this->ptr);
131 } // namespace Msp::Game