#pragma once #include #include #include #include #include #include class Component; enum class eReplicaComponentType : uint32_t; using LWOOBJID = int64_t; namespace dECS { // template // concept IsComponent = std::derived_from; // Data structures struct WorldData; class World; template class System; class Entity; struct IStorage; template class Storage; using WorldPtr = std::shared_ptr; using WeakWorldPtr = std::weak_ptr; class World { public: World(); [[nodiscard]] Entity MakeEntity(); template [[nodiscard]] System MakeSystem() { return System{}; } template [[nodiscard]] System MakeSystem(S&& name) { return System{ std::forward(name) }; } private: WorldPtr m_World; }; template class System { public: friend System World::MakeSystem(); template friend System World::MakeSystem(S&&); /*template requires std::is_invocable_r_v void ForEach(Fn&& f) { for (ObjId i = 0; i < mT.size(); ++i) { auto& c = mT[i]; f(i, std::get(c)...); } }*/ template requires std::is_invocable_r_v void ForEach(Fn&& fn) { std::tuple comps; // some sort of iterator that returns a tuple each 'step?' for (size_t i = 0; i < 5; ++i) { fn(std::get(comps)...); } } private: System() = default; template explicit System(S&& name) : m_name{ std::forward(name) } {} std::string m_name; }; class Entity { public: friend Entity World::MakeEntity(); using StorageConstructor = std::function()>; [[nodiscard]] constexpr LWOOBJID GetObjectID() const noexcept { return m_Id; } [[maybe_unused]] void* AddComponent(eReplicaComponentType, StorageConstructor); template [[maybe_unused]] C* AddComponent() { return static_cast(AddComponent(C::ComponentType, std::make_unique>)); } [[nodiscard]] const void* GetComponent(eReplicaComponentType) const; [[nodiscard]] void* GetComponent(eReplicaComponentType); template [[nodiscard]] const C* GetComponent() const { return static_cast(GetComponent(C::ComponentType)); } template [[nodiscard]] C* GetComponent() { return static_cast(GetComponent(C::ComponentType)); } private: Entity(const LWOOBJID id, const WeakWorldPtr world) : m_Id{ id } , m_World { world } {} LWOOBJID m_Id; WeakWorldPtr m_World; }; struct IStorage { using RowMap = std::unordered_map; virtual ~IStorage() = default; [[nodiscard]] virtual void* at(size_t) = 0; [[nodiscard]] virtual const void* at(size_t) const = 0; [[nodiscard]] virtual void* emplace_back() = 0; RowMap rowMap; }; template class Storage : public IStorage { public: [[nodiscard]] void* at(const size_t index) override { return static_cast(&m_Vec.at(index)); } [[nodiscard]] const void* at(const size_t index) const override { return static_cast(&m_Vec.at(index)); } [[nodiscard]] void* emplace_back() override { return static_cast(&m_Vec.emplace_back()); } private: std::vector m_Vec; }; }