R-Type 0.1
Loading...
Searching...
No Matches
sceneManager.hpp
1#pragma once
2
3#include <concepts>
4#include <optional>
5#include <stdexcept>
6#include <utility>
7#include <variant>
8
9#include "sceneConcept.hpp"
10
11namespace rtk {
28template <SceneIdentifier TSceneId, typename TDependency, typename TInput,
29 typename... TScenes>
30 requires((Scene<TScenes, TSceneId, TInput> && ...) &&
31 (std::constructible_from<TScenes, TDependency &> && ...))
33public:
35 using SceneVariant = std::variant<TScenes...>;
36
42 template <typename TInitialScene>
43 SceneManager(TDependency &dependency, std::in_place_type_t<TInitialScene>)
44 : _dependency(dependency),
45 _currentScene(std::in_place_type<TInitialScene>, dependency) {}
46
51 void start(EngineContext &context) {
52 std::visit([&](auto &scene) { scene.onEnter(context); }, _currentScene);
53 }
54
62 void update(EngineContext &context, const TInput &input, float dt) {
63 const auto requestedScene = std::visit(
64 [&](auto &scene) { return scene.onUpdate(context, input, dt); },
65 _currentScene);
66
67 if (requestedScene.has_value())
68 switchScene(context, *requestedScene);
69 }
70
75 void stop(EngineContext &context) {
76 std::visit([&](auto &scene) { scene.onExit(context); }, _currentScene);
77 }
78
84 template <typename TScene>
85 requires(std::same_as<TScene, TScenes> || ...)
86 [[nodiscard]] TScene *get() noexcept {
87 return std::get_if<TScene>(&_currentScene);
88 }
89
95 template <typename TScene>
96 requires(std::same_as<TScene, TScenes> || ...)
97 [[nodiscard]] const TScene *get() const noexcept {
98 return std::get_if<TScene>(&_currentScene);
99 }
100
101private:
102 template <typename TScene> bool trySwitchScene(TSceneId nextScene) {
103 if (nextScene != TScene::Type)
104 return false;
105
106 _currentScene.template emplace<TScene>(_dependency);
107 return true;
108 }
109
110 void switchScene(EngineContext &context, TSceneId nextScene) {
111 stop(context);
112
113 const bool found = (trySwitchScene<TScenes>(nextScene) || ...);
114
115 if (!found)
116 throw std::runtime_error("Unknown scene");
117
118 start(context);
119 }
120
121 TDependency &_dependency;
122 SceneVariant _currentScene;
123};
124
126} // namespace rtk
Holds the active scene and switches between a fixed set of scenes.
Definition sceneManager.hpp:32
std::variant< TScenes... > SceneVariant
Variant holding the active scene.
Definition sceneManager.hpp:35
void start(EngineContext &context)
Calls onEnter() on the active scene.
Definition sceneManager.hpp:51
TScene * get() noexcept
Returns the active scene if it has the given type.
Definition sceneManager.hpp:86
void update(EngineContext &context, const TInput &input, float dt)
Updates the active scene and switches if it asks to.
Definition sceneManager.hpp:62
void stop(EngineContext &context)
Calls onExit() on the active scene.
Definition sceneManager.hpp:75
SceneManager(TDependency &dependency, std::in_place_type_t< TInitialScene >)
Constructs the initial scene without entering it.
Definition sceneManager.hpp:43
const TScene * get() const noexcept
Returns the active scene if it has the given type.
Definition sceneManager.hpp:97
Engine services handed to the game and its scenes.
Definition EngineContext.hpp:20