Gorgon Game Engine
Scene.h
Go to the documentation of this file.
1 #pragma once
2 
3 #include "Utils/Assert.h"
4 #include "Event.h"
5 #include "ConsumableEvent.h"
6 #include "Main.h"
7 
8 #include "Layer.h"
9 #include "Input/Layer.h"
10 #include "Input/Keyboard.h"
11 #include "Graphics/Layer.h"
12 #include "Containers/Hashmap.h"
13 #include "Window.h"
14 #include "Time.h"
15 
16 #include <stdexcept>
17 
18 
19 namespace Gorgon {
44  using SceneID = int;
46 
49  static constexpr SceneID NoSceneID = -1;
50 
51  class SceneManager;
52 
60  class Scene : public Animation::Governor {
61  friend class SceneManager;
62  public:
63 
66  explicit Scene(SceneID id = NoSceneID, bool mouseinput = true) : id(id), mouseinput(mouseinput) {
67  main.Add(graphics);
68  if(mouseinput)
69  main.Add(mouse);
70  }
71 
73  explicit Scene(SceneManager &parent, SceneID id = NoSceneID, bool mouseinput = true) : Scene(id, mouseinput) {
74  this->parent = &parent;
75  }
76 
78  virtual bool RequiresKeyInput() const = 0;
79 
81  virtual void Activate() override;
82 
84  SceneID GetID() const {
85  return id;
86  }
87 
89  virtual void KeyEvent(Gorgon::Input::Key, float) { }
90 
95 
100 
101  protected:
104  virtual void first_activation() { }
105 
108  virtual void activate() { }
109 
111  virtual void deactivate() { }
112 
115  virtual void doframe(unsigned int delta) = 0;
116 
120  virtual void render() = 0;
121 
123  void setlayerbounds(const Geometry::Bounds &bounds) {
124  main.SetBounds(bounds);
125  }
126 
127 
130 
133 
139 
142  SceneManager *parent = nullptr;
143 
144  private:
145 
146  void activate_scene();
147 
148  void deactivate_scene();
149 
150  Gorgon::Layer main;
151  bool mouseinput = false;
152  bool isactive = false;
153  bool first = true;
154  };
155 
163  class SceneManager : public Window, public Runner {
164  public:
165  using Window::Window;
166 
168  }
169 
170  SceneManager(SceneManager &&) = default;
171 
173 
175  scenes.Destroy();
176  }
177 
181  void SwitchScene(SceneID scene) {
182  if(active && active->GetID() == scene)
183  return;
184 
185  Deactivate();
186 
187  if(scene == NoSceneID) {
188  return;
189  }
190 
191  if(!scenes.Exists(scene))
192  throw std::runtime_error("Scene does not exist");
193 
194  active = &scenes[scene];
195  active->activate_scene();
196  if(active->RequiresKeyInput()) {
197  KeyEvent.Enable(inputtoken);
198  KeyEvent.MoveToTop(inputtoken);
199  }
200 
202  }
203 
205  void Deactivate() {
206  if(active) {
207  active->deactivate_scene();
208  }
209 
210  active = nullptr;
211 
212  KeyEvent.Disable(inputtoken);
213  }
214 
215 
219  if(active && active->RequiresKeyInput()) {
220  KeyEvent.Enable(inputtoken);
221  KeyEvent.MoveToTop(inputtoken);
222  }
223  }
224 
228  void Run() override {
229  while(!quiting) {
230  if(active) {
232  active->render();
233  }
234 
236  }
237 
238  SwitchScene(NoSceneID);
239  }
240 
243  void Step() override {
244  if(active) {
246  active->render();
247  }
248 
250  }
251 
253  int GetSceneCount() const {
254  return scenes.GetCount();
255  }
256 
258  bool SceneExists(SceneID id) const {
259  return scenes.Exists(id);
260  }
261 
265  return scenes[scene];
266  }
267 
270  void DeleteScene(SceneID scene) {
271  scenes.Delete(scene);
272  }
273 
278  auto &scene = scenes[id];
279 
280  scenes.Remove(id);
281  scene.parent = nullptr;
282 
283  return scene;
284  }
285 
288  void Assume(Scene &scene) {
289  scene.parent = this;
290  scenes.Add(scene.id, scene);
291  }
292 
294  auto begin() {
295  return scenes.begin();
296  }
297 
299  auto begin() const {
300  return scenes.begin();
301  }
302 
304  auto end() {
305  return scenes.end();
306  }
307 
309  auto end() const {
310  return scenes.end();
311  }
312 
317  void Quit() override {
318  quiting = true;
319  }
320 
353  template<class S_, class ... P_>
354  S_ &NewScene(SceneID id, P_ && ... params) {
355  auto *s = new S_(*this, id, std::forward<P_>(params)...);
356 
357  scenes.Add(id, s, true);
358 
359  return *s;
360  }
361 
364 
365  protected:
366  decltype(KeyEvent)::Token init() {
367  inputtoken = KeyEvent.Register([this](Input::Key key, float amount) {
368  if(active && active->RequiresKeyInput())
369  active->KeyEvent(key, amount);
370 
371  return true;
372  });
373 
374  KeyEvent.Disable(inputtoken);
375 
376  return inputtoken;
377  }
378 
380  Scene *active = nullptr;
381  decltype(KeyEvent)::Token inputtoken = init(); //to initialize token after window got constructed
382  bool quiting = false;
383  };
384 
385 
386  inline void Scene::activate_scene() {
387  if(isactive) return;
388 
389  if(!parent)
390  throw std::runtime_error("This scene has no parent");
391 
392  parent->Add(main);
393  main.Add(graphics);
394 
396 
397  isactive = true;
398 
399  if(first) {
400  first = false;
402  }
403 
404  activate();
405 
406  ActivatedEvent();
407  }
408 
409  inline void Scene::deactivate_scene() {
410  if(!isactive) return;
411 
412  deactivate();
413 
414  if(main.HasParent())
415  main.GetParent().Remove(main);
416 
418 
419  isactive = false;
420 
422  }
423 
424  inline void Scene::Activate() {
425  if(parent)
426  parent->SwitchScene(id);
427  }
428 
429 }
Gorgon::Scene::ActivatedEvent
Gorgon::Event< Scene > ActivatedEvent
Fires whenever activation of this layer is completed.
Definition: Scene.h:94
Gorgon::Geometry::basic_Bounds
This class represents boundaries of 2D objects.
Definition: Bounds.h:27
Gorgon::Scene::Scene
Scene(SceneManager &parent, SceneID id=NoSceneID, bool mouseinput=true)
Sets the parent layer so that the scene can be activated.
Definition: Scene.h:73
Gorgon::Window
This class represents a window.
Definition: Window.h:31
Layer.h
Gorgon::SceneManager::scenes
Gorgon::Containers::Hashmap< SceneID, Scene > scenes
Definition: Scene.h:379
Gorgon::SceneManager::SceneManager
SceneManager(SceneManager &&)=default
Gorgon::Scene::id
SceneID id
ID of the current scene.
Definition: Scene.h:129
Gorgon::SceneManager::init
decltype(KeyEvent) ::Token init()
Definition: Scene.h:366
Gorgon::Event
This class provides event mechanism.
Definition: Event.h:134
Gorgon::Layer::Add
void Add(Layer &layer)
Adds the given layer as a child.
Definition: Layer.cpp:23
Gorgon::SceneManager::GetSceneCount
int GetSceneCount() const
Returns the number of scenes registered.
Definition: Scene.h:253
Gorgon::SceneManager::Step
void Step() override
Steps the application by running the active scene, progressing OS events and rendering mechanism.
Definition: Scene.h:243
Gorgon::SceneManager::ActivateKeyboard
void ActivateKeyboard()
Moves keyboard input event to the top if there is a layer that accepts keyboard input.
Definition: Scene.h:218
Gorgon::Containers::Hashmap
This class is a reference based hashmap.
Definition: Hashmap.h:35
Gorgon::SceneManager::ActivatedEvent
Gorgon::Event< SceneManager, Scene & > ActivatedEvent
This event will be fired whenever a scene is activated.
Definition: Scene.h:363
Gorgon::Window::Window
Window()
Empty constructor creates a non-initialized window.
Definition: Window.h:45
Window.h
Gorgon::Scene::activate
virtual void activate()
Called after very activation.
Definition: Scene.h:108
Gorgon::NextFrame
void NextFrame()
This function marks the end of current frame and starts the next one.
Definition: Main.cpp:115
Gorgon::SceneManager::Run
void Run() override
Runs the application by running the active scene, progressing OS events and rendering mechanism.
Definition: Scene.h:228
Gorgon::SceneManager::Assume
void Assume(Scene &scene)
Assumes the ownership of the the given scene, adding it to the list of scenes.
Definition: Scene.h:288
Gorgon::Scene::DeactivatedEvent
Gorgon::Event< Scene > DeactivatedEvent
Fires whenever deactivation of this layer is completed.
Definition: Scene.h:99
Gorgon::SceneManager::Quit
void Quit() override
Quits the scene manager, returning the execution to the point where Run function is called.
Definition: Scene.h:317
Gorgon::SceneManager::end
auto end()
Returns iterator to the end of scenes.
Definition: Scene.h:304
Gorgon::Scene
This class represents a scene in the game like menu screen in game, post game, pause or different gam...
Definition: Scene.h:60
Hashmap.h
contains Hashmap, a map of references
Gorgon::Time::DeltaTime
unsigned long DeltaTime()
Returns the time passed since the last frame.
Definition: Time.h:258
Gorgon::SceneManager::begin
auto begin() const
Returns iterator to the first scene.
Definition: Scene.h:299
Gorgon::Graphics::Layer
This layer allows drawing texture images on.
Definition: Layer.h:169
Gorgon::Runner
Defines the abstract class of Runner.
Definition: Main.h:21
Gorgon::SceneManager::operator=
SceneManager & operator=(SceneManager &&)=default
Gorgon::Input::Key
int Key
A type to represent an input key.
Definition: Input.h:14
Gorgon::SceneManager::end
auto end() const
Returns iterator to the end of scenes.
Definition: Scene.h:309
Gorgon
Root namespace for Gorgon Game Engine.
Definition: Any.h:19
Gorgon::SceneManager::NewScene
S_ & NewScene(SceneID id, P_ &&... params)
Creates a new scene using the given type and parameters.
Definition: Scene.h:354
Gorgon::Scene::mouse
Gorgon::Input::Layer mouse
Mouse layer that can be used to receive mouse events.
Definition: Scene.h:138
Gorgon::Layer::GetParent
virtual Layer & GetParent() const
Returns the parent of this layer.
Definition: Layer.h:226
Gorgon::SceneManager
This class is a Window that manages scenes, allowing swapping, handling input and game loop.
Definition: Scene.h:163
Gorgon::SceneManager::Release
Scene & Release(SceneID id)
Releases the ownership of the scene with the given ID, removing it from the manager.
Definition: Scene.h:277
Gorgon::SceneManager::SceneManager
SceneManager()
Definition: Scene.h:167
Gorgon::Scene::first_activation
virtual void first_activation()
Called only for the first time this scene is activated.
Definition: Scene.h:104
Gorgon::SceneID
int SceneID
Can be used to identify scenes.
Definition: Scene.h:45
Layer.h
Gorgon::Scene::render
virtual void render()=0
This is called after doframe to perform rendering operation.
Gorgon::Scene::Activate
virtual void Activate() override
Activates the current scene.
Definition: Scene.h:424
Gorgon::Scene::graphics
Gorgon::Graphics::Layer graphics
Graphics layer that can be drawn on.
Definition: Scene.h:132
Gorgon::Animation::Governor
This class governs the progress of animations.
Definition: Animation.h:26
Gorgon::Layer::SetBounds
void SetBounds(const Geometry::Bounds &bounds)
Sets the boundaries of this layer.
Definition: Layer.h:357
Gorgon::Layer::Remove
void Remove(Layer &layer)
Removes the given layer.
Definition: Layer.h:203
Gorgon::Layer
This class is the base class for all layer types.
Definition: Layer.h:79
Gorgon::Scene::doframe
virtual void doframe(unsigned int delta)=0
Scene should perform its frame based operations in this function.
Gorgon::SceneManager::SceneExists
bool SceneExists(SceneID id) const
Returns if the given scene exists.
Definition: Scene.h:258
Gorgon::Animation::Governor::Activate
virtual void Activate()
Activates this governor, replacing current one.
Definition: Animation.h:34
Gorgon::SceneManager::inputtoken
decltype(KeyEvent) ::Token inputtoken
Definition: Scene.h:381
Gorgon::SceneManager::GetScene
Scene & GetScene(SceneID scene)
Returns the requested scene.
Definition: Scene.h:264
Gorgon::SceneManager::quiting
bool quiting
Definition: Scene.h:382
Event.h
contains event distribution mechanism
Gorgon::SceneManager::SwitchScene
void SwitchScene(SceneID scene)
Switches the current scene to the scene with the given id.
Definition: Scene.h:181
Gorgon::Scene::setlayerbounds
void setlayerbounds(const Geometry::Bounds &bounds)
Changes the boundaries of the main layer.
Definition: Scene.h:123
Gorgon::SceneManager::DeleteScene
void DeleteScene(SceneID scene)
Deletes the given scene, nothing is done if the scene is not found.
Definition: Scene.h:270
Time.h
contains time related functions and classes
Main.h
Gorgon::Scene::KeyEvent
virtual void KeyEvent(Gorgon::Input::Key, float)
Called when the scene receives a key.
Definition: Scene.h:89
Gorgon::Animation::Governor::Default
static Governor & Default()
Returns the default governor.
Definition: Animation.h:44
Gorgon::SceneManager::active
Scene * active
Definition: Scene.h:380
Gorgon::Scene::Scene
Scene(SceneID id=NoSceneID, bool mouseinput=true)
Empty constructor.
Definition: Scene.h:66
Gorgon::Scene::RequiresKeyInput
virtual bool RequiresKeyInput() const =0
Whether this scene requires keyboard input.
Gorgon::SceneManager::Deactivate
void Deactivate()
Deactivates all scenes.
Definition: Scene.h:205
Gorgon::Input::Layer
Input layer allows mouse events to be handled.
Definition: Layer.h:25
Gorgon::Layer::HasParent
bool HasParent() const
Returns whether this layer has a parent.
Definition: Layer.h:219
Gorgon::Scene::parent
SceneManager * parent
The parent window for the scene.
Definition: Scene.h:142
Gorgon::Scene::deactivate
virtual void deactivate()
Called before deactivation.
Definition: Scene.h:111
Keyboard.h
Gorgon::Window::KeyEvent
ConsumableEvent< Window, Input::Key, float > KeyEvent
Called when a key is pressed or released.
Definition: Window.h:392
Gorgon::SceneManager::~SceneManager
~SceneManager()
Definition: Scene.h:174
Gorgon::Scene::GetID
SceneID GetID() const
Returns the ID of the current scene.
Definition: Scene.h:84
Assert.h
Gorgon::SceneManager::begin
auto begin()
Returns iterator to the first scene.
Definition: Scene.h:294