Simulant  21.12-1303
A portable game engine for Windows, OSX, Linux, Dreamcast, and PSP
scene.h
1 /* * Copyright (c) 2011-2017 Luke Benstead https://simulant-engine.appspot.com
2  *
3  * This file is part of Simulant.
4  *
5  * Simulant is free software: you can redistribute it and/or modify
6  * it under the terms of the GNU Lesser General Public License as published
7  * by the Free Software Foundation, either version 3 of the License, or (at your
8  * option) any later version.
9  *
10  * Simulant is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public License
16  * along with Simulant. If not, see <http://www.gnu.org/licenses/>.
17  */
18 
19 #ifndef SCENE_H
20 #define SCENE_H
21 
40 #include <set>
41 
42 #include "../asset_manager.h"
43 #include "../compositor.h"
44 #include "../generic/any/any.h"
45 #include "../generic/managed.h"
46 #include "../generic/property.h"
47 #include "../interfaces.h"
48 #include "../interfaces/nameable.h"
49 #include "../interfaces/updateable.h"
50 #include "../nodes/stage_node_manager.h"
51 #include "../nodes/stage_node_watch_controller.h"
52 #include "../types.h"
53 #include "../utils/unicode.h"
54 #include "simulant/utils/params.h"
55 
56 namespace smlt {
57 
58 class Application;
59 class Window;
60 class InputManager;
61 class SceneManager;
62 class Service;
63 
64 class SceneLoadException: public std::runtime_error {};
65 
66 typedef sig::signal<void()> SceneOnActivatedSignal;
68 
69 typedef sig::signal<void(StageNode*, StageNodeType)> StageNodeCreatedSignal;
70 typedef sig::signal<void(StageNode*, StageNodeType)> StageNodeDestroyedSignal;
71 
72 typedef sig::signal<void(Camera*, Viewport*, StageNode*)>
74 typedef sig::signal<void(Camera*, Viewport*, StageNode*)>
76 
78 public:
79  smlt::Color ambient_light() const {
80  return ambient_light_;
81  }
82 
83  void set_ambient_light(const smlt::Color& c) {
84  ambient_light_ = c;
85  }
86 
87 private:
88  smlt::Color ambient_light_;
89 };
90 
91 class Scene:
92  public StageNode,
93  public StageNodeManager,
95 
96  DEFINE_SIGNAL(SceneOnActivatedSignal, signal_activated);
97  DEFINE_SIGNAL(SceneOnDeactivatedSignal, signal_deactivated);
98 
99  DEFINE_SIGNAL(StageNodeCreatedSignal, signal_stage_node_created);
100  DEFINE_SIGNAL(StageNodeDestroyedSignal, signal_stage_node_destroyed);
101 
102  DEFINE_SIGNAL(LayerRenderStartedSignal, signal_layer_render_started);
103  DEFINE_SIGNAL(LayerRenderFinishedSignal, signal_layer_render_finished);
104 
105 public:
106  typedef std::shared_ptr<Scene> ptr;
107 
108  Scene(Window* window);
109  virtual ~Scene();
110 
111  void load();
112  void unload();
113 
114  void activate();
115  void deactivate();
116 
117  bool is_loaded() const {
118  return is_loaded_;
119  }
120  bool is_active() const {
121  return is_active_;
122  }
123 
124  const std::string name() const {
125  return name_;
126  }
127 
128  void set_name(const std::string& name) {
129  name_ = name;
130  }
131 
132  /* Whether or not the scene should be unloaded when it's deactivated
133  * this is the default behaviour */
134  bool unload_on_deactivate() const {
135  return unload_on_deactivate_;
136  }
137  void set_unload_on_deactivate(bool v) {
138  unload_on_deactivate_ = v;
139  }
140 
141  template<typename T>
142  T* start_service() {
143  size_t info = typeid(T).hash_code();
144  if(services_.count(info)) {
145  return static_cast<T*>(services_.at(info).get());
146  }
147 
148  auto service = std::make_shared<T>();
149 
150  // FIXME: start signal
151 
152  services_.insert(std::make_pair(info, service));
153  return service.get();
154  }
155 
156  template<typename T>
157  bool stop_service() {
158  size_t info = typeid(T).hash_code();
159  auto it = services_.find(info);
160  if(it != services_.end()) {
161  return false;
162  }
163 
164  // FIXME: Stop signal
165  services_.erase(it);
166  return true;
167  }
168 
169  template<typename T>
170  T* find_service() const {
171  auto info = typeid(T).hash_code();
172  auto it = services_.find(info);
173  if(it != services_.end()) {
174  return static_cast<T*>(it->second.get());
175  }
176 
177  return nullptr;
178  }
179 
180  const std::set<StageNode*> stray_nodes() const {
181  return stray_nodes_;
182  }
183 
184  const char* node_type_name() const override {
185  return "Scene";
186  }
187 
188  // Scenes don't take parameters (for now...)
189  std::set<NodeParam> node_params() const override {
190  return std::set<NodeParam>();
191  }
192 
193 protected:
194  virtual void on_load() = 0;
195  virtual void on_unload() {}
196  virtual void on_activate() {}
197  virtual void on_deactivate() {}
198 
199 private:
200  void on_fixed_update(float step) override;
201 
202  void register_builtin_nodes();
203  std::unordered_map<size_t, std::shared_ptr<Service>> services_;
204 
205  virtual void on_pre_load() {}
206  virtual void on_post_unload() {}
207 
208  bool is_loaded_ = false;
209  bool is_active_ = false;
210  bool unload_on_deactivate_ = true;
211 
212  std::string name_;
213 
214  Window* window_;
215  InputManager* input_;
216  Application* app_;
217  SceneManager* scene_manager_ = nullptr;
218  SceneCompositor compositor_;
219 
220  AssetManager assets_;
221 
222  friend class SceneManager;
223 
224  std::vector<any> load_args;
225 
226  void on_clean_up() override {
227  unload();
228  }
229 
230  // So that stage nodes can call queue_clean_up
231  friend class StageNode;
232 
233  void clean_up_destroyed_objects();
234  void queue_clean_up(StageNode* node);
235  std::list<StageNode*> queued_for_clean_up_;
236  std::set<StageNode*> stray_nodes_;
237 
238  LightingSettings lighting_;
239 
240  /* Don't allow overriding on_create in subclasses, currently
241  * the hook for that is init + load */
242  bool on_create(Params) override final {
243  return true;
244  }
245 
246  void do_generate_renderables(batcher::RenderQueue*, const Camera*,
247  const Viewport*, const DetailLevel, Light**,
248  const std::size_t) override final {
249  /* Do nothing, Scenes don't create renderables.. for now */
250  }
251 
252  /* Scenes don't care about AABBs */
253  const AABB& aabb() const override final {
254  static AABB ret;
255  return ret;
256  }
257 
258 protected:
259  /* Returns the number of arguments passed when loading */
260  std::size_t load_arg_count() const;
261 
262  template<typename T>
263  T get_load_arg(int i) {
264  return any_cast<T>(load_args[i]);
265  }
266 
267 public:
268  S_DEFINE_PROPERTY(window, &Scene::window_);
269  S_DEFINE_PROPERTY(app, &Scene::app_);
270  S_DEFINE_PROPERTY(input, &Scene::input_);
271  S_DEFINE_PROPERTY(scenes, &Scene::scene_manager_);
272  S_DEFINE_PROPERTY(compositor, &Scene::compositor_);
273  S_DEFINE_PROPERTY(lighting, &Scene::lighting_);
274  S_DEFINE_PROPERTY(assets, &Scene::assets_);
275 };
276 
277 } // namespace smlt
278 
279 #endif // SCENE_H
smlt::LightingSettings
Definition: scene.h:77
smlt::SceneLoadException
Definition: scene.h:64
smlt::SceneCompositor
The SceneCompositor class.
Definition: compositor.h:131
smlt::Application
Definition: application.h:160
smlt::Params
Definition: params.h:45
smlt
Definition: animation.cpp:25
smlt::Light
Definition: light.h:34
smlt::Window
Definition: window.h:68
smlt::Scene
Definition: scene.h:94
smlt::batcher::RenderQueue
Definition: render_queue.h:169
smlt::Color
Definition: color.h:32
smlt::Camera
Definition: camera.h:17
smlt::InputManager
Definition: input_manager.h:48
smlt::StageNodeManager
Definition: stage_node_manager.h:27
smlt::AABB
Definition: aabb.h:22
smlt::StageNode
Definition: stage_node.h:442
smlt::SceneManager
Definition: scene_manager.h:52
smlt::StageNodeWatchController
Definition: stage_node_watch_controller.h:60
smlt::Viewport
Definition: viewport.h:44
smlt::AssetManager
Definition: asset_manager.h:92
smlt::sig::signal
Definition: signal.h:330