Acheron
Loading...
Searching...
No Matches
world.hpp
1#pragma once
2
3#include "singleton.hpp"
4#include "module.hpp"
5#include "system_function.hpp"
6#include "types.hpp"
7#include "event.hpp"
8#include "system.hpp"
9#include "component.hpp"
10#include "entity.hpp"
11
12#include <memory>
13
14namespace acheron::ecs {
20 class World {
21 public:
25 World();
26
31 Entity Spawn();
32
39 void AddStageBefore(std::string name, std::string after);
40
47 void AddStageAfter(std::string name, std::string before);
48
64 template<typename... Cs, typename... Overrides>
65 Entity SpawnWith(Overrides&&... overrides) {
66 Entity e = Spawn();
67
68 auto check_override = [](auto&& override_val) {
69 using T = std::decay_t<decltype(override_val)>;
70 static_assert((std::disjunction_v<std::is_same<T, Cs>...>),
71 "Override type not in component list!");
72 };
73
74 (check_override(overrides), ...);
75 (void)check_override;
76
77 (AddOrDefault<Cs>(e, std::forward<Overrides>(overrides)...), ...);
78 return e;
79 }
80
88 void Despawn(Entity entity);
89
95 template<typename T>
97 componentManager->RegisterComponent<T>();
98 }
99
107 template<typename T>
108 bool HasComponent(Entity entity) {
109 return componentManager->HasComponent<T>(entity);
110 }
111
112 template<typename... Components, typename Func>
113 void View(Func&& func) {
114 Signature required = MakeSignature<Components...>();
115
116 for (auto& [entity, sig] : entityManager->signatures) {
117 bool match = std::includes(
118 sig.begin(), sig.end(),
119 required.begin(), required.end()
120 );
121
122 if (match) {
123 func(entity, GetComponent<Components>(entity)...);
124 }
125 }
126 }
127
137 template<typename T, typename... Args>
138 void AddComponent(Entity entity, Args&&... args) {
139 componentManager->AddComponent<T>(entity, T(std::forward<Args>(args)...));
140
141 auto signature = entityManager->GetSignature(entity);
142 signature.insert(componentManager->GetComponentID<T>());
143 entityManager->SetSignature(entity, signature);
144
145 systemManager->EntitySignatureChanged(entity, signature);
146 }
147
156 template<typename T>
157 void RemoveComponent(Entity entity) {
158 componentManager->RemoveComponent<T>(entity);
159
160 auto signature = entityManager->GetSignature(entity);
161 signature.erase(componentManager->GetComponentID<T>());
162 entityManager->SetSignature(entity, signature);
163
164 systemManager->EntitySignatureChanged(entity, signature);
165 }
166
176 template<typename T>
177 T& GetComponent(Entity entity) {
178 return componentManager->GetComponent<T>(entity);
179 }
180
186 template<typename T>
187 ComponentID GetComponentID() {
188 return componentManager->GetComponentID<T>();
189 }
190
198 template<typename... Components>
199 Signature MakeSignature() {
200 Signature signature;
201 (signature.insert(GetComponentID<Components>()), ...);
202 return signature;
203 }
204
215 template<typename T>
216 std::shared_ptr<T> RegisterSystem(Signature signature = {}, std::string stage = "Update") {
217 auto system = systemManager->RegisterSystem<T>(stage);
218 SetSystemSignature<T>(signature);
219 return system;
220 }
221
235 template<typename Func>
236 std::shared_ptr<System> RegisterSystemExplicit(Func&& func, Signature signature = {}, std::string stage = "Update") {
237 using SystemType = SystemFunction<std::decay_t<Func>>;
238 auto systemFunc = std::make_shared<SystemType>(std::forward<Func>(func));
239
240 static int counter = 0;
241 std::string typeName = "LambdaSystem_" + std::to_string(counter++);
242
243 systemManager->systems[typeName] = systemFunc;
244 if (!signature.empty()) {
245 systemManager->signatures[typeName] = signature;
246 }
247 systemManager->stageSystems[systemManager->GetStageOrFail(stage)].push_back(systemFunc);
248
249 return systemFunc;
250 }
251
270 template<typename... Components, typename Func>
271 std::shared_ptr<System> RegisterSystem(Func&& func, std::string stage = "Update") {
272 auto signature = MakeSignature<Components...>();
273 return RegisterSystemExplicit(std::forward<Func>(func), signature, stage);
274 }
275
283 template<typename T>
284 void SetSystemSignature(Signature signature) {
285 systemManager->SetSignature<T>(signature);
286 }
287
295 template<typename T>
296 void SetSingleton(T value) {
297 SingletonStorage<T>::Set(std::move(value));
298 }
299
308 template<typename T>
311 }
312
320 template<typename T>
323 }
324
332 template<typename T>
333 void Import() {
334 static_assert(std::is_base_of<Module, T>::value, "Import must inherit from Module");
335
336 auto module = T{};
337 module.Register(*this);
338 }
339
347 template<typename T>
349 eventManager->Subscribe<T>(*this, cb);
350 }
351
359 template<typename T>
360 void EmitEvent(const T& event) {
361 eventManager->Emit<T>(event);
362 }
363
368 eventManager->Dispatch();
369 }
370
382 void Update(double dt = 0.0);
383
384 private:
385
397 template<typename C, typename... Overrides>
398 void AddOrDefault(Entity entity, Overrides&&... overrides) {
399 bool added = false;
400 // just wanted to write this here
401 // ooooo scary folding expressions ooo scary c++ :fearful:
402 (
403 [&] {
404 if constexpr(std::is_same_v<std::decay_t<Overrides>, C>) {
405 AddComponent<C>(entity, std::forward<Overrides>(overrides));
406 added = true;
407 }
408 }(),
409 ...
410 );
411
412 if (!added) AddComponent<C>(entity);
413 }
414
415 int counter = 0;
416 bool hasStarted = false;
417 std::unique_ptr<EntityManager> entityManager;
418 std::unique_ptr<ComponentManager> componentManager;
419 std::unique_ptr<SystemManager> systemManager;
420 std::unique_ptr<EventManager> eventManager;
421 };
422}
std::function< void(World &, const T &)> Callback
Function signature for event callbacks.
Definition event.hpp:29
static bool IsSet()
Check if the singleton is set.
Definition singleton.hpp:40
static void Set(const T &value)
Initializes singleton and sets the instance value.
Definition singleton.hpp:19
static T & Get()
Get the instance of a singleton.
Definition singleton.hpp:30
Wrapper class for systems to support lambda and function pointers.
Definition system_function.hpp:15
void SetSystemSignature(Signature signature)
Sets the component signature for a system.
Definition world.hpp:284
void AddComponent(Entity entity, Args &&... args)
Adds a component to an entity.
Definition world.hpp:138
void RemoveComponent(Entity entity)
Removes a component from an entity.
Definition world.hpp:157
void Despawn(Entity entity)
Despawns(destroys) an entity.
Definition world.cpp:44
std::shared_ptr< System > RegisterSystemExplicit(Func &&func, Signature signature={}, std::string stage="Update")
Registers a system explicitly from a function object or lambda.
Definition world.hpp:236
Signature MakeSignature()
Creates a signature that includes all specified component types.
Definition world.hpp:199
std::shared_ptr< System > RegisterSystem(Func &&func, std::string stage="Update")
Registers a system from a lambda or callable with component type deduction.
Definition world.hpp:271
void SetSingleton(T value)
Stores a singleton instance in the world.
Definition world.hpp:296
void RegisterComponent()
Registers a new component type with the ECS.
Definition world.hpp:96
void Update(double dt=0.0)
Runs system updates in the world.
Definition world.cpp:51
Entity SpawnWith(Overrides &&... overrides)
Spawns an entity with components.
Definition world.hpp:65
Entity Spawn()
Spawns a new entity.
Definition world.cpp:40
void SubscribeEvent(EventManager::Callback< T > cb)
Subscribes a callback to an event.
Definition world.hpp:348
void EmitEvent(const T &event)
Emit an event to the event queue.
Definition world.hpp:360
T & GetSingleton()
Retrieves a singleton instance from the world.
Definition world.hpp:309
ComponentID GetComponentID()
Retrieves the unique ID associated with a component type.
Definition world.hpp:187
bool IsSingletonSet()
Checks if singleton is set.
Definition world.hpp:321
void DispatchEvents()
Dispatch events.
Definition world.hpp:367
void Import()
Imports a module into the world.
Definition world.hpp:333
bool HasComponent(Entity entity)
Checks if en entity has a component.
Definition world.hpp:108
T & GetComponent(Entity entity)
Retrieves a reference to a component on an entity.
Definition world.hpp:177
void AddStageBefore(std::string name, std::string after)
Creates a stage before another.
Definition world.cpp:30
std::shared_ptr< T > RegisterSystem(Signature signature={}, std::string stage="Update")
Registers a system of type T.
Definition world.hpp:216
void AddStageAfter(std::string name, std::string before)
Creates a stage before another.
Definition world.cpp:35
World()
Constructs a new World, initializing managers.
Definition world.cpp:10