4 #include <unordered_map>
5 #include <unordered_set>
8 #include "../core/stage_node_id.h"
10 #include "../logging.h"
11 #include "../signals/signal.h"
12 #include "../macros.h"
16 const bool DONT_REFCOUNT =
false;
17 const bool DO_REFCOUNT =
true;
19 namespace _object_manager_impl {
25 static uint32_t next_id() {
26 static uint32_t
id = 0;
31 template<
typename IDType,
typename ObjectType,
typename ObjectTypePtrType,
typename SmartPo
interConverter>
35 typedef ObjectTypePtrType ObjectTypePtr;
36 typedef typename ObjectTypePtrType::element_type object_type;
41 virtual void update() = 0;
43 uint32_t count()
const {
44 return objects_.size();
48 ObjectTypePtrType clone(IDType
id,
this_type* target_manager=
nullptr) {
50 target_manager =
this;
53 auto source = get(
id);
54 auto copy = target_manager->make(&source->asset_manager());
60 template<
typename... Args>
61 ObjectTypePtrType make(Args&&... args) {
62 return make_as<ObjectType>(std::forward<Args>(args)...);
65 template<
typename T,
typename... Args>
66 ObjectTypePtrType make_as(Args&&... args) {
67 IDType new_id(next_id());
69 S_DEBUG(
"Creating a new object with ID: {0}", new_id);
70 auto obj = T::create(new_id, std::forward<Args>(args)...);
71 objects_.insert(std::make_pair(obj->id(), obj));
74 return SmartPointerConverter::convert(obj);
77 void destroy(IDType
id) {
83 for(
auto& p: objects_) {
90 ObjectTypePtr get(IDType
id)
const {
91 auto it = objects_.find(
id);
92 if(it == objects_.end()) {
93 return ObjectTypePtr();
96 return SmartPointerConverter::convert(it->second);
99 bool contains(IDType
id)
const {
100 return objects_.count(
id) > 0;
103 void each(std::function<
void (uint32_t, ObjectTypePtr)> callback) {
105 for(
auto& p: objects_) {
107 callback(i++, SmartPointerConverter::convert(ptr));
111 void each(std::function<
void (uint32_t,
const ObjectTypePtr)> callback)
const {
113 for(
auto& p: objects_) {
115 callback(i++, SmartPointerConverter::convert(ptr));
119 ObjectTypePtr find_object(
const std::string& name)
const {
120 for(
auto& p: objects_) {
121 if(p.second->name() == name) {
126 return ObjectTypePtr();
134 typedef std::shared_ptr<ObjectType> ObjectTypeInternalPtrType;
137 IDType, ObjectTypeInternalPtrType
140 sig::signal<void (ObjectType&, IDType)> signal_post_create_;
141 sig::signal<void (ObjectType&, IDType)> signal_pre_destroy_;
143 virtual void on_make(IDType
id) {
147 virtual void on_get(IDType
id) {
151 virtual void on_destroy(IDType
id) {
159 static std::shared_ptr<T> convert(
const std::shared_ptr<T>& ptr) {
166 static T* convert(
const std::shared_ptr<T>& ptr) {
172 template<
typename IDType,
typename ObjectType,
bool RefCounted>
175 template<
typename IDType,
typename ObjectType>
178 IDType, ObjectType, ObjectType*,
179 _object_manager_impl::ToRawPtr<ObjectType>> {
183 IDType, ObjectType, ObjectType*,
187 typedef typename parent_class::ObjectTypePtr ObjectTypePtr;
188 typedef typename parent_class::object_type object_type;
190 void update()
override {}
193 enum GarbageCollectMethod {
194 GARBAGE_COLLECT_NEVER,
195 GARBAGE_COLLECT_PERIODIC
198 template<
typename IDType,
typename ObjectType>
201 IDType, ObjectType, std::shared_ptr<ObjectType>,
202 _object_manager_impl::ToSharedPtr<ObjectType>
210 typedef typename parent_class::ObjectTypePtr ObjectTypePtr;
211 typedef typename parent_class::object_type object_type;
213 void update()
override {
214 for(
auto it = this->objects_.begin(); it != this->objects_.end();) {
215 ObjMeta meta = object_metas_.at(it->first);
216 bool collect = meta.collection_method == GARBAGE_COLLECT_PERIODIC;
218 if(collect && it->second.unique()) {
221 on_destroy(it->first);
222 it = this->objects_.erase(it);
229 void set_garbage_collection_method(IDType
id, GarbageCollectMethod method) {
230 auto& meta = object_metas_.at(
id);
231 meta.collection_method = method;
232 if(method != GARBAGE_COLLECT_NEVER) {
233 meta.created = std::chrono::system_clock::now();
238 typedef std::chrono::time_point<std::chrono::system_clock> date_time;
242 created(std::chrono::system_clock::now()) {}
244 GarbageCollectMethod collection_method = GARBAGE_COLLECT_PERIODIC;
248 std::unordered_map<IDType, ObjMeta> object_metas_;
250 void on_make(IDType
id)
override {
251 object_metas_.insert(std::make_pair(
id, ObjMeta()));
254 void on_destroy(IDType
id)
override {
255 S_DEBUG(
"Garbage collecting {0}",
id);
257 object_metas_.erase(
id);