Simulant  21.12-1292
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 protected:
185  virtual void on_load() = 0;
186  virtual void on_unload() {}
187  virtual void on_activate() {}
188  virtual void on_deactivate() {}
189 
190 private:
191  void on_fixed_update(float step) override;
192 
193  void register_builtin_nodes();
194  std::unordered_map<size_t, std::shared_ptr<Service>> services_;
195 
196  virtual void on_pre_load() {}
197  virtual void on_post_unload() {}
198 
199  bool is_loaded_ = false;
200  bool is_active_ = false;
201  bool unload_on_deactivate_ = true;
202 
203  std::string name_;
204 
205  Window* window_;
206  InputManager* input_;
207  Application* app_;
208  SceneManager* scene_manager_ = nullptr;
209  SceneCompositor compositor_;
210 
211  AssetManager assets_;
212 
213  friend class SceneManager;
214 
215  std::vector<any> load_args;
216 
217  void on_clean_up() override {
218  unload();
219  }
220 
221  // So that stage nodes can call queue_clean_up
222  friend class StageNode;
223 
224  void clean_up_destroyed_objects();
225  void queue_clean_up(StageNode* node);
226  std::list<StageNode*> queued_for_clean_up_;
227  std::set<StageNode*> stray_nodes_;
228 
229  LightingSettings lighting_;
230 
231  /* Don't allow overriding on_create in subclasses, currently
232  * the hook for that is init + load */
233  bool on_create(Params) override final {
234  return true;
235  }
236 
237  void do_generate_renderables(batcher::RenderQueue*, const Camera*,
238  const Viewport*, const DetailLevel, Light**,
239  const std::size_t) override final {
240  /* Do nothing, Scenes don't create renderables.. for now */
241  }
242 
243  /* Scenes don't care about AABBs */
244  const AABB& aabb() const override final {
245  static AABB ret;
246  return ret;
247  }
248 
249 protected:
250  /* Returns the number of arguments passed when loading */
251  std::size_t load_arg_count() const;
252 
253  template<typename T>
254  T get_load_arg(int i) {
255  return any_cast<T>(load_args[i]);
256  }
257 
258 public:
259  S_DEFINE_PROPERTY(window, &Scene::window_);
260  S_DEFINE_PROPERTY(app, &Scene::app_);
261  S_DEFINE_PROPERTY(input, &Scene::input_);
262  S_DEFINE_PROPERTY(scenes, &Scene::scene_manager_);
263  S_DEFINE_PROPERTY(compositor, &Scene::compositor_);
264  S_DEFINE_PROPERTY(lighting, &Scene::lighting_);
265  S_DEFINE_PROPERTY(assets, &Scene::assets_);
266 };
267 
268 } // namespace smlt
269 
270 #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:44
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