ToyMaker Game Engine 0.0.2
ToyMaker is a game engine developed and maintained by Zoheb Shujauddin.
Loading...
Searching...
No Matches
ecs_world.hpp
Go to the documentation of this file.
1
13
14#ifndef TOYMAKERENGINE_ECSWORLD_H
15#define TOYMAKERENGINE_ECSWORLD_H
16
17#include <cstdint>
18#include <typeinfo>
19#include <tuple>
20#include <memory>
21#include <vector>
22#include <set>
23#include <bitset>
24#include <unordered_map>
25#include <set>
26
27#include <nlohmann/json.hpp>
28
29#include "../util.hpp"
30#include "../registrator.hpp"
31
37
43
49
55
56namespace ToyMaker {
57
58
59
66 using EntityID = std::uint64_t;
67
74 using WorldID = std::uint64_t;
75
83 using UniversalEntityID = std::pair<WorldID, EntityID>;
84
91 using ECSType = std::uint8_t;
92
102
111
117 constexpr EntityID kMaxEntities { 1000000 };
118
123 constexpr ECSType kMaxECSTypes { 255 };
124
131
138
152 using Signature = std::bitset<kMaxComponents>;
153
154 class BaseSystem;
155 class SystemManager;
156 class ComponentManager;
157 class Entity;
158 class ECSWorld;
159
167 public:
168
174 explicit BaseComponentArray(std::weak_ptr<ECSWorld> world): mWorld{world} {}
175
180 virtual ~BaseComponentArray()=default;
181
187 virtual void handleEntityDestroyed(EntityID entityID)=0;
188
195 virtual void handlePreSimulationStep() = 0;
196
203 virtual void copyComponent(EntityID to, EntityID from)=0;
204
212 virtual void copyComponent(EntityID to, EntityID from, BaseComponentArray& other) = 0;
213
220 virtual void addComponent(EntityID to, const nlohmann::json& jsonComponent)=0;
221
228 virtual void updateComponent(EntityID to, const nlohmann::json& jsonComponent)=0;
229
237 virtual bool hasComponent(EntityID entityID) const=0;
238
244 virtual void removeComponent(EntityID entityID)=0;
245
252 virtual std::shared_ptr<BaseComponentArray> instantiate(std::weak_ptr<ECSWorld> world) const = 0;
253
254 protected:
255
260 std::weak_ptr<ECSWorld> mWorld {};
261 };
262
286 template <typename TComponent, typename Enable=void>
294 static TComponent get(const nlohmann::json& jsonComponent){
295 // in the regular case, just invoke the from_json method that the
296 // author of the component has presumably implemented
297 TComponent component = jsonComponent;
298 return component;
299 }
300 };
301
312 template <typename TComponent, typename Enable>
313 struct ComponentFromJSON<std::shared_ptr<TComponent>, Enable> {
314 static std::shared_ptr<TComponent> get(const nlohmann::json& jsonComponent) {
315 // assume once again that the author of the component has provided
316 // a from_json function that will be invoked here
317 std::shared_ptr<TComponent> component { new TComponent{} = jsonComponent };
318 return component;
319 }
320 };
321
334 template<typename T>
336 public:
345 T operator() (const T& previousState, const T& nextState, float simulationProgress=1.f) const;
346
347 private:
352 RangeMapperLinear mProgressLimits {0.f, 1.f, 0.f, 1.f};
353 };
354
363 template<typename TComponent>
365 public:
371 explicit ComponentArray(std::weak_ptr<ECSWorld> world): BaseComponentArray{ world } {}
372
373 private:
374
381 std::shared_ptr<BaseComponentArray> instantiate(std::weak_ptr<ECSWorld> world) const override;
382
389 void addComponent(EntityID entityID, const TComponent& component);
390
397 void addComponent(EntityID entityID, const nlohmann::json& componentJSON) override;
398
404 void removeComponent(EntityID entityID) override;
405
413 TComponent getComponent(EntityID entityID, float simulationProgress=1.f) const;
414
424 bool hasComponent(EntityID entityID) const override;
425
432 void updateComponent(EntityID entityID, const TComponent& newValue);
433
440 void updateComponent(EntityID entityID, const nlohmann::json& value) override;
441
447 virtual void handleEntityDestroyed(EntityID entityID) override;
448
455 virtual void handlePreSimulationStep() override;
456
463 virtual void copyComponent(EntityID to, EntityID from) override;
464
472 virtual void copyComponent(EntityID to, EntityID from, BaseComponentArray& other) override;
473
478 std::vector<TComponent> mComponentsNext {};
479
484 std::vector<TComponent> mComponentsPrevious {};
485
491 std::unordered_map<EntityID, std::size_t> mEntityToComponentIndex {};
492
498 std::unordered_map<std::size_t, EntityID> mComponentToEntity {};
499 friend class ComponentManager;
500 };
501
502
510 public:
516 explicit ComponentManager(std::weak_ptr<ECSWorld> world): mWorld { world } {};
517 private:
518
525 ComponentManager instantiate(std::weak_ptr<ECSWorld> world) const;
526
532 template<typename TComponent>
534
540 template <typename TComponent>
547 std::string operator()() {
548 return TComponent::getComponentTypeName();
549 }
550 };
551
558 template <typename TComponent>
559 struct getComponentTypeName<std::shared_ptr<TComponent>> {
560 std::string operator()() {
561 return TComponent::getComponentTypeName();
562 }
563 };
564
571 template<typename TComponent>
572 std::shared_ptr<ComponentArray<TComponent>> getComponentArray() const {
573 const std::size_t componentHash { typeid(TComponent).hash_code() };
574 assert(mHashToComponentType.find(componentHash) != mHashToComponentType.end() && "This component type has not been registered");
575 return std::dynamic_pointer_cast<ComponentArray<TComponent>>(mHashToComponentArray.at(componentHash));
576 }
577
584 std::shared_ptr<BaseComponentArray> getComponentArray(const std::string& componentTypeName) const {
585 const std::size_t componentHash { mNameToComponentHash.at(componentTypeName) };
586 return mHashToComponentArray.at(componentHash);
587 }
588
595 template<typename TComponent>
597
604 ComponentType getComponentType(const std::string& typeName) const;
605
622
630 template<typename TComponent>
631 void addComponent(EntityID entityID, const TComponent& component);
632
639 void addComponent(EntityID entityID, const nlohmann::json& jsonComponent);
640
647 template<typename TComponent>
648 void removeComponent(EntityID entityID);
649
656 void removeComponent(EntityID entityID, const std::string& type);
657
668 template<typename TComponent>
669 bool hasComponent(EntityID entityID) const;
670
681 bool hasComponent(EntityID entityID, const std::string& type);
682
691 template<typename TComponent>
692 TComponent getComponent(EntityID entityID, float simulationProgress=1.f) const;
693
703 template<typename TComponent>
704 void updateComponent(EntityID entityID, const TComponent& newValue);
705
714 void updateComponent(EntityID entityID, const nlohmann::json& componentProperties);
715
723 template<typename TComponent>
724 void copyComponent(EntityID to, EntityID from);
725
732 void copyComponents(EntityID to, EntityID from);
733
741 void copyComponents(EntityID to, EntityID from, ComponentManager& other);
742
750 void handleEntityDestroyed(EntityID entityID);
751
758
763 void unregisterAll();
764
770 std::unordered_map<std::string, std::size_t> mNameToComponentHash {};
771
779 std::unordered_map<std::size_t, ComponentType> mHashToComponentType {};
780
785 std::unordered_map<std::size_t, std::shared_ptr<BaseComponentArray>> mHashToComponentArray {};
786
796 std::unordered_map<EntityID, Signature> mEntityToSignature {};
797
802 std::weak_ptr<ECSWorld> mWorld;
803
804 friend class ECSWorld;
805 };
806
812 class BaseSystem : public std::enable_shared_from_this<BaseSystem> {
813 public:
819 BaseSystem(std::weak_ptr<ECSWorld> world): mWorld { world } {}
820
825 virtual ~BaseSystem() = default;
826
833 virtual bool isSingleton() const { return false; }
834
835 protected:
845 template<typename TComponent>
847
853 const std::set<EntityID>& getEnabledEntities();
854
860 const std::set<EntityID>& getEnabledEntities() const;
861
871 template <typename TComponent, typename TSystem>
872 TComponent getComponent_(EntityID entityID, float progress=1.f) const;
873
882 template <typename TComponent, typename TSystem>
883 void updateComponent_(EntityID entityID, const TComponent& component);
884
892 bool isEnabled(EntityID entityID) const;
893
901 bool isRegistered(EntityID entityID) const;
902
909 virtual std::shared_ptr<BaseSystem> instantiate(std::weak_ptr<ECSWorld> world) = 0;
910
915 std::weak_ptr<ECSWorld> mWorld;
916 private:
917
924 void addEntity(EntityID entityID, bool enabled=true);
925
931 void removeEntity(EntityID entityID);
932
938 void enableEntity(EntityID entityID);
944 void disableEntity(EntityID entityID);
945
953 virtual void onEntityEnabled(EntityID entityID) {(void)entityID; /* prevent unused parameter warnings*/}
954
962 virtual void onEntityDisabled(EntityID entityID) { (void)entityID; /* prevent unused parameter warnings*/}
963
970 virtual void onEntityUpdated(EntityID entityID, ComponentType updatedComponentType) {
971 /* prevent unused parameter warnings*/
972 (void)entityID;
973 (void)updatedComponentType;
974 assert(false && "The base class version of onEntityUpdated should never be called");
975 }
976
981 virtual void onInitialize() {}
982
987 virtual void onSimulationActivated() {}
988
994 virtual void onSimulationPreStep(uint32_t simStepMillis) {(void)simStepMillis;/*prevent unused parameter warnings*/}
995
1003 virtual void onSimulationStep(uint32_t simStepMillis) {(void)simStepMillis;/*prevent unused parameter warnings*/}
1004
1010 virtual void onSimulationPostStep(uint32_t simStepMillis) {(void)simStepMillis;/*prevent unused parameter warnings*/}
1011
1017 virtual void onPostTransformUpdate(uint32_t timeStepMillis) {(void)timeStepMillis;/*prevent unused parameter warnings*/}
1018
1028 virtual void onVariableStep(float simulationProgress, uint32_t variableStepMillis) {(void)simulationProgress; (void)variableStepMillis;/*prevent unused parameter warnings*/}
1029
1035 virtual void onPreRenderStep(float simulationProgress) {(void)simulationProgress;/*prevent unused parameter warnings*/}
1036
1042 virtual void onPostRenderStep(float simulationProgress) {(void)simulationProgress;/*prevent unused parameter warnings*/}
1043
1050 virtual void onSimulationDeactivated() {}
1051
1058 virtual void onDestroyed() {}
1059
1064 std::set<EntityID> mEnabledEntities {};
1065
1070 std::set<EntityID> mDisabledEntities {};
1071
1072 friend class SystemManager;
1073 friend class ECSWorld;
1074 };
1075
1084 template <typename TSystemDerived, typename TListenedForComponentsTuple, typename TRequiredComponentsTuple>
1085 class System{ static_assert(false && "Non specialized system cannot be declared"); };
1086
1097 template <typename TSystemDerived, typename ...TListenedForComponents, typename ...TRequiredComponents>
1098 class System<TSystemDerived, std::tuple<TListenedForComponents...>, std::tuple<TRequiredComponents...>>: public BaseSystem {
1099
1104 static void registerSelf();
1105
1106 protected:
1107
1115 explicit System(std::weak_ptr<ECSWorld> world): BaseSystem { world } { s_registrator.emptyFunc(); }
1116
1125 template<typename TComponent>
1126 TComponent getComponent(EntityID entityID, float progress=1.f) {
1127 assert(!isSingleton() && "Singletons cannot retrieve components by EntityID alone");
1129 }
1130
1138 template<typename TComponent>
1139 void updateComponent(EntityID entityID, const TComponent& component) {
1140 assert(!isSingleton() && "Singletons cannot retrieve components by EntityID alone");
1142 }
1143
1150 std::shared_ptr<BaseSystem> instantiate(std::weak_ptr<ECSWorld> world) override;
1151 private:
1152
1157 inline static Registrator<System<TSystemDerived, std::tuple<TListenedForComponents...>, std::tuple<TRequiredComponents...>>>& s_registrator {
1158 Registrator<System<TSystemDerived, std::tuple<TListenedForComponents...>, std::tuple<TRequiredComponents...>>>::getRegistrator()
1159 };
1160
1161 friend class Registrator<System<TSystemDerived, std::tuple<TListenedForComponents...>, std::tuple<TRequiredComponents...>>>;
1162 };
1163
1172 public:
1178 explicit SystemManager(std::weak_ptr<ECSWorld> world): mWorld{ world } {}
1179 private:
1186 SystemManager instantiate(std::weak_ptr<ECSWorld> world) const;
1187
1197 template<typename TSystem>
1198 void registerSystem(const Signature& signature, const Signature& listenedForComponents);
1199
1204 void unregisterAll();
1205
1212 template<typename TSystem>
1213 std::shared_ptr<TSystem> getSystem();
1214
1221 template<typename TSystem>
1222 void enableEntity(EntityID entityID);
1223
1233 void enableEntity(EntityID entityID, Signature entitySignature, Signature systemMask = Signature{}.set());
1234
1241 template<typename TSystem>
1242 void disableEntity(EntityID entityID);
1243
1250 void disableEntity(EntityID entityID, Signature entitySignature);
1251
1260 template<typename TSystem>
1261 SystemType getSystemType() const;
1262
1271 template<typename TSystem>
1272 bool isEnabled(EntityID entityID);
1273
1282 template <typename TSystem>
1283 bool isRegistered(EntityID entityID);
1284
1291 void handleEntitySignatureChanged(EntityID entityID, Signature signature);
1292
1298 void handleEntityDestroyed(EntityID entityID);
1299
1307 void handleEntityUpdated(EntityID entityID, Signature signature, ComponentType updatedComponent);
1308
1318 template<typename TSystem>
1319 void handleEntityUpdatedBySystem(EntityID entityID, Signature signature, ComponentType updatedComponent);
1320
1326 void handleInitialize();
1327
1333 void handleSimulationActivated();
1334
1342 void handleSimulationPreStep(uint32_t simStepMillis);
1343
1351 void handleSimulationStep(uint32_t simStepMillis);
1352
1360 void handleSimulationPostStep(uint32_t simStepMillis);
1361
1369 void handlePostTransformUpdate(uint32_t timeStepMillis);
1370
1380 void handleVariableStep(float simulationProgress, uint32_t variableStepMillis);
1381
1389 void handlePreRenderStep(float simulationProgress);
1390
1396 void handlePostRenderStep(float simulationProgress);
1397
1402 void handleSimulationDeactivated();
1403
1410 std::unordered_map<std::string, Signature> mNameToSignature {};
1411
1418 std::unordered_map<std::string, Signature> mNameToListenedForComponents {};
1419
1425 std::unordered_map<std::string, SystemType> mNameToSystemType {};
1426
1431 std::unordered_map<std::string, std::shared_ptr<BaseSystem>> mNameToSystem {};
1432
1437 std::weak_ptr<ECSWorld> mWorld;
1438
1439 friend class ECSWorld;
1440 friend class BaseSystem;
1441 };
1442
1462 class ECSWorld: public std::enable_shared_from_this<ECSWorld> {
1463 public:
1475 static std::weak_ptr<const ECSWorld> getPrototype();
1476
1482 std::shared_ptr<ECSWorld> instantiate() const;
1483
1541 template<typename ...TComponent>
1542 static void registerComponentTypes();
1543
1551 template <typename TSystemDerived, typename TListenedForComponents, typename TRequiredComponents>
1552 struct SystemRegistrationArgs { static_assert(false && "Cannot create unspecialized instance of SystemRegistrationArgs"); };
1553
1564 template <typename TSystemDerived, typename ...TListenedForComponents, typename ...TRequiredComponents>
1565 struct SystemRegistrationArgs<TSystemDerived, std::tuple<TListenedForComponents...>, std::tuple<TRequiredComponents...>> {};
1566
1567
1613 template <typename TSystemDerived, typename ...TListenedForComponents, typename ...TRequiredComponents>
1614 static void registerSystem(SystemRegistrationArgs<TSystemDerived, std::tuple<TListenedForComponents...>, std::tuple<TRequiredComponents...>>);
1615
1622 template<typename TSystem>
1623 std::shared_ptr<TSystem> getSystem();
1624
1633 template<typename TSystem>
1634 static std::shared_ptr<TSystem> getSystemPrototype();
1635
1646 template <typename TSingletonSystem>
1647 static std::shared_ptr<TSingletonSystem> getSingletonSystem();
1648
1659 template <typename TSystem>
1661
1668 template<typename TComponent>
1670
1679 template <typename TSystem>
1680 bool isEnabled(EntityID entityID);
1681
1690 template <typename TSystem>
1691 bool isRegistered(EntityID entityID);
1692
1702 template<typename ...TComponents>
1703 Entity createEntity(TComponents...components);
1704
1716 template <typename ...TComponents>
1717 static Entity createEntityPrototype(TComponents...components);
1718
1719 // Simulation lifecycle events
1720
1725 void initialize();
1726
1731 void activateSimulation();
1732
1737 void deactivateSimulation();
1738
1739 // Simulation loop events
1740
1750 void simulationPreStep(uint32_t simStepMillis);
1751
1759 void simulationStep(uint32_t simStepMillis);
1760
1768 void simulationPostStep(uint32_t simStepMillis);
1769
1777 void postTransformUpdate(uint32_t timeStepMillis);
1778
1789 void variableStep(float simulationProgress, uint32_t variableStepMillis);
1790
1798 void preRenderStep(float simulationProgress);
1799
1807 void postRenderStep(float simulationProgress);
1808
1813 void cleanup();
1814
1822 inline WorldID getID() const { return mID; }
1823
1824 private:
1825
1831 static std::shared_ptr<ECSWorld> createWorld();
1832
1838 static std::weak_ptr<ECSWorld> getInstance();
1839
1844 ECSWorld() = default;
1845
1852 void copyComponents(EntityID to, EntityID from);
1853
1861 void copyComponents(EntityID to, EntityID from, ECSWorld& other);
1862
1868 void relocateEntity(Entity& entity);
1869
1877 template<typename ...TComponents>
1878 Entity privateCreateEntity(TComponents...components);
1879
1887 void destroyEntity(EntityID entityID);
1888
1897 template<typename TSystem>
1898 void enableEntity(EntityID entityID);
1899
1908 void enableEntity(EntityID entityID, Signature systemMask = Signature{}.set());
1909
1918 template<typename TSystem>
1919 void disableEntity(EntityID entityID);
1920
1927 void disableEntity(EntityID entityID);
1928
1938 template<typename TComponent>
1939 void addComponent(EntityID entityID, const TComponent& component);
1940
1949 void addComponent(EntityID entityID, const nlohmann::json& jsonComponent);
1950
1951
1962 template<typename TComponent>
1963 TComponent getComponent(EntityID entityID, float simulationProgress=1.f) const;
1964
1975 template<typename TComponent, typename TSystem>
1976 TComponent getComponent(EntityID entityID, float simulationProgress=1.f) const;
1977
1988 template <typename TComponent>
1989 bool hasComponent(EntityID entityID) const;
1990
2002 bool hasComponent(EntityID entityID, const std::string& typeName) const;
2003
2013 template<typename TComponent>
2014 void updateComponent(EntityID entityID, const TComponent& newValue);
2015
2024 void updateComponent(EntityID entityID, const nlohmann::json& newValue);
2025
2036 template<typename TComponent, typename TSystem>
2037 void updateComponent(EntityID entityID, const TComponent& newValue);
2038
2048 template<typename TSystem>
2049 void updateComponent(EntityID entityID, const nlohmann::json& newValue);
2050
2059 template<typename TComponent>
2060 void removeComponent(EntityID entityID);
2061
2068 void removeComponent(EntityID entityID, const std::string& typeName);
2069
2075 void removeComponentsAll(EntityID entityID);
2076
2081 std::unique_ptr<ComponentManager> mComponentManager {nullptr};
2082
2087 std::unique_ptr<SystemManager> mSystemManager {nullptr};
2088
2093 std::vector<EntityID> mDeletedIDs {};
2094
2102
2108
2114
2115 friend class Entity;
2116 friend class BaseSystem;
2117 };
2118
2127 class Entity {
2128 public:
2134 Entity(const Entity& other);
2140 Entity(Entity&& other) noexcept;
2141
2148 Entity& operator=(const Entity& other);
2149
2156 Entity& operator=(Entity&& other) noexcept;
2157
2162 ~Entity();
2163
2169 inline EntityID getID() { return mID; };
2170
2178 void copy(const Entity& other);
2179
2188 template<typename TComponent>
2189 void addComponent(const TComponent& component);
2190
2198 void addComponent(const nlohmann::json& jsonComponent);
2199
2207 template<typename TComponent>
2208 void removeComponent();
2209
2217 void removeComponent(const std::string& typeName);
2218
2219
2229 template<typename TComponent>
2230 bool hasComponent() const;
2231
2241 bool hasComponent(const std::string& typeName) const;
2242
2252 template<typename TComponent>
2253 TComponent getComponent(float simulationProgress=1.f) const;
2254
2263 template<typename TComponent>
2264 void updateComponent(const TComponent& newValue);
2265
2273 void updateComponent(const nlohmann::json& jsonValue);
2274
2284 template<typename TSystem>
2285 bool isEnabled() const;
2286
2296 template <typename TSystem>
2297 bool isRegistered() const;
2298
2306 template<typename TSystem>
2307 void enableSystem();
2308
2316 template<typename TSystem>
2317 void disableSystem();
2318
2324 void disableSystems();
2325
2331 void enableSystems(Signature systemMask);
2332
2338 inline std::weak_ptr<ECSWorld> getWorld() { return mWorld; }
2339
2345 void joinWorld(ECSWorld& world);
2346
2347 private:
2354 Entity(EntityID entityID, std::shared_ptr<ECSWorld> world): mID{ entityID }, mWorld{ world } {};
2355
2361
2366 std::weak_ptr<ECSWorld> mWorld;
2367 friend class ECSWorld;
2368 };
2369
2370
2377 template<typename T>
2378 T Interpolator<T>::operator() (const T& previousState, const T& nextState, float simulationProgress) const {
2379 if(simulationProgress < .5f) return previousState;
2380 return nextState;
2381 }
2382
2383 template<typename TComponent>
2384 void ComponentArray<TComponent>::addComponent(EntityID entityID, const TComponent& component) {
2385 assert(mEntityToComponentIndex.find(entityID) == mEntityToComponentIndex.end() && "Component already added for this entity");
2386
2387 std::size_t newComponentID { mComponentsNext.size() };
2388
2389 const TComponent componentCopy { component };
2390 mComponentsNext.push_back(componentCopy);
2391 mComponentsPrevious.push_back(componentCopy);
2392 mEntityToComponentIndex[entityID] = newComponentID;
2393 mComponentToEntity[newComponentID] = entityID;
2394 }
2395
2396 template <typename TComponent>
2397 void ComponentArray<TComponent>::addComponent(EntityID entityID, const nlohmann::json& jsonComponent) {
2398 addComponent(entityID, ComponentFromJSON<TComponent>::get(jsonComponent));
2399 }
2400
2401 template <typename TComponent>
2402 void ComponentArray<TComponent>::updateComponent(EntityID entityID, const nlohmann::json& jsonComponent) {
2403 updateComponent(entityID, ComponentFromJSON<TComponent>::get(jsonComponent));
2404 }
2405
2406 template<typename TComponent>
2408 return mEntityToComponentIndex.find(entityID) != mEntityToComponentIndex.end();
2409 }
2410
2411 template<typename TComponent>
2413 assert(mEntityToComponentIndex.find(entityID) != mEntityToComponentIndex.end());
2414
2415 const std::size_t removedComponentIndex { mEntityToComponentIndex[entityID] };
2416 const std::size_t lastComponentIndex { mComponentsNext.size() - 1 };
2417 const std::size_t lastComponentEntity { mComponentToEntity[lastComponentIndex] };
2418
2419 // store last component in the removed components place
2420 mComponentsNext[removedComponentIndex] = mComponentsNext[lastComponentIndex];
2421 mComponentsPrevious[removedComponentIndex] = mComponentsPrevious[lastComponentIndex];
2422 // map the last component's entity to its new index
2423 mEntityToComponentIndex[lastComponentEntity] = removedComponentIndex;
2424 // map the removed component's index to the last entity
2425 mComponentToEntity[removedComponentIndex] = lastComponentEntity;
2426
2427 // erase all traces of the removed entity's component and other
2428 // invalid references
2429 mComponentsNext.pop_back();
2430 mComponentsPrevious.pop_back();
2431 mEntityToComponentIndex.erase(entityID);
2432 mComponentToEntity.erase(lastComponentIndex);
2433 }
2434
2435 template <typename TComponent>
2436 TComponent ComponentArray<TComponent>::getComponent(EntityID entityID, float simulationProgress) const {
2437 static Interpolator<TComponent> interpolator{};
2438 assert(mEntityToComponentIndex.find(entityID) != mEntityToComponentIndex.end());
2439 std::size_t componentID { mEntityToComponentIndex.at(entityID) };
2440 return interpolator(mComponentsPrevious[componentID], mComponentsNext[componentID], simulationProgress);
2441 }
2442
2443 template <typename TComponent>
2444 void ComponentArray<TComponent>::updateComponent(EntityID entityID, const TComponent& newComponent) {
2445 assert(mEntityToComponentIndex.find(entityID) != mEntityToComponentIndex.end());
2446 std::size_t componentID { mEntityToComponentIndex.at(entityID) };
2447 mComponentsNext[componentID] = newComponent;
2448 }
2449
2450 template <typename TComponent>
2452 if(mEntityToComponentIndex.find(entityID) != mEntityToComponentIndex.end()) {
2453 removeComponent(entityID);
2454 }
2455 }
2456
2457 template<typename TComponent>
2459 std::copy<typename std::vector<TComponent>::iterator, typename std::vector<TComponent>::iterator>(
2460 mComponentsNext.begin(), mComponentsNext.end(),
2461 mComponentsPrevious.begin()
2462 );
2463 }
2464
2465 template <typename TComponent>
2467 copyComponent(to, from, *this);
2468 }
2469
2470 template <typename TComponent>
2472 assert(to < kMaxEntities && "Cannot copy to an entity with an invalid entity ID");
2473 ComponentArray<TComponent>& downcastOther { static_cast<ComponentArray<TComponent>&>(other) };
2474 if(downcastOther.mEntityToComponentIndex.find(from) == downcastOther.mEntityToComponentIndex.end()) return;
2475
2476 const TComponent componentValueNext { downcastOther.mComponentsNext[downcastOther.mEntityToComponentIndex[from]] };
2477 const TComponent componentValuePrevious { downcastOther.mComponentsPrevious[downcastOther.mEntityToComponentIndex[from]] };
2478
2479 if(mEntityToComponentIndex.find(to) == mEntityToComponentIndex.end()) {
2480 addComponent(to, componentValueNext);
2481 } else {
2482 mComponentsNext[mEntityToComponentIndex[to]] = componentValueNext;
2483 }
2484 mComponentsPrevious[mEntityToComponentIndex[to]] = componentValuePrevious;
2485 }
2486
2487 template<typename TComponent>
2489 const std::size_t componentHash { typeid(TComponent).hash_code() };
2490 // nop when a component array for this type already exists
2491 if(mHashToComponentType.find(componentHash) != mHashToComponentType.end()) {
2492 return;
2493 }
2494
2495 std::string componentTypeName { getComponentTypeName<TComponent>{}() };
2496 assert(mHashToComponentType.size() + 1 < kMaxComponents && "Component type limit reached");
2497 assert(mNameToComponentHash.find(componentTypeName) == mNameToComponentHash.end() && "Another component with this name\
2498 has already been registered");
2499
2500 mNameToComponentHash.insert_or_assign(componentTypeName, componentHash);
2501 mHashToComponentArray.insert_or_assign(
2502 componentHash, std::static_pointer_cast<BaseComponentArray>(std::make_shared<ComponentArray<TComponent>>(mWorld))
2503 );
2504 mHashToComponentType[componentHash] = mHashToComponentType.size();
2505 }
2506
2507 template<typename TComponent>
2509 const std::size_t componentHash { typeid(TComponent).hash_code() };
2510 assert(mHashToComponentType.find(componentHash) != mHashToComponentType.end() && "Component type has not been registered");
2511 return mHashToComponentType.at(componentHash);
2512 }
2513
2514 template<typename TComponent>
2515 void ComponentManager::addComponent(EntityID entityID, const TComponent& component) {
2516 getComponentArray<TComponent>()->addComponent(entityID, component);
2517 mEntityToSignature[entityID].set(getComponentType<TComponent>(), true);
2518 }
2519
2520 template <typename TComponent>
2522 return getComponentArray<TComponent>()->hasComponent(entityID);
2523 }
2524
2525 template<typename TComponent>
2527 getComponentArray<TComponent>()->removeComponent(entityID);
2528 mEntityToSignature[entityID].set(getComponentType<TComponent>(), false);
2529 }
2530
2531 template<typename TComponent>
2532 TComponent ComponentManager::getComponent(EntityID entityID, float simulationProgress) const {
2533 return getComponentArray<TComponent>()->getComponent(entityID, simulationProgress);
2534 }
2535
2536 template<typename TComponent>
2537 void ComponentManager::updateComponent(EntityID entityID, const TComponent& newValue) {
2538 getComponentArray<TComponent>()->updateComponent(entityID, newValue);
2539 }
2540
2541 template <typename TComponent>
2543 assert(mEntityToSignature[from].test(getComponentType<TComponent>()) && "The entity being copied from does not have this component");
2544 getComponentArray<TComponent>()->copyComponent(to, from);
2546 }
2547
2548 template<typename TSystem>
2550 const std::string systemTypeName{ TSystem::getSystemTypeName() };
2551 assert(mNameToSystemType.find(systemTypeName) != mNameToSystemType.end() && "Component type has not been registered");
2552 return mNameToSystemType.at(systemTypeName);
2553 }
2554
2555 template <typename TSystem>
2557 return mSystemManager->isEnabled<TSystem>(entityID);
2558 }
2559 template <typename TSystem>
2561 return mSystemManager->isRegistered<TSystem>(entityID);
2562 }
2563
2564 template <typename TComponent>
2565 bool ECSWorld::hasComponent(EntityID entityID) const {
2566 return mComponentManager->hasComponent<TComponent>(entityID);
2567 }
2568
2569
2570 template <typename TSystemDerived, typename ...TListenedForComponents, typename ...TRequiredComponents>
2571 void System<TSystemDerived, std::tuple<TListenedForComponents...>, std::tuple<TRequiredComponents...>>::registerSelf() {
2572 ECSWorld::registerComponentTypes<TRequiredComponents...>();
2573 ECSWorld::registerComponentTypes<TListenedForComponents...>();
2574 ECSWorld::registerSystem(ECSWorld::SystemRegistrationArgs<TSystemDerived, std::tuple<TListenedForComponents...>, std::tuple<TRequiredComponents...>>{});
2575 }
2576
2577
2578 template<typename TSystem>
2579 void SystemManager::registerSystem(const Signature& signature, const Signature& listenedForComponents) {
2580 const std::string systemTypeName { TSystem::getSystemTypeName() };
2581 assert(mNameToSignature.find(systemTypeName) == mNameToSignature.end() && "System has already been registered");
2582 assert(mNameToSystemType.size() + 1 < kMaxSystems && "System type limit reached");
2583
2584 mNameToSignature[systemTypeName] = signature;
2585 mNameToListenedForComponents[systemTypeName] = listenedForComponents;
2586 mNameToSystem.insert_or_assign(systemTypeName, std::make_shared<TSystem>(mWorld));
2587 mNameToSystemType[systemTypeName] = mNameToSystemType.size();
2588 }
2589
2590 template<typename TSystem>
2591 std::shared_ptr<TSystem> SystemManager::getSystem() {
2592 std::string systemTypeName { TSystem::getSystemTypeName() };
2593 assert(mNameToSignature.find(systemTypeName) != mNameToSignature.end() && "System has not yet been registered");
2594 return std::dynamic_pointer_cast<TSystem>(mNameToSystem[systemTypeName]);
2595 }
2596
2597 template<typename TSystem>
2599 std::string systemTypeName { TSystem::getSystemTypeName() };
2600 mNameToSystem[systemTypeName]->enableEntity(entityID);
2601 }
2602
2603 template<typename TSystem>
2605 std::string systemTypeName { TSystem::getSystemTypeName() };
2606 mNameToSystem[systemTypeName]->disableEntity(entityID);
2607 }
2608
2609 template <typename TComponent>
2610 void Entity::addComponent(const TComponent& component) {
2611 mWorld.lock()->addComponent<TComponent>(mID, component);
2612 }
2613
2614 template <typename TComponent>
2616 return mWorld.lock()->hasComponent<TComponent>(mID);
2617 }
2618
2619 template<typename TComponent>
2620 TComponent Entity::getComponent(float simulationProgress) const {
2621 return mWorld.lock()->getComponent<TComponent>(mID, simulationProgress);
2622 }
2623
2624 template<typename TComponent>
2625 void Entity::updateComponent(const TComponent& newValue) {
2626 mWorld.lock()->updateComponent<TComponent>(mID, newValue);
2627 }
2628
2629 template <typename TComponent>
2631 mWorld.lock()->removeComponent<TComponent>(mID);
2632 }
2633
2634 template <typename TSystem>
2636 mWorld.lock()->enableEntity<TSystem>(mID);
2637 }
2638
2639 template <typename TSystem>
2640 bool Entity::isEnabled() const {
2641 return mWorld.lock()->isEnabled<TSystem>(mID);
2642 }
2643
2644 template <typename TSystem>
2646 return mWorld.lock()->isRegistered<TSystem>(mID);
2647 }
2648
2649 template <typename TSystem>
2651 mWorld.lock()->disableEntity<TSystem>(mID);
2652 }
2653
2654 template <typename TSystem>
2656 const std::string systemTypeName { TSystem::getSystemTypeName() };
2657 return mNameToSystem[systemTypeName]->isEnabled(entityID);
2658 }
2659
2660 template <typename TSystem>
2662 const std::string systemTypeName { TSystem::getSystemTypeName() };
2663 return mNameToSystem[systemTypeName]->isRegistered(entityID);
2664 }
2665
2666 template<typename ...TComponents>
2667 Entity ECSWorld::privateCreateEntity(TComponents...components) {
2668 assert((mNextEntity < kMaxEntities || !mDeletedIDs.empty()) && "Max number of entities reached");
2669
2670 EntityID nextID;
2671 if(!mDeletedIDs.empty()){
2672 nextID = mDeletedIDs.back();
2673 mDeletedIDs.pop_back();
2674 } else {
2675 nextID = mNextEntity++;
2676 }
2677
2678 Entity entity { nextID, shared_from_this()};
2679
2680 (addComponent<TComponents>(nextID, components), ...);
2681 return entity;
2682 }
2683
2684 template<typename TSystem>
2686 return mSystemManager->getSystemType<TSystem>();
2687 }
2688
2689 template<typename TComponent>
2691 return mComponentManager->getComponentType<TComponent>();
2692 }
2693
2694 template<typename TComponent>
2695 void ECSWorld::addComponent(EntityID entityID, const TComponent& component) {
2696 assert(entityID < kMaxEntities && "Cannot add a component to an entity that does not exist");
2697 mComponentManager->addComponent<TComponent>(entityID, component);
2698 Signature signature { mComponentManager->getSignature(entityID) };
2699 mSystemManager->handleEntitySignatureChanged(entityID, signature);
2700 }
2701
2702 template<typename TComponent>
2704 mComponentManager->removeComponent<TComponent>(entityID);
2705 Signature signature { mComponentManager->getSignature(entityID) };
2706 mSystemManager->handleEntitySignatureChanged(entityID, signature);
2707 }
2708
2709 template<typename TSystem>
2711 mSystemManager->enableEntity<TSystem>(entityID);
2712 }
2713
2714 template<typename TSystem>
2716 mSystemManager->disableEntity<TSystem>(entityID);
2717 }
2718
2719 template<typename TComponent>
2720 TComponent ECSWorld::getComponent(EntityID entityID, float progress) const {
2721 return mComponentManager->getComponent<TComponent>(entityID, progress);
2722 }
2723
2724 template<typename TComponent, typename TSystem>
2725 TComponent ECSWorld::getComponent(EntityID entityID, float progress) const {
2726 assert(
2727 (
2728 mSystemManager->mNameToSignature.at(TSystem::getSystemTypeName())
2729 .test(mComponentManager->getComponentType<TComponent>())
2730 )
2731 && "This system cannot access this kind of component"
2732 );
2733 return getComponent<TComponent>(entityID, progress);
2734 }
2735
2736
2737 template<typename TComponent>
2738 void ECSWorld::updateComponent(EntityID entityID, const TComponent& newValue) {
2739 mComponentManager->updateComponent<TComponent>(entityID, newValue);
2740 mSystemManager->handleEntityUpdated(
2741 entityID,
2742 mComponentManager->getSignature(entityID),
2743 mComponentManager->getComponentType<TComponent>()
2744 );
2745 }
2746
2747 template<typename TComponent, typename TSystem>
2748 void ECSWorld::updateComponent(EntityID entityID, const TComponent& newValue) {
2749 assert(
2750 (
2751 mSystemManager->mNameToSignature.at(TSystem::getSystemTypeName())
2752 .test(mComponentManager->getComponentType<TComponent>())
2753 )
2754 && "This system cannot access this kind of component"
2755 );
2756 mComponentManager->updateComponent<TComponent>(entityID, newValue);
2757 mSystemManager->handleEntityUpdatedBySystem<TSystem>(
2758 entityID,
2759 mComponentManager->getSignature(entityID),
2760 mComponentManager->getComponentType<TComponent>()
2761 );
2762 }
2763
2764 template <typename TSystem>
2765 void ECSWorld::updateComponent(EntityID entityID, const nlohmann::json& newValue) {
2766 assert(
2767 (
2768 mSystemManager->mNameToSignature.at(TSystem::getSystemTypeName())
2769 .test(mComponentManager->getComponentType(newValue.at("type")))
2770 )
2771 && "This system cannot access this kind of component"
2772 );
2773 mComponentManager->updateComponent(entityID, newValue);
2774 mSystemManager->handleEntityUpdatedBySystem<TSystem>(
2775 entityID,
2776 mComponentManager->getSignature(entityID),
2777 mComponentManager->getComponentType(newValue.at("type"))
2778 );
2779 }
2780
2781 template<typename ...TComponents>
2783 ((getInstance().lock()->mComponentManager->registerComponentArray<TComponents>()),...);
2784 }
2785
2786 template<typename TSystem, typename ...TListenedForComponents, typename ...TRequiredComponents>
2788 ECSWorld::SystemRegistrationArgs<TSystem, std::tuple<TListenedForComponents...>, std::tuple<TRequiredComponents...>>
2789 ) {
2790 Signature listensFor {};
2791 Signature required {};
2792
2793 (listensFor.set(getInstance().lock()->mComponentManager->getComponentType<TListenedForComponents>()), ...);
2794 (required.set(getInstance().lock()->mComponentManager->getComponentType<TRequiredComponents>()), ...);
2795
2796 getInstance().lock()->mSystemManager->registerSystem<TSystem>(required|listensFor, listensFor);
2797 }
2798
2799 template<typename ...TComponents>
2800 Entity ECSWorld::createEntity(TComponents...components) {
2801 return privateCreateEntity<TComponents...>(components...);
2802 }
2803
2804 template <typename ...TComponents>
2805 Entity ECSWorld::createEntityPrototype(TComponents...components) {
2806 return ECSWorld::getInstance().lock()->privateCreateEntity<TComponents...>(components...);
2807 }
2808
2809 template<typename TSystem>
2810 std::shared_ptr<TSystem> ECSWorld::getSystem() {
2811 return mSystemManager->getSystem<TSystem>();
2812 }
2813
2814 template<typename TSystem>
2815 std::shared_ptr<TSystem> ECSWorld::getSystemPrototype() {
2816 return getInstance().lock()->mSystemManager->getSystem<TSystem>();
2817 }
2818
2819 template <typename TSingletonSystem>
2820 std::shared_ptr<TSingletonSystem> ECSWorld::getSingletonSystem() {
2821 std::shared_ptr<TSingletonSystem> system { getInstance().lock()->getSystem<TSingletonSystem>() };
2822 assert(system->isSingleton() && "System specified is not an ECSWorld-aware singleton system");
2823 return system;
2824 }
2825
2826 template<typename TComponent>
2828 return mWorld.lock()->getComponentType<TComponent>();
2829 }
2830
2831 template<typename TComponent, typename TSystem>
2832 TComponent BaseSystem::getComponent_(EntityID entityID, float progress) const {
2833 assert(!isSingleton() && "Singletons cannot retrieve entity components through entity ID alone");
2834 return mWorld.lock()->getComponent<TComponent, TSystem>(entityID, progress);
2835 }
2836 template<typename TSystem, typename ...TListenedForComponents, typename ...TRequiredComponents>
2837 std::shared_ptr<BaseSystem> System<TSystem, std::tuple<TListenedForComponents...>, std::tuple<TRequiredComponents...>>::instantiate(std::weak_ptr<ECSWorld> world) {
2838 if(isSingleton()) return shared_from_this();
2839 return std::make_shared<TSystem>(world);
2840 }
2841
2842 template <typename TComponent>
2843 std::shared_ptr<BaseComponentArray> ComponentArray<TComponent>::instantiate(std::weak_ptr<ECSWorld> world) const {
2844 return std::make_shared<ComponentArray<TComponent>>(world);
2845 }
2846
2847 template<typename TComponent, typename TSystem>
2848 void BaseSystem::updateComponent_(EntityID entityID, const TComponent& component) {
2849 assert(!isSingleton() && "Singletons cannot retrieve entity components through entity ID alone");
2850 mWorld.lock()->updateComponent<TComponent, TSystem>(entityID, component);
2851 }
2852
2853 template<typename TSystem>
2855 std::string originatingSystemTypeName { TSystem::getSystemTypeName() };
2856 for(const auto& pair: mNameToSignature) {
2857 // see if the updated entity's signature matches that of the system
2858 if((pair.second&signature) != pair.second) continue;
2859
2860 // suppress update callback from the system that caused this update
2861 if(pair.first == originatingSystemTypeName) continue;
2862
2863 // see if the system is listening for updates to this system
2864 if(!mNameToListenedForComponents[pair.first].test(updatedComponent)) continue;
2865
2866 // ignore disabled and singleton systems
2867 BaseSystem& system { *(mNameToSystem[pair.first]).get() };
2868 if(system.isSingleton() || !system.isEnabled(entityID)) continue;
2869
2870 // apply update
2871 system.onEntityUpdated(entityID, updatedComponent);
2872 }
2873 }
2874
2875}
2876
2877#endif
An abstract base class for all ECS component arrays.
Definition ecs_world.hpp:166
virtual void copyComponent(EntityID to, EntityID from, BaseComponentArray &other)=0
Handles the copying of a component from one entity to another, where the other entity belongs to anot...
virtual void updateComponent(EntityID to, const nlohmann::json &jsonComponent)=0
Updates the component associated with an entity based on a json description of a new component.
virtual ~BaseComponentArray()=default
Destroy the Base Component Array object.
virtual std::shared_ptr< BaseComponentArray > instantiate(std::weak_ptr< ECSWorld > world) const =0
Creates a fresh, empty component array and associates it with a new World.
std::weak_ptr< ECSWorld > mWorld
A reference to the world to which this component array belongs.
Definition ecs_world.hpp:260
virtual void handleEntityDestroyed(EntityID entityID)=0
A virtual function that handles the side-effect of destroying an entity, i.e., deleting its component...
virtual void copyComponent(EntityID to, EntityID from)=0
Handles the copying of a component from one entity to another within the same array.
virtual void addComponent(EntityID to, const nlohmann::json &jsonComponent)=0
Constructs and adds a component to an array based on its json description.
BaseComponentArray(std::weak_ptr< ECSWorld > world)
Construct a new Base Component Array object.
Definition ecs_world.hpp:174
virtual bool hasComponent(EntityID entityID) const =0
Tests whether this array has an entry for this entity.
virtual void removeComponent(EntityID entityID)=0
Removes the component associated with this entity, if present.
virtual void handlePreSimulationStep()=0
An unimplemented callback for a step that occurs before each simulation step.
The base class that acts as the interface between the engine's ECS system and a particular built-in o...
Definition ecs_world.hpp:812
virtual void onInitialize()
An overridable callback for right after an ECS world has just been created.
Definition ecs_world.hpp:981
virtual void onSimulationDeactivated()
Overridable callback called just after the ECS world owning this system has been deactivated.
Definition ecs_world.hpp:1050
virtual void onPreRenderStep(float simulationProgress)
Overridable callback called just before the render step takes place.
Definition ecs_world.hpp:1035
virtual void onSimulationPostStep(uint32_t simStepMillis)
An overridable callback called once at the end of this simulation step, and after related transform u...
Definition ecs_world.hpp:1010
virtual void onEntityUpdated(EntityID entityID, ComponentType updatedComponentType)
An overridable callback for when another system has updated a component shared by this system and an ...
Definition ecs_world.hpp:970
void updateComponent_(EntityID entityID, const TComponent &component)
The actual implementation of updateComponent for a system.
Definition ecs_world.hpp:2848
virtual ~BaseSystem()=default
Destroy the Base System object.
void removeEntity(EntityID entityID)
Removes an entity from this system.
Definition ecs_world.cpp:128
virtual void onVariableStep(float simulationProgress, uint32_t variableStepMillis)
Overridable callback called after all simulation updates (if any) for the current frame have been com...
Definition ecs_world.hpp:1028
void enableEntity(EntityID entityID)
Allows a registered entity to be influenced by this system.
Definition ecs_world.cpp:81
std::weak_ptr< ECSWorld > mWorld
A reference to the world this system belongs to.
Definition ecs_world.hpp:915
virtual void onEntityDisabled(EntityID entityID)
An overridable callback for when an entity has been disabled.
Definition ecs_world.hpp:962
void disableEntity(EntityID entityID)
Prevents the influencing of an entity by this system.
Definition ecs_world.cpp:100
BaseSystem(std::weak_ptr< ECSWorld > world)
Construct a new Base System object.
Definition ecs_world.hpp:819
virtual void onPostTransformUpdate(uint32_t timeStepMillis)
An overridable callback called after all the transforms in the scene are updated by the scene system.
Definition ecs_world.hpp:1017
virtual std::shared_ptr< BaseSystem > instantiate(std::weak_ptr< ECSWorld > world)=0
Creates a fresh copy of this system and associates it with a new ECS World, using this system as its ...
bool isEnabled(EntityID entityID) const
Tests whether a particular entity is active for this system.
Definition ecs_world.cpp:141
virtual void onEntityEnabled(EntityID entityID)
An overridable callback for when an entity has been enabled.
Definition ecs_world.hpp:953
std::set< EntityID > mEnabledEntities
A set of all entities that are actively influenced by this system, managed by this system's ECS world...
Definition ecs_world.hpp:1064
virtual void onDestroyed()
Overridable callback called just before this system is destroyed.
Definition ecs_world.hpp:1058
virtual void onSimulationActivated()
An overridable callback for right after the ECS World has been activated.
Definition ecs_world.hpp:987
virtual void onSimulationStep(uint32_t simStepMillis)
An overridable callback called once in the middle of every simulation step.
Definition ecs_world.hpp:1003
const std::set< EntityID > & getEnabledEntities()
Get a set of all entities that are influenced by this System.
Definition ecs_world.cpp:133
virtual void onPostRenderStep(float simulationProgress)
Overridable callback called just after the render step takes place.
Definition ecs_world.hpp:1042
ComponentType getComponentType() const
Get the component type ID for a given component type.
Definition ecs_world.hpp:2827
virtual bool isSingleton() const
A method to query whether a particular System is a singleton, or is instantiated for each world in th...
Definition ecs_world.hpp:833
void addEntity(EntityID entityID, bool enabled=true)
Adds an entity to this system.
Definition ecs_world.cpp:112
std::set< EntityID > mDisabledEntities
A set of all entities that are compatible with this system, but have not been enabled for it.
Definition ecs_world.hpp:1070
virtual void onSimulationPreStep(uint32_t simStepMillis)
An overridable callback called once at the beginning of every simulation step in the game loop.
Definition ecs_world.hpp:994
TComponent getComponent_(EntityID entityID, float progress=1.f) const
The actual implementation of getComponent for a system.
Definition ecs_world.hpp:2832
bool isRegistered(EntityID entityID) const
Tests whether a particular entity can be influenced by this system.
Definition ecs_world.cpp:145
A class that implements BaseComponentArray specializing it for a component of type TComponent.
Definition ecs_world.hpp:364
std::shared_ptr< BaseComponentArray > instantiate(std::weak_ptr< ECSWorld > world) const override
Creates a new component array of the same type as this and associated with a new World.
Definition ecs_world.hpp:2843
std::unordered_map< std::size_t, EntityID > mComponentToEntity
A mapping from the index of a component to the ID of the entity that owns that component.
Definition ecs_world.hpp:498
void removeComponent(EntityID entityID) override
Removes the component associated with a specific entity, maintaining packing but not order.
Definition ecs_world.hpp:2412
virtual void handlePreSimulationStep() override
A callback for the start of a simulation step.
Definition ecs_world.hpp:2458
void addComponent(EntityID entityID, const TComponent &component)
Adds a component belonging to this entity to this array.
Definition ecs_world.hpp:2384
ComponentArray(std::weak_ptr< ECSWorld > world)
Construct a new Component Array object.
Definition ecs_world.hpp:371
void updateComponent(EntityID entityID, const TComponent &newValue)
Updates the value of the component belonging to this entity.
Definition ecs_world.hpp:2444
std::vector< TComponent > mComponentsPrevious
An array containing the state of each entity's component as seen in the last simulation tick.
Definition ecs_world.hpp:484
bool hasComponent(EntityID entityID) const override
Tests whether an entry for a component belonging to this entity is present.
Definition ecs_world.hpp:2407
TComponent getComponent(EntityID entityID, float simulationProgress=1.f) const
Get the component object.
Definition ecs_world.hpp:2436
std::unordered_map< EntityID, std::size_t > mEntityToComponentIndex
A mapping from the ID of an entity to the index in the component array that stores the entity's compo...
Definition ecs_world.hpp:491
virtual void handleEntityDestroyed(EntityID entityID) override
A callback to handle the side effect of the destruction of an entity. Here: deletion of the component...
Definition ecs_world.hpp:2451
virtual void copyComponent(EntityID to, EntityID from) override
Handles the copying of a component belonging to one entity to another.
Definition ecs_world.hpp:2466
std::vector< TComponent > mComponentsNext
An array containing the state of each entity's component as will be seen at the start of the next sim...
Definition ecs_world.hpp:478
An object that stores and manages updates to all the component arrays instantiated for this ECS World...
Definition ecs_world.hpp:509
void unregisterAll()
Unregisters all component arrays associated with this manager, as part of the destruction process for...
Definition ecs_world.cpp:435
Signature getSignature(EntityID entityID)
Get the component signature for a given entity.
Definition ecs_world.cpp:390
void copyComponent(EntityID to, EntityID from)
Copies a component value from one component to another within the same component array.
Definition ecs_world.hpp:2542
void handlePreSimulationStep()
Callback for the start of a simulation step, where the contents of every component's next member is c...
Definition ecs_world.cpp:520
std::unordered_map< EntityID, Signature > mEntityToSignature
Stores the component signature of each entity.
Definition ecs_world.hpp:796
void addComponent(EntityID entityID, const TComponent &component)
Adds a component entry for this entity in the array specified.
Definition ecs_world.hpp:2515
TComponent getComponent(EntityID entityID, float simulationProgress=1.f) const
Get the component value for this entity.
Definition ecs_world.hpp:2532
void updateComponent(EntityID entityID, const TComponent &newValue)
Updates a component belonging to an entity with its new value.
Definition ecs_world.hpp:2537
std::shared_ptr< BaseComponentArray > getComponentArray(const std::string &componentTypeName) const
Get the Component Array object.
Definition ecs_world.hpp:584
std::unordered_map< std::size_t, ComponentType > mHashToComponentType
Maps a component's type hash to its ComponentType.
Definition ecs_world.hpp:779
void copyComponents(EntityID to, EntityID from)
Copies all components from one entity and updates or adds them to the other.
Definition ecs_world.cpp:399
bool hasComponent(EntityID entityID) const
Tests whether an entity has a component of a particular type.
Definition ecs_world.hpp:2521
std::unordered_map< std::size_t, std::shared_ptr< BaseComponentArray > > mHashToComponentArray
Maps the hash of a component type to its corresponding ComponentArray.
Definition ecs_world.hpp:785
std::unordered_map< std::string, std::size_t > mNameToComponentHash
Maps each component type name to its corresponding hash.
Definition ecs_world.hpp:770
std::shared_ptr< ComponentArray< TComponent > > getComponentArray() const
Get the (specialized) Component Array object.
Definition ecs_world.hpp:572
void removeComponent(EntityID entityID)
Removes the component of the type specified from the entity.
Definition ecs_world.hpp:2526
ComponentManager(std::weak_ptr< ECSWorld > world)
Construct a new Component Manager object.
Definition ecs_world.hpp:516
std::weak_ptr< ECSWorld > mWorld
Holds a reference to the ECS world this component manager manages component arrays for.
Definition ecs_world.hpp:802
void handleEntityDestroyed(EntityID entityID)
Handles component arrays specific side effect of entity destruction.
Definition ecs_world.cpp:411
void registerComponentArray()
A method to allow a new component type to register itself with the ECS system for this project.
Definition ecs_world.hpp:2488
ComponentManager instantiate(std::weak_ptr< ECSWorld > world) const
Constructs a new component manager and associates it with the world passed in as argument....
Definition ecs_world.cpp:355
ComponentType getComponentType() const
Get the component type ID for a given component type.
Definition ecs_world.hpp:2508
A class that represents a set of systems, entities, and components, that are all interrelated,...
Definition ecs_world.hpp:1462
SystemType getSystemType()
Get the SystemType id for a particular system.
Definition ecs_world.hpp:2685
void cleanup()
Loses references to member systems, component arrays, and entities, resulting in their destruction.
Definition ecs_world.cpp:581
bool isRegistered(EntityID entityID)
Tests whether an entity is eligible for membership with a system, per its component signature.
Definition ecs_world.hpp:2560
void initialize()
Runs the initialization step for this world and the systems that belong to it.
Definition ecs_world.cpp:538
bool isEnabled(EntityID entityID)
Tests whether a particular entity is enabled for a particular system.
Definition ecs_world.hpp:2556
static Entity createEntityPrototype(TComponents...components)
Create a prototype entity object.
Definition ecs_world.hpp:2805
std::shared_ptr< ECSWorld > instantiate() const
Creates a new ECSWorld using the systems and component arrays present in this one as a template.
Definition ecs_world.cpp:491
void simulationPreStep(uint32_t simStepMillis)
Runs callbacks associated with the start of a simulation update.
Definition ecs_world.cpp:557
bool hasComponent(EntityID entityID) const
Tests whether an entity has a component of a specific type.
Definition ecs_world.hpp:2565
static void registerComponentTypes()
Registers ComponentArrays for each type of component present in the component type list,...
Definition ecs_world.hpp:2782
void enableEntity(EntityID entityID)
Enables an entity for a specific system.
Definition ecs_world.hpp:2710
EntityID mNextEntity
A new EntityID that has never been created before in this world.
Definition ecs_world.hpp:2101
ECSWorld()=default
Construct a new ECSWorld object.
TComponent getComponent(EntityID entityID, float simulationProgress=1.f) const
Get a component associated with an entity.
Definition ecs_world.hpp:2720
static std::weak_ptr< const ECSWorld > getPrototype()
Get the prototype ECSWorld.
Definition ecs_world.cpp:475
static std::shared_ptr< TSingletonSystem > getSingletonSystem()
Get a system that has been marked as a singleton System.
Definition ecs_world.hpp:2820
void simulationPostStep(uint32_t simStepMillis)
Runs calbacks associated with the end of the simulation step.
Definition ecs_world.cpp:564
void simulationStep(uint32_t simStepMillis)
Runs callbacks associated with the simulation step.
Definition ecs_world.cpp:561
WorldID getID() const
Gets the ID associated with this world.
Definition ecs_world.hpp:1822
void destroyEntity(EntityID entityID)
Destroys an Entity with a specific ID.
Definition ecs_world.cpp:513
std::vector< EntityID > mDeletedIDs
A list of previously existing entity IDs that were since retired and are available to be used again.
Definition ecs_world.hpp:2093
void relocateEntity(Entity &entity)
Moves an entity from one ECSWorld to this one.
Definition ecs_world.cpp:62
void copyComponents(EntityID to, EntityID from)
Copies components from one entity to another within a single ECSWorld.
Definition ecs_world.cpp:527
ComponentType getComponentType() const
Get the component type ID for a given component type.
Definition ecs_world.hpp:2690
void preRenderStep(float simulationProgress)
Runs callbacks associated with the start of the rendering step.
Definition ecs_world.cpp:574
std::unique_ptr< SystemManager > mSystemManager
A reference to this world SystemManager.
Definition ecs_world.hpp:2087
void activateSimulation()
Marks this world as an active one, calling the activation callbacks of systems that belong to it.
Definition ecs_world.cpp:541
void removeComponent(EntityID entityID)
Removes a component from an entity.
Definition ecs_world.hpp:2703
Entity privateCreateEntity(TComponents...components)
Creates a new entity and assigns it the components specified as arguments.
Definition ecs_world.hpp:2667
WorldID mID
The unique ID associated with this ECSWorld.
Definition ecs_world.hpp:2107
std::unique_ptr< ComponentManager > mComponentManager
A reference to this world's ComponentManager.
Definition ecs_world.hpp:2081
static std::shared_ptr< TSystem > getSystemPrototype()
Get the system object of a specific type belonging to the prototype ECSWorld.
Definition ecs_world.hpp:2815
void updateComponent(EntityID entityID, const TComponent &newValue)
Updates a component belonging to an entity with a new value.
Definition ecs_world.hpp:2738
Entity createEntity(TComponents...components)
Creates a new entity that will exist in this ECSWorld.
Definition ecs_world.hpp:2800
void postRenderStep(float simulationProgress)
Runs callbacks associated with the end of the rendering step.
Definition ecs_world.cpp:577
void postTransformUpdate(uint32_t timeStepMillis)
Runs callbacks associated with the end of transform updates.
Definition ecs_world.cpp:568
std::shared_ptr< TSystem > getSystem()
Get the system object of a specific type belonging to this ECSWorld.
Definition ecs_world.hpp:2810
void disableEntity(EntityID entityID)
Disables an entity on a particular system.
Definition ecs_world.hpp:2715
void variableStep(float simulationProgress, uint32_t variableStepMillis)
Runs callbacks associated with the variable step of the game loop.
Definition ecs_world.cpp:571
void deactivateSimulation()
Marks ths world as an inactive one, and suspends operation for its member systems.
Definition ecs_world.cpp:544
static void registerSystem(SystemRegistrationArgs< TSystemDerived, std::tuple< TListenedForComponents... >, std::tuple< TRequiredComponents... > >)
Registers a System with the ECS System for this project.
static WorldID s_nextWorld
The ID the next ECSWorld to be instantiated will receive.
Definition ecs_world.hpp:2113
static std::weak_ptr< ECSWorld > getInstance()
Creates an instance of the prototype ECSWorld, and returns a reference to it.
Definition ecs_world.cpp:486
void addComponent(EntityID entityID, const TComponent &component)
Adds a new component to the entity.
Definition ecs_world.hpp:2695
The Entity is a wrapper on an entity ID, used as the primary interface between an application and the...
Definition ecs_world.hpp:2127
void addComponent(const TComponent &component)
Adds a new component to this Entity.
Definition ecs_world.hpp:2610
EntityID getID()
Gets the ID associated with this Entity.
Definition ecs_world.hpp:2169
std::weak_ptr< ECSWorld > mWorld
The world this Entity belongs to.
Definition ecs_world.hpp:2366
void updateComponent(const TComponent &newValue)
Updates the value of a component belonging to this Entity.
Definition ecs_world.hpp:2625
void disableSystem()
Disables this entity for a particular system.
Definition ecs_world.hpp:2650
EntityID mID
The ID of this entity within its owning ECSWorld.
Definition ecs_world.hpp:2360
Entity & operator=(const Entity &other)
Copies an Entity object, replacing any component values currently present on this one.
Definition ecs_world.cpp:32
bool hasComponent() const
Tests whether this entity has a particular component.
Definition ecs_world.hpp:2615
std::weak_ptr< ECSWorld > getWorld()
Get the ECSWorld object this Entity belongs to.
Definition ecs_world.hpp:2338
void enableSystem()
Enables this Entity for a particular System.
Definition ecs_world.hpp:2635
Entity(const Entity &other)
Construct a new Entity object.
Definition ecs_world.cpp:16
bool isRegistered() const
Tests whether this entity is eligible for participation with a given system.
Definition ecs_world.hpp:2645
Entity(EntityID entityID, std::shared_ptr< ECSWorld > world)
Construct a new Entity object, with a new ID as a member of a new ECSWorld.
Definition ecs_world.hpp:2354
bool isEnabled() const
Tests whether this entity is enabled for a particular system.
Definition ecs_world.hpp:2640
TComponent getComponent(float simulationProgress=1.f) const
Get the value of the component at a specific time this frame.
Definition ecs_world.hpp:2620
void removeComponent()
Removes a component from an entity.
Definition ecs_world.hpp:2630
A template class for interpolating components between simulation frames for various purposes.
Definition ecs_world.hpp:335
RangeMapperLinear mProgressLimits
a functor that performs the actual interpolation in the default case
Definition ecs_world.hpp:352
A simple linear interpolation implementation between a fixed input and output range.
Definition util.hpp:213
Helper class for registering a class at program startup.
Definition registrator.hpp:64
Holds references to all the systems belonging to this manager's ECSWorld.
Definition ecs_world.hpp:1171
void disableEntity(EntityID entityID)
Disables an entity for a particular system.
Definition ecs_world.hpp:2604
std::unordered_map< std::string, Signature > mNameToListenedForComponents
Mapping from the system type name for a system to its component listening signature.
Definition ecs_world.hpp:1418
std::weak_ptr< ECSWorld > mWorld
The world this System manager belongs to.
Definition ecs_world.hpp:1437
bool isEnabled(EntityID entityID)
Tests whether an entity is enabled for a particular system.
Definition ecs_world.hpp:2655
SystemManager(std::weak_ptr< ECSWorld > world)
Construct a new System Manager object.
Definition ecs_world.hpp:1178
SystemType getSystemType() const
Get the SystemType for a system.
Definition ecs_world.hpp:2549
std::unordered_map< std::string, std::shared_ptr< BaseSystem > > mNameToSystem
Maps system type names to references to the actual in-memory Systems they represent.
Definition ecs_world.hpp:1431
std::shared_ptr< TSystem > getSystem()
Gets an instance of a system belonging to this ECS World.
Definition ecs_world.hpp:2591
void enableEntity(EntityID entityID)
Enables the visibility of an entity to a particular system.
Definition ecs_world.hpp:2598
std::unordered_map< std::string, Signature > mNameToSignature
Mapping from the system type name for a system to its component signature.
Definition ecs_world.hpp:1410
std::unordered_map< std::string, SystemType > mNameToSystemType
Maps system type names to their corresponding SystemType values.
Definition ecs_world.hpp:1425
void handleEntityUpdatedBySystem(EntityID entityID, Signature signature, ComponentType updatedComponent)
Handles an update to an entity by running a callback on all interested systems (except the one that t...
Definition ecs_world.hpp:2854
void registerSystem(const Signature &signature, const Signature &listenedForComponents)
During static initialization, adds the new System type and its component signatures to its tables.
Definition ecs_world.hpp:2579
bool isRegistered(EntityID entityID)
Tests whether an entity is eligible for participation in a particular system.
Definition ecs_world.hpp:2661
void updateComponent(EntityID entityID, const TComponent &component)
Updates a component via this system's specialized version of updateComponent.
Definition ecs_world.hpp:1139
std::shared_ptr< BaseSystem > instantiate(std::weak_ptr< ECSWorld > world) override
Instantiates a fresh System using this one as a template, and associates it with a new world.
System(std::weak_ptr< ECSWorld > world)
Construct a new System object.
Definition ecs_world.hpp:1115
static void registerSelf()
Helper function called during static initialization to make this project's ECS system aware that this...
Definition ecs_world.hpp:2571
TComponent getComponent(EntityID entityID, float progress=1.f)
Gets the component belonging to the entity using this System's specialized version of getComponent.
Definition ecs_world.hpp:1126
static Registrator< System< TSystemDerived, std::tuple< TListenedForComponents... >, std::tuple< TRequiredComponents... > > > & s_registrator
A specialization of Registrator<T> which ensures registerSelf() is called during this project's stati...
Definition ecs_world.hpp:1157
A system template that disables systems with this form of declaration.
Definition ecs_world.hpp:1085
ECSType ComponentType
An unsigned integer representing the type of a component.
Definition ecs_world.hpp:101
T operator()(const T &previousState, const T &nextState, float simulationProgress=1.f) const
Returns an interpolated value for a component between two given states.
Definition ecs_world.hpp:2378
constexpr ComponentType kMaxComponents
A constant that restricts the number of definable components in a project.
Definition ecs_world.hpp:130
std::bitset< kMaxComponents > Signature
A 255 bit number, where each enabled bit represents a relationship between an entity and some ECS rel...
Definition ecs_world.hpp:152
constexpr SystemType kMaxSystems
A constant that restricts the number of definable systems in a project.
Definition ecs_world.hpp:137
ECSType SystemType
An unsigned integer representing the type of a system.
Definition ecs_world.hpp:110
std::uint8_t ECSType
A number tag used to represent components and systems.
Definition ecs_world.hpp:91
constexpr EntityID kMaxEntities
A user-set constant which limits the number of creatable entities in a single ECS system.
Definition ecs_world.hpp:117
std::pair< WorldID, EntityID > UniversalEntityID
An ID that uniquely identifies an entity.
Definition ecs_world.hpp:83
std::uint64_t EntityID
A single unsigned integer used as a name for an entity managed by an ECS system.
Definition ecs_world.hpp:66
std::uint64_t WorldID
An unsigned integer representing the name of an ECS world.
Definition ecs_world.hpp:74
constexpr ECSType kMaxECSTypes
A constant used to restrict the number of definable system and component types in a project.
Definition ecs_world.hpp:123
Namespace containing all class definitions and functions related to the ToyMaker engine.
Definition application.hpp:26
STL namespace.
Contains the definition for the Registrator<T> utility class, used anywhere that automatic registrati...
A struct that describes how a JSON component description is turned into a component.
Definition ecs_world.hpp:287
static TComponent get(const nlohmann::json &jsonComponent)
Get method that automatically invokes a from_json function, found by nlohmann json.
Definition ecs_world.hpp:294
Helper function for retrieving the component type string defined as part of the component.
Definition ecs_world.hpp:541
std::string operator()()
The method that retrieves the component type string.
Definition ecs_world.hpp:547
Prevents the use of the unspecialized version of SystemRegistrationArgs.
Definition ecs_world.hpp:1552
Contains a couple of classes not tied to any part of the engine in particular, but useful to those pa...