Simulant  21.12-194
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 #include "ui/frame.h"
16 #include "ui/keyboard.h"
17 
18 #define STAGE_NODE_MANAGER_DEBUG 0
19 
20 namespace smlt {
21 
22 
23 template<typename PoolType, typename IDType, typename T, typename ...Subtypes>
25 public:
26  typedef StageNodeManager<PoolType, IDType, T, Subtypes...> this_type;
27 
28  StageNodeManager(PoolType* pool):
29  pool_(pool) {}
30 
31  ~StageNodeManager() {
32  clear();
33  }
34 
35  const PoolType* pool() const {
36  return pool_;
37  }
38 
39  template<typename Derived, typename... Args>
40  Derived* make_as(Args&&... args) {
41  auto pair = pool_->template create<Derived>(
42  std::forward<Args>(args)...
43  );
44 
45  Derived* derived = pair.first;
46  assert(derived);
47 
48  derived->_overwrite_id(IDType(pair.second));
49  derived->_bind_id_pointer(derived);
50 
51  if(!derived->init()) {
52  derived->clean_up();
53  pool_->erase(pool_->find(pair.second));
55  }
56 
57  objects_.push_back(derived);
58 
59  return derived;
60  }
61 
62  template<typename... Args>
63  T* make(Args&&... args) {
64  return make_as<T>(std::forward<Args>(args)...);
65  }
66 
67  bool contains(const IDType& id) const {
68  return bool(get(id));
69  }
70 
71  T* get(const IDType& id) const {
72  StageNode* node = (*pool_)[id.value()];
73  T* result = dynamic_cast<T*>(node);
74 #if STAGE_NODE_MANAGER_DEBUG
75  assert((node && result) || (!node && !result));
76 #endif
77  return result;
78  }
79 
80  T* clone(const IDType& id, this_type* target_manager=nullptr) {
81  T* source = get(id);
82  return target_manager->make(*source);
83  }
84 
85  bool destroy(const IDType& id) {
86  auto it = pool_->find(id.value());
87  if(it != pool_->end()) {
88  /* Ensure we fire the destroyed signal */
89  if(!(*it)->destroyed_) {
90  (*it)->signal_destroyed()();
91  (*it)->destroyed_ = true;
92  }
93 
94  queued_for_destruction_.insert(id);
95  return true;
96  } else {
97  return false;
98  }
99  }
100 
101  void clear() {
102  destroy_all();
103  clean_up();
104  }
105 
106  void destroy_all() {
107  destroy_all_next_clean_ = true;
108  }
109 
110  bool destroy_immediately(const IDType& id) {
111  auto it = pool_->find(id.value());
112  if(it != pool_->end()) {
113  StageNode* node = *it;
114 
115  /* Ensure we fire the destroyed signal */
116  if(!(*it)->destroyed_) {
117  (*it)->signal_destroyed()();
118  (*it)->destroyed_ = true;
119  }
120 
121  T* a = dynamic_cast<T*>(node);
122  assert((node && a) || (!node && !a));
123 
124  a->clean_up();
125 
126  objects_.remove(a);
127  pool_->erase(it);
128  queued_for_destruction_.erase(id);
129  return true;
130  }
131  return false;
132  }
133 
134  void clean_up() {
135  if(destroy_all_next_clean_) {
136  destroy_all_next_clean_ = false;
137  for(auto ptr: objects_) {
138  ptr->clean_up();
139  pool_->erase(pool_->find(ptr->id().value()));
140  }
141  objects_.clear();
142  } else {
143  auto queued = queued_for_destruction_;
144  for(auto i: queued) {
145  destroy_immediately(i);
146  }
147  }
148  queued_for_destruction_.clear();
149  }
150 
151  std::size_t size() const {
152  return objects_.size();
153  }
154 
155  typename std::list<T*>::iterator begin() {
156  return objects_.begin();
157  }
158 
159  typename std::list<T*>::iterator end() {
160  return objects_.end();
161  }
162 
163 private:
164  PoolType* pool_ = nullptr;
165  std::list<T*> objects_;
166  std::set<IDType> queued_for_destruction_;
167  bool destroy_all_next_clean_ = false;
168 };
169 
170 }
smlt
Definition: animation.cpp:25
smlt::InstanceInitializationError
Definition: managed.h:29
smlt::StageNodeManager
Definition: stage_node_manager.h:24
smlt::StageNode
Definition: stage_node.h:61