Line data Source code
1 : /*
2 : * Copyright (C) 2025 aeml
3 : *
4 : * This program is free software: you can redistribute it and/or modify
5 : * it under the terms of the GNU General Public License as published by
6 : * the Free Software Foundation, either version 3 of the License, or
7 : * (at your option) any later version.
8 : *
9 : * This program is distributed in the hope that it will be useful,
10 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 : * GNU General Public License for more details.
13 : *
14 : * You should have received a copy of the GNU General Public License
15 : * along with this program. If not, see <https://www.gnu.org/licenses/>.
16 : */
17 :
18 : #pragma once
19 :
20 : #include <cstddef>
21 : #include <memory>
22 : #include <string>
23 : #include <string_view>
24 : #include <vector>
25 :
26 : namespace ecs { class World; }
27 :
28 : namespace simlab
29 : {
30 : class IScenario
31 : {
32 : public:
33 60 : virtual ~IScenario() = default;
34 : virtual void Setup(ecs::World& world) = 0;
35 : // Scenario-specific logic hook. The engine owns world stepping.
36 : virtual void Update(ecs::World& world, float dt) = 0;
37 : virtual void Render(ecs::World& world, std::ostream& out) = 0;
38 : };
39 :
40 : std::unique_ptr<IScenario> CreatePlanetaryGravityScenario();
41 : std::unique_ptr<IScenario> CreateWreckingBallScenario();
42 : std::unique_ptr<IScenario> CreateParticleFluidScenario();
43 : std::unique_ptr<IScenario> CreateFullDemoScenario();
44 : std::unique_ptr<IScenario> CreateFailSetupScenario();
45 : std::unique_ptr<IScenario> CreateFailUpdateScenario();
46 : std::unique_ptr<IScenario> CreateFailWorldUpdateScenario();
47 : std::unique_ptr<IScenario> CreateFailRenderScenario();
48 :
49 : using ScenarioFactory = std::unique_ptr<IScenario>(*)();
50 :
51 : struct ScenarioDesc
52 : {
53 : const char* key;
54 : const char* title;
55 : ScenarioFactory factory;
56 : const char* category; // optional grouping, e.g., "Text Tests"
57 : const char* subcategory; // optional subgroup, e.g., "Text Renderer Tests"
58 : };
59 :
60 : struct ScenarioSelectionResult
61 : {
62 : std::unique_ptr<IScenario> scenario;
63 : std::string requestedKey;
64 : std::string selectedKey;
65 : bool fallbackUsed{false};
66 : bool shouldLogUnknownScenario{false};
67 : bool shouldLogSelectedScenario{false};
68 : std::string unknownScenarioKey;
69 : };
70 :
71 : class ScenarioRegistry
72 : {
73 : public:
74 : static void Register(const char* key, const char* title, ScenarioFactory factory);
75 : static void Register(const char* key, const char* title, ScenarioFactory factory,
76 : const char* category, const char* subcategory);
77 : static const std::vector<ScenarioDesc>& All();
78 : static ScenarioFactory FindFactory(const std::string& key);
79 : static std::unique_ptr<IScenario> Create(const std::string& key);
80 : static ScenarioSelectionResult ResolveScenarioSelection(std::string_view requestedKey,
81 : std::size_t menuChoiceIndex);
82 :
83 : private:
84 : static std::vector<ScenarioDesc>& Storage();
85 : };
86 :
87 : struct ScenarioAutoRegister
88 : {
89 : ScenarioAutoRegister(const char* key, const char* title, ScenarioFactory factory)
90 : {
91 : ScenarioRegistry::Register(key, title, factory);
92 : }
93 : ScenarioAutoRegister(const char* key, const char* title, ScenarioFactory factory,
94 : const char* category, const char* subcategory)
95 : {
96 : ScenarioRegistry::Register(key, title, factory, category, subcategory);
97 : }
98 : };
99 :
100 : void SetHeadlessRendering(bool enabled);
101 : bool IsHeadlessRendering();
102 : }
|