Skip to content

Commit

Permalink
world resource
Browse files Browse the repository at this point in the history
  • Loading branch information
Ubpa committed Mar 22, 2021
1 parent 8288be9 commit a2d3305
Show file tree
Hide file tree
Showing 16 changed files with 222 additions and 104 deletions.
1 change: 1 addition & 0 deletions doc/changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
- remove none-parallel
- support change filter
- multiple sysc points (layer)
- world resource
- 0.15.1
- support MacOS GCC 10.2
- 0.15.0
Expand Down
29 changes: 16 additions & 13 deletions include/UECS/CmptTraits.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
#include <string>

namespace Ubpa::UECS {
class EntityMngr;

// run-time dynamic component traits
// size (> 0) is neccessary
// optional
Expand All @@ -23,20 +25,14 @@ namespace Ubpa::UECS {
public:
static constexpr std::size_t default_alignment = alignof(std::max_align_t);

CmptTraits();
CmptTraits(const CmptTraits& other);
CmptTraits(CmptTraits&& other) noexcept = default;
CmptTraits& operator=(const CmptTraits & other);
CmptTraits& operator=(CmptTraits&& other) noexcept = default;

CmptTraits& Clear();

CmptTraits& RegisterName(Type);
CmptTraits& RegisterTrivial(TypeID);
CmptTraits& RegisterSize(TypeID, std::size_t size);
CmptTraits& RegisterAlignment(TypeID, std::size_t alignment);
CmptTraits& RegisterDefaultConstructor(TypeID, std::function<void(void*)>);
CmptTraits& RegisterCopyConstructor(TypeID, std::function<void(void*,void*)>);
CmptTraits& RegisterDefaultConstructor(TypeID, std::function<void(void*, std::pmr::memory_resource*)>);
CmptTraits& RegisterCopyConstructor(TypeID, std::function<void(void*,const void*, std::pmr::memory_resource*)>);
CmptTraits& RegisterMoveConstructor(TypeID, std::function<void(void*,void*)>);
CmptTraits& RegisterMoveAssignment(TypeID, std::function<void(void*,void*)>);
CmptTraits& RegisterDestructor(TypeID, std::function<void(void*)>);
Expand All @@ -54,7 +50,7 @@ namespace Ubpa::UECS {
std::size_t Sizeof(TypeID) const;
std::size_t Alignof(TypeID) const;
void DefaultConstruct(TypeID, void* cmpt) const;
void CopyConstruct(TypeID, void* dst, void* src) const;
void CopyConstruct(TypeID, void* dst, const void* src) const;
void MoveConstruct(TypeID, void* dst, void* src) const;
void MoveAssign(TypeID, void* dst, void* src) const;
void Destruct(TypeID, void* cmpt) const;
Expand All @@ -72,6 +68,11 @@ namespace Ubpa::UECS {
void Deregister();

private:
friend class EntityMngr;
CmptTraits(std::pmr::memory_resource* world_rsrc);
CmptTraits(const CmptTraits& other, std::pmr::memory_resource* world_rsrc);
CmptTraits(CmptTraits&& other) noexcept;

// register all for Cmpt
// static_assert
// - is_default_constructible_v
Expand All @@ -90,11 +91,13 @@ namespace Ubpa::UECS {
std::unordered_map<TypeID, std::string_view> names;
std::unordered_map<TypeID, std::size_t> sizeofs;
std::unordered_map<TypeID, std::size_t> alignments;
std::unordered_map<TypeID, std::function<void(void*)>> default_constructors; // dst <- src
std::unordered_map<TypeID, std::function<void(void*,void*)>> copy_constructors; // dst <- src
std::unordered_map<TypeID, std::function<void(void*,void*)>> move_constructors; // dst <- src
std::unordered_map<TypeID, std::function<void(void*,void*)>> move_assignments; // dst <- src
std::unordered_map<TypeID, std::function<void(void*, std::pmr::memory_resource*)>> default_constructors; // dst <- src
std::unordered_map<TypeID, std::function<void(void*, const void*, std::pmr::memory_resource*)>> copy_constructors; // dst <- src
std::unordered_map<TypeID, std::function<void(void*, void*)>> move_constructors; // dst <- src
std::unordered_map<TypeID, std::function<void(void*, void*)>> move_assignments; // dst <- src
std::unordered_map<TypeID, std::function<void(void*)>> destructors;

std::pmr::memory_resource* world_rsrc;
};
}

Expand Down
11 changes: 6 additions & 5 deletions include/UECS/EntityMngr.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,6 @@ namespace Ubpa::UECS {
// - when free entries is empty, use new entity entry (version is 0)
class EntityMngr {
public:
EntityMngr();
EntityMngr(const EntityMngr& em);
EntityMngr(EntityMngr&&) noexcept;
~EntityMngr();

CmptTraits cmptTraits;

Entity Create(std::span<const TypeID> types = {});
Expand Down Expand Up @@ -87,6 +82,11 @@ namespace Ubpa::UECS {

void Clear();
private:
EntityMngr(std::pmr::memory_resource* world_rsrc);
EntityMngr(const EntityMngr& em, std::pmr::memory_resource* world_rsrc);
EntityMngr(EntityMngr&&) noexcept;
~EntityMngr();

friend class World;
friend class Archetype;

Expand All @@ -110,6 +110,7 @@ namespace Ubpa::UECS {
bool AutoGen(World*, Job*, SystemFunc*, int layer) const;

std::uint64_t version{ 0 };
std::pmr::memory_resource* world_rsrc;

struct EntityInfo {
Archetype* archetype{ nullptr };
Expand Down
3 changes: 3 additions & 0 deletions include/UECS/Schedule.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,9 @@ namespace Ubpa::UECS {
T* CreateFrameObject(Args&&... args) const;
std::string_view RegisterFrameString(std::string_view str);


Schedule& operator=(Schedule&&) noexcept = delete;
Schedule& operator=(const Schedule&) = delete;
private:
Schedule();
Schedule(const Schedule&);
Expand Down
14 changes: 9 additions & 5 deletions include/UECS/World.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ namespace Ubpa::UECS {

// SystemMngr + EntityMngr
class World {
std::unique_ptr<std::pmr::synchronized_pool_resource> world_rsrc; // init before entityMngr

public:
World();
World(const World&);
Expand All @@ -24,10 +26,10 @@ namespace Ubpa::UECS {
SystemMngr systemMngr;
EntityMngr entityMngr;

// 1. schedule: run registered System's static OnUpdate(Schedule&)
// 2. gen job graph: schedule -> graph
// 3. run job graph in worker threads
// 4. run commands in main thread
// 1. update schedule
// 2. run job graph for several layers
// 3. update version
// 4. clear frame resource
void Update();

void AddCommand(std::function<void()> command, int layer);
Expand Down Expand Up @@ -116,6 +118,8 @@ namespace Ubpa::UECS {
template<typename T, typename... Args>
T* SyncCreateFrameObject(Args&&... args);

std::pmr::synchronized_pool_resource* GetSyncResource() { return world_rsrc.get(); }

std::uint64_t Version() const noexcept { return version; }
private:
bool inRunningJobGraph{ false };
Expand All @@ -126,7 +130,7 @@ namespace Ubpa::UECS {

Job jobGraph;
std::vector<Job*> jobs;
std::unique_ptr<std::pmr::unsynchronized_pool_resource> jobRsrc;
std::unique_ptr<std::pmr::monotonic_buffer_resource> jobRsrc;

// command
std::map<int, CommandBuffer> lcommandBuffer;
Expand Down
49 changes: 41 additions & 8 deletions include/UECS/details/CmptTraits.inl
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,24 @@

#include "../CmptTraits.hpp"

namespace Ubpa::UECS::details {
template<typename T>
concept ContainPmrAlloc = requires() {
typename T::allocator_type;
std::is_constructible_v<typename T::allocator_type, std::pmr::memory_resource*>;
};

template<typename T>
concept DefaultCtorWithAlloc = ContainPmrAlloc<T> && requires(const typename T::allocator_type & alloc) {
new T(alloc);
};

template<typename T>
concept CopyCtorWithAlloc = ContainPmrAlloc<T> &&
(requires(const T & other, const typename T::allocator_type & alloc) { new T(other, alloc); }
|| requires(const T & other, const typename T::allocator_type & alloc) { new T(std::allocator_arg_t{}, alloc, other); });
}

namespace Ubpa::UECS {
template<typename... Cmpts>
void CmptTraits::Register() {
Expand All @@ -23,9 +41,16 @@ namespace Ubpa::UECS {
alignments.emplace(type.GetID(), alignof(Cmpt));
names.emplace(type.GetID(), type.GetName());

if constexpr (std::is_default_constructible_v<Cmpt>) {
default_constructors.emplace(type.GetID(), [](void* cmpt) {
new(cmpt)Cmpt{};
if constexpr (details::DefaultCtorWithAlloc<Cmpt>) {
default_constructors.emplace(type.GetID(), [](void* cmpt, std::pmr::memory_resource* world_rsrc) {
using Alloc = typename Cmpt::allocator_type;
Alloc alloc(world_rsrc);
std::allocator_traits<Alloc>::template construct(alloc, reinterpret_cast<Cmpt*>(cmpt));
});
}
else if constexpr (std::is_default_constructible_v<Cmpt>) {
default_constructors.emplace(type.GetID(), [](void* cmpt, std::pmr::memory_resource*) {
new(cmpt)Cmpt();
});
}

Expand All @@ -46,18 +71,26 @@ namespace Ubpa::UECS {
*static_cast<Cmpt*>(dst) = std::move(*static_cast<Cmpt*>(src));
});
}
if constexpr (std::is_copy_constructible_v<Cmpt> && !std::is_trivially_copy_constructible_v<Cmpt>) {
copy_constructors.emplace(type.GetID(), [](void* dst, void* src) {
new(dst)Cmpt(*static_cast<Cmpt*>(src));

if constexpr (details::CopyCtorWithAlloc<Cmpt>) {
copy_constructors.emplace(type.GetID(), [](void* dst, const void* src, std::pmr::memory_resource* world_rsrc) {
using Alloc = typename Cmpt::allocator_type;
Alloc alloc(world_rsrc);
std::allocator_traits<Alloc>::template construct(alloc, reinterpret_cast<Cmpt*>(dst), *static_cast<const Cmpt*>(src));
});
}
else if constexpr (std::is_copy_constructible_v<Cmpt> && !std::is_trivially_copy_constructible_v<Cmpt>) {
copy_constructors.emplace(type.GetID(), [](void* dst, const void* src, std::pmr::memory_resource*) {
new(dst)Cmpt(*static_cast<const Cmpt*>(src));
});
}
}

template<typename Cmpt>
void CmptTraits::RegisterOne() {
static_assert(!IsTaggedCmpt_v<Cmpt>, "<Cmpt> should not be tagged");
static_assert(std::is_default_constructible_v<Cmpt>, "<Cmpt> must be default-constructible");
static_assert(std::is_copy_constructible_v<Cmpt>, "<Cmpt> must be copy-constructible");
static_assert(std::is_default_constructible_v<Cmpt> || details::DefaultCtorWithAlloc<Cmpt>, "<Cmpt> must be default-constructible or with alloc");
static_assert(std::is_copy_constructible_v<Cmpt> || details::CopyCtorWithAlloc<Cmpt>, "<Cmpt> must be copy-constructible or with alloc");
static_assert(std::is_move_constructible_v<Cmpt>, "<Cmpt> must be move-constructible");
static_assert(std::is_move_assignable_v<Cmpt>, "<Cmpt> must be move-assignable");
static_assert(std::is_destructible_v<Cmpt>, "<Cmpt> must be destructible");
Expand Down
32 changes: 22 additions & 10 deletions src/core/Archetype.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,11 @@
using namespace Ubpa::UECS;
using namespace std;

Archetype::Archetype(std::pmr::memory_resource* rsrc, std::pmr::memory_resource* world_rsrc, std::uint64_t version) noexcept :
chunkAllocator{ rsrc },
version{ version },
world_rsrc{ world_rsrc }{}

Archetype::~Archetype() {
if (cmptTraits.IsTrivial())
return;
Expand All @@ -26,8 +31,9 @@ Archetype::~Archetype() {
// entityMngr->sharedChunkPool.Recycle(chunk);
}

Archetype::Archetype(std::pmr::memory_resource* rsrc, const Archetype& src)
: chunkAllocator{ rsrc }
Archetype::Archetype(std::pmr::memory_resource* rsrc, std::pmr::memory_resource* world_rsrc, const Archetype& src) :
chunkAllocator{ rsrc },
world_rsrc{ world_rsrc }
{
cmptTraits = src.cmptTraits;
entityNum = src.entityNum;
Expand Down Expand Up @@ -61,7 +67,7 @@ Archetype::Archetype(std::pmr::memory_resource* rsrc, const Archetype& src)
if (trait.copy_ctor) {
for (std::size_t j = 0; j < num; j++) {
auto offset_j = j * trait.size;
trait.copy_ctor(dstBegin + offset_j, srcBegin + offset_j);
trait.copy_ctor(dstBegin + offset_j, srcBegin + offset_j, world_rsrc);
}
}
else
Expand All @@ -83,7 +89,7 @@ Archetype::Archetype(std::pmr::memory_resource* rsrc, const Archetype& src)
auto* cursor_dst = dstChunk->data + offsets[j];
if (trait.copy_ctor) {
for (std::size_t k = 0; k < num; k++) {
trait.copy_ctor(cursor_dst, cursor_src);
trait.copy_ctor(cursor_dst, cursor_src, world_rsrc);
cursor_src += trait.size;
cursor_dst += trait.size;
}
Expand Down Expand Up @@ -129,10 +135,16 @@ void Archetype::SetLayout() {
}
}

Archetype* Archetype::New(CmptTraits& rtdCmptTraits, std::pmr::memory_resource* rsrc, std::span<const TypeID> types, std::uint64_t version) {
Archetype* Archetype::New(
CmptTraits& rtdCmptTraits,
std::pmr::memory_resource* rsrc,
std::pmr::memory_resource* world_rsrc,
std::span<const TypeID> types,
std::uint64_t version)
{
assert(std::find(types.begin(), types.end(), TypeID_of<Entity>) == types.end());

auto* rst = new Archetype{ rsrc, version };
auto* rst = new Archetype{ rsrc, world_rsrc, version };

rst->cmptTraits.Register(rtdCmptTraits, TypeID_of<Entity>);
for (const auto& type : types)
Expand All @@ -147,7 +159,7 @@ Archetype* Archetype::Add(CmptTraits& rtdCmptTraits, const Archetype* from, std:
assert(std::find(types.begin(), types.end(), TypeID_of<Entity>) == types.end());
assert(std::find_if_not(types.begin(), types.end(), [&](const auto& type) { return from->cmptTraits.GetTypes().contains(type); }) != types.end());

auto* rst = new Archetype{ from->chunkAllocator.resource(), from->version };
auto* rst = new Archetype{ from->chunkAllocator.resource(), from->world_rsrc, from->version };

rst->cmptTraits = from->cmptTraits;
for (const auto& type : types)
Expand All @@ -162,7 +174,7 @@ Archetype* Archetype::Remove(const Archetype* from, std::span<const TypeID> type
assert(std::find(types.begin(), types.end(), TypeID_of<Entity>) == types.end());
assert(std::find_if(types.begin(), types.end(), [&](const auto& type) { return from->cmptTraits.GetTypes().contains(type); }) != types.end());

auto* rst = new Archetype{ from->chunkAllocator.resource(), from->version };
auto* rst = new Archetype{ from->chunkAllocator.resource(), from->world_rsrc, from->version };

rst->cmptTraits = from->cmptTraits;

Expand Down Expand Up @@ -190,7 +202,7 @@ std::size_t Archetype::Create(Entity e) {
}
else {
std::uint8_t* dst = buffer + offset + idxInChunk * trait.size;
trait.DefaultConstruct(dst);
trait.DefaultConstruct(dst, world_rsrc);
}
}
chunk->GetHead()->UpdateVersion(version);
Expand Down Expand Up @@ -261,7 +273,7 @@ std::size_t Archetype::Instantiate(Entity e, std::size_t srcIdx) {
std::uint8_t* dst = dstBuffer + offset + dstIdxInChunk * size;
std::uint8_t* src = srcBuffer + offset + srcIdxInChunk * size;

trait.CopyConstruct(dst, src);
trait.CopyConstruct(dst, src, world_rsrc);
}
}

Expand Down
7 changes: 4 additions & 3 deletions src/core/Archetype.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,16 @@ namespace Ubpa::UECS {
// type of Entity + Components is Archetype's type
class Archetype {
public:
Archetype(std::pmr::memory_resource* rsrc, std::uint64_t version) noexcept : chunkAllocator{ rsrc }, version{ version } {}
Archetype(std::pmr::memory_resource* rsrc, std::pmr::memory_resource* world_rsrc, std::uint64_t version) noexcept;

// copy
Archetype(std::pmr::memory_resource* rsrc, const Archetype&);
Archetype(std::pmr::memory_resource* rsrc, std::pmr::memory_resource* world_rsrc, const Archetype&);
Archetype(const Archetype&) = delete;

~Archetype();

// auto add Entity
static Archetype* New(CmptTraits&, std::pmr::memory_resource* rsrc, std::span<const TypeID> types, std::uint64_t version);
static Archetype* New(CmptTraits&, std::pmr::memory_resource* rsrc, std::pmr::memory_resource* world_rsrc, std::span<const TypeID> types, std::uint64_t version);

static Archetype* Add(CmptTraits&, const Archetype* from, std::span<const TypeID> types);

Expand Down Expand Up @@ -91,6 +91,7 @@ namespace Ubpa::UECS {
ArchetypeCmptTraits cmptTraits; // Entity + Components

std::uint64_t version;
std::pmr::memory_resource* world_rsrc;

// chunk infomations
std::pmr::polymorphic_allocator<Chunk> chunkAllocator;
Expand Down
10 changes: 4 additions & 6 deletions src/core/ArchetypeCmptTraits.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,23 +10,21 @@

using namespace Ubpa::UECS;

void ArchetypeCmptTraits::CmptTrait::DefaultConstruct(void* cmpt) const {
void ArchetypeCmptTraits::CmptTrait::DefaultConstruct(void* cmpt, std::pmr::memory_resource* world_rsrc) const {
if(default_ctor)
default_ctor(cmpt);
default_ctor(cmpt, world_rsrc);
}

void ArchetypeCmptTraits::CmptTrait::CopyConstruct(void* dst, void* src) const {
void ArchetypeCmptTraits::CmptTrait::CopyConstruct(void* dst, const void* src, std::pmr::memory_resource* world_rsrc) const {
if (copy_ctor)
copy_ctor(dst, src);
copy_ctor(dst, src, world_rsrc);
else
std::memcpy(dst, src, size);
}

void ArchetypeCmptTraits::CmptTrait::MoveConstruct(void* dst, void* src) const {
if (move_ctor)
move_ctor(dst, src);
else if (copy_ctor)
copy_ctor(dst, src);
else
std::memcpy(dst, src, size);
}
Expand Down
Loading

0 comments on commit a2d3305

Please sign in to comment.