Simulant  21.09-46
A portable game engine for Windows, OSX, Linux, Dreamcast, and PSP
stage_node_manager.h
1 #pragma once
2 
3 #include "../generic/containers/polylist.h"
4 
5 #include "actor.h"
6 #include "camera.h"
7 #include "geom.h"
8 #include "light.h"
9 #include "particle_system.h"
10 #include "sprite.h"
11 #include "ui/button.h"
12 #include "ui/image.h"
13 #include "ui/label.h"
14 #include "ui/progress_bar.h"
15 
16 namespace smlt {
17 
18 
19 template<typename PoolType, typename IDType, typename T, typename ...Subtypes>
21 public:
22  typedef StageNodeManager<PoolType, IDType, T, Subtypes...> this_type;
23 
24  StageNodeManager(PoolType* pool):
25  pool_(pool) {}
26 
27  ~StageNodeManager() {
28  clear();
29  }
30 
31  const PoolType* pool() const {
32  return pool_;
33  }
34 
35  template<typename Derived, typename... Args>
36  Derived* make_as(Args&&... args) {
37  auto pair = pool_->template create<Derived>(
38  std::forward<Args>(args)...
39  );
40 
41  Derived* derived = pair.first;
42  assert(derived);
43 
44  derived->_overwrite_id(IDType(pair.second));
45  derived->_bind_id_pointer(derived);
46 
47  if(!derived->init()) {
48  derived->clean_up();
49  pool_->erase(pool_->find(pair.second));
51  }
52 
53  objects_.push_back(derived);
54 
55  return derived;
56  }
57 
58  template<typename... Args>
59  T* make(Args&&... args) {
60  return make_as<T>(std::forward<Args>(args)...);
61  }
62 
63  bool contains(const IDType& id) const {
64  return bool(get(id));
65  }
66 
67  T* get(const IDType& id) const {
68  StageNode* node = (*pool_)[id.value()];
69  T* result = dynamic_cast<T*>(node);
70  assert((node && result) || (!node && !result));
71  return result;
72  }
73 
74  T* clone(const IDType& id, this_type* target_manager=nullptr) {
75  T* source = get(id);
76  return target_manager->make(*source);
77  }
78 
79  bool destroy(const IDType& id) {
80  auto it = pool_->find(id.value());
81  if(it != pool_->end()) {
82  get(id)->is_marked_for_destruction_ = true;
83  queued_for_destruction_.insert(id);
84  return true;
85  } else {
86  return false;
87  }
88  }
89 
90  void clear() {
91  destroy_all();
92  clean_up();
93  }
94 
95  void destroy_all() {
96  destroy_all_next_clean_ = true;
97  }
98 
99  bool destroy_immediately(const IDType& id) {
100  auto it = pool_->find(id.value());
101  if(it != pool_->end()) {
102  StageNode* node = *it;
103  T* a = dynamic_cast<T*>(node);
104  assert((node && a) || (!node && !a));
105 
106  a->clean_up();
107 
108  objects_.remove(a);
109  pool_->erase(it);
110  queued_for_destruction_.erase(id);
111  return true;
112  }
113  return false;
114  }
115 
116  void clean_up() {
117  if(destroy_all_next_clean_) {
118  destroy_all_next_clean_ = false;
119  for(auto ptr: objects_) {
120  ptr->clean_up();
121  pool_->erase(pool_->find(ptr->id().value()));
122  }
123  objects_.clear();
124  } else {
125  auto queued = queued_for_destruction_;
126  for(auto i: queued) {
127  destroy_immediately(i);
128  }
129  }
130  queued_for_destruction_.clear();
131  }
132 
133  bool is_marked_for_destruction(const IDType& id) const {
134  auto obj = get(id);
135  if(obj) {
136  return obj->is_marked_for_destruction_;
137  }
138 
139  return false;
140  }
141 
142  std::size_t size() const {
143  return objects_.size();
144  }
145 
146  typename std::list<T*>::iterator begin() {
147  return objects_.begin();
148  }
149 
150  typename std::list<T*>::iterator end() {
151  return objects_.end();
152  }
153 
154 private:
155  PoolType* pool_ = nullptr;
156  std::list<T*> objects_;
157  std::set<IDType> queued_for_destruction_;
158  bool destroy_all_next_clean_ = false;
159 };
160 
161 }
smlt
Definition: animation.cpp:25
smlt::InstanceInitializationError
Definition: managed.h:29
smlt::StageNodeManager
Definition: stage_node_manager.h:20
smlt::StageNode
Definition: stage_node.h:60