4 #include <unordered_map>
5 #include <unordered_set>
8 #include "default_init_ptr.h"
11 #include "../logging.h"
12 #include "../signals/signal.h"
13 #include "../macros.h"
17 const bool DONT_REFCOUNT =
false;
18 const bool DO_REFCOUNT =
true;
20 namespace _object_manager_impl {
26 static uint32_t next_id() {
27 static uint32_t
id = 0;
32 template<
typename IDType,
typename ObjectType,
typename ObjectTypePtrType,
typename SmartPo
interConverter>
36 typedef ObjectTypePtrType ObjectTypePtr;
37 typedef typename ObjectTypePtrType::element_type object_type;
39 virtual void update() = 0;
41 uint32_t count()
const {
42 return objects_.size();
46 ObjectTypePtrType clone(IDType
id,
this_type* target_manager=
nullptr) {
48 target_manager =
this;
51 auto source = get(
id);
52 auto copy = target_manager->make(&source->asset_manager());
58 template<
typename... Args>
59 ObjectTypePtrType make(Args&&... args) {
60 return make_as<ObjectType>(std::forward<Args>(args)...);
63 template<
typename T,
typename... Args>
64 ObjectTypePtrType make_as(Args&&... args) {
65 IDType new_id(next_id());
67 S_DEBUG(
"Creating a new object with ID: {0}", new_id);
68 auto obj = T::create(new_id, std::forward<Args>(args)...);
70 S_DEBUG(
"Binding ID pointer");
71 obj->_bind_id_pointer(obj);
73 objects_.insert(std::make_pair(obj->id(), obj));
75 S_DEBUG(
"Calling on_make()");
79 return SmartPointerConverter::convert(obj);
82 void destroy(IDType
id) {
88 for(
auto& p: objects_) {
95 ObjectTypePtr get(IDType
id)
const {
96 auto it = objects_.find(
id);
97 if(it == objects_.end()) {
98 return ObjectTypePtr();
101 return SmartPointerConverter::convert(it->second);
104 bool contains(IDType
id)
const {
105 return objects_.count(
id) > 0;
108 void each(std::function<
void (uint32_t, ObjectTypePtr)> callback) {
110 for(
auto& p: objects_) {
112 callback(i++, SmartPointerConverter::convert(ptr));
116 void each(std::function<
void (uint32_t,
const ObjectTypePtr)> callback)
const {
118 for(
auto& p: objects_) {
120 callback(i++, SmartPointerConverter::convert(ptr));
124 ObjectTypePtr find_object(
const std::string& name)
const {
125 for(
auto& p: objects_) {
126 if(p.second->name() == name) {
131 return ObjectTypePtr();
139 typedef std::shared_ptr<ObjectType> ObjectTypeInternalPtrType;
142 IDType, ObjectTypeInternalPtrType
145 sig::signal<void (ObjectType&, IDType)> signal_post_create_;
146 sig::signal<void (ObjectType&, IDType)> signal_pre_destroy_;
148 virtual void on_make(IDType
id) {
152 virtual void on_get(IDType
id) {
156 virtual void on_destroy(IDType
id) {
164 static std::shared_ptr<T> convert(std::shared_ptr<T> ptr) {
179 template<
typename IDType,
typename ObjectType,
bool RefCounted>
182 template<
typename IDType,
typename ObjectType>
185 IDType, ObjectType, default_init_ptr<ObjectType>,
186 _object_manager_impl::ToDefaultInitPtr<ObjectType>
195 typedef typename parent_class::object_type object_type;
197 void update()
override {}
200 enum GarbageCollectMethod {
201 GARBAGE_COLLECT_NEVER,
202 GARBAGE_COLLECT_PERIODIC
205 template<
typename IDType,
typename ObjectType>
208 IDType, ObjectType, std::shared_ptr<ObjectType>,
209 _object_manager_impl::ToSharedPtr<ObjectType>
217 typedef typename parent_class::ObjectTypePtr ObjectTypePtr;
218 typedef typename parent_class::object_type object_type;
220 void update()
override {
221 for(
auto it = this->objects_.begin(); it != this->objects_.end();) {
222 ObjMeta meta = object_metas_.at(it->first);
223 bool collect = meta.collection_method == GARBAGE_COLLECT_PERIODIC;
225 if(collect && it->second.unique()) {
228 on_destroy(it->first);
229 it = this->objects_.erase(it);
236 void set_garbage_collection_method(IDType
id, GarbageCollectMethod method) {
237 auto& meta = object_metas_.at(
id);
238 meta.collection_method = method;
239 if(method != GARBAGE_COLLECT_NEVER) {
240 meta.created = std::chrono::system_clock::now();
245 typedef std::chrono::time_point<std::chrono::system_clock> date_time;
249 created(std::chrono::system_clock::now()) {}
251 GarbageCollectMethod collection_method = GARBAGE_COLLECT_PERIODIC;
255 std::unordered_map<IDType, ObjMeta> object_metas_;
257 void on_make(IDType
id)
override {
258 object_metas_.insert(std::make_pair(
id, ObjMeta()));
261 void on_destroy(IDType
id)
override {
262 S_DEBUG(
"Garbage collecting {0}",
id);
264 object_metas_.erase(
id);