Skip to content

Commit

Permalink
RTDCmptTraits -> CmptTraits
Browse files Browse the repository at this point in the history
  • Loading branch information
Ubpa committed Mar 22, 2021
1 parent 0b622cd commit 1636998
Show file tree
Hide file tree
Showing 12 changed files with 110 additions and 89 deletions.
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
## Example

```c++
#include <UECS/UECS.h>
#include <UECS/UECS.hpp>

using namespace Ubpa::UECS;

Expand All @@ -62,8 +62,9 @@ struct MoverSystem {

int main() {
World w;
w.entityMngr.cmptTraits.Register<Position, Velocity>();
w.systemMngr.RegisterAndActivate<MoverSystem>();
w.entityMngr.Create<Position, Velocity>();
w.entityMngr.Create(Ubpa::TypeIDs_of<Position, Velocity>);
w.Update();
}
```
Expand All @@ -87,6 +88,7 @@ int main() {
- [directly run execution](src/test/19_direct_run/main.cpp)
- [system lifecycle](src/test/20_system_lifecycle/main.cpp)
- [random access components](src/test/21_random/main.cpp)
- [change filter](src/test/22_change_filter/main.cpp)
## Licensing
Expand Down
44 changes: 25 additions & 19 deletions include/UECS/RTDCmptTraits.hpp → include/UECS/CmptTraits.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,27 +19,27 @@ namespace Ubpa::UECS {
// - move assignment: memcpy as default
// - destructor: do nothing as default
// - name
class RTDCmptTraits {
class CmptTraits {
public:
static constexpr std::size_t default_alignment = alignof(std::max_align_t);

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

RTDCmptTraits& Clear();
CmptTraits& Clear();

RTDCmptTraits& RegisterName(Type);
RTDCmptTraits& RegisterTrivial(TypeID);
RTDCmptTraits& RegisterSize(TypeID, std::size_t size);
RTDCmptTraits& RegisterAlignment(TypeID, std::size_t alignment);
RTDCmptTraits& RegisterDefaultConstructor(TypeID, std::function<void(void*)>);
RTDCmptTraits& RegisterCopyConstructor(TypeID, std::function<void(void*,void*)>);
RTDCmptTraits& RegisterMoveConstructor(TypeID, std::function<void(void*,void*)>);
RTDCmptTraits& RegisterMoveAssignment(TypeID, std::function<void(void*,void*)>);
RTDCmptTraits& RegisterDestructor(TypeID, std::function<void(void*)>);
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& RegisterMoveConstructor(TypeID, std::function<void(void*,void*)>);
CmptTraits& RegisterMoveAssignment(TypeID, std::function<void(void*,void*)>);
CmptTraits& RegisterDestructor(TypeID, std::function<void(void*)>);

const auto& GetSizeofs() const noexcept { return sizeofs; }
const auto& GetAlignments() const noexcept { return alignments; };
Expand All @@ -60,11 +60,14 @@ namespace Ubpa::UECS {
void Destruct(TypeID, void* cmpt) const;
std::string_view Nameof(TypeID) const;

RTDCmptTraits& Deregister(TypeID) noexcept;
CmptTraits& Deregister(TypeID) noexcept;

template<typename... Cmpts>
void Register();

template<typename... Cmpts>
void UnsafeRegister();

template<typename Cmpt>
void Deregister();

Expand All @@ -78,7 +81,10 @@ namespace Ubpa::UECS {
// - is_destructible_v
template<typename Cmpt>
void RegisterOne();


template<typename Cmpt>
void UnsafeRegisterOne();

std::unique_ptr<std::pmr::unsynchronized_pool_resource> rsrc;
std::unordered_set<TypeID> trivials;
std::unordered_map<TypeID, std::string_view> names;
Expand All @@ -92,4 +98,4 @@ namespace Ubpa::UECS {
};
}

#include "details/RTDCmptTraits.inl"
#include "details/CmptTraits.inl"
8 changes: 4 additions & 4 deletions include/UECS/EntityMngr.hpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#pragma once

#include "RTDCmptTraits.hpp"
#include "CmptTraits.hpp"
#include "EntityQuery.hpp"
#include "SingletonLocator.hpp"
#include "CmptPtr.hpp"
Expand All @@ -24,7 +24,7 @@ namespace Ubpa::UECS {
// - Singleton: IsSingleton, GetSingletonEntity, GetSingleton
// - other: EntityNum, AddCommand
// [important]
// - some API with TypeID need RTDCmptTraits to get {size|alignment|lifecycle function} (throw std::logic_error)
// - some API with TypeID need CmptTraits to get {size|alignment|lifecycle function} (throw std::logic_error)
// - API with Entity require Entity exist (throw std::invalid_argument)
// [details]
// - when free entries is empty, use new entity entry (version is 0)
Expand All @@ -35,7 +35,7 @@ namespace Ubpa::UECS {
EntityMngr(EntityMngr&&) noexcept;
~EntityMngr();

RTDCmptTraits cmptTraits;
CmptTraits cmptTraits;

Entity Create(std::span<const TypeID> types = {});

Expand Down Expand Up @@ -95,7 +95,7 @@ namespace Ubpa::UECS {
// types not contain Entity
Archetype* GetOrCreateArchetypeOf(std::span<const TypeID> types);

small_vector<CmptAccessPtr, 16> LocateSingletons(const SingletonLocator&) const;
small_vector<CmptAccessPtr> LocateSingletons(const SingletonLocator&) const;

const std::set<Archetype*>& QueryArchetypes(const EntityQuery&) const;
mutable std::unordered_map<EntityQuery, std::set<Archetype*>> queryCache;
Expand Down
2 changes: 1 addition & 1 deletion include/UECS/UECS.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@
#include "CmptPtr.hpp"
#include "CmptsView.hpp"
#include "CmptTag.hpp"
#include "CmptTraits.hpp"
#include "config.hpp"
#include "Entity.hpp"
#include "EntityMngr.hpp"
#include "EntityQuery.hpp"
#include "IListener.hpp"
#include "RandomAccessor.hpp"
#include "RTDCmptTraits.hpp"
#include "Schedule.hpp"
#include "SingletonLocator.hpp"
#include "SingletonsView.hpp"
Expand Down
2 changes: 1 addition & 1 deletion include/UECS/World.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ namespace Ubpa::UECS {
std::string DumpUpdateJobGraph() const;

// after running Update()
// use RTDCmptTraits' registered component name
// use CmptTraits' registered component name
UGraphviz::Graph GenUpdateFrameGraph() const;

void Accept(IListener*) const;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,23 +1,19 @@
#pragma once

#include "../RTDCmptTraits.hpp"
#include "../CmptTraits.hpp"

namespace Ubpa::UECS {
template<typename... Cmpts>
void RTDCmptTraits::Register() {
void CmptTraits::Register() {
(RegisterOne<Cmpts>(), ...);
}
template<typename... Cmpts>
void CmptTraits::UnsafeRegister() {
(UnsafeRegisterOne<Cmpts>(), ...);
}

template<typename Cmpt>
void RTDCmptTraits::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> || std::is_constructible_v<Cmpt, Cmpt&>,
"<Cmpt> must be copy-constructible or constructible with <Cmpt&>");
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");

void CmptTraits::UnsafeRegisterOne() {
constexpr Type type = Type_of<Cmpt>;

if constexpr (std::is_trivial_v<Cmpt>)
Expand All @@ -27,33 +23,50 @@ namespace Ubpa::UECS {
alignments.emplace(type.GetID(), alignof(Cmpt));
names.emplace(type.GetID(), type.GetName());

default_constructors.emplace(type.GetID(), [](void* cmpt) {
new(cmpt)Cmpt{};
});
if constexpr (!std::is_trivially_destructible_v<Cmpt>) {
if constexpr (std::is_default_constructible_v<Cmpt>) {
default_constructors.emplace(type.GetID(), [](void* cmpt) {
new(cmpt)Cmpt{};
});
}

if constexpr (std::is_destructible_v<Cmpt> && !std::is_trivially_destructible_v<Cmpt>) {
destructors.emplace(type.GetID(), [](void* cmpt) {
static_cast<Cmpt*>(cmpt)->~Cmpt();
});
}
if constexpr (!std::is_trivially_move_constructible_v<Cmpt>) {

if constexpr (std::is_move_constructible_v<Cmpt> && !std::is_trivially_move_constructible_v<Cmpt>) {
move_constructors.emplace(type.GetID(), [](void* dst, void* src) {
new(dst)Cmpt(std::move(*static_cast<Cmpt*>(src)));
});
}
if constexpr (!std::is_trivially_move_assignable_v<Cmpt>) {

if constexpr (std::is_move_assignable_v<Cmpt> && !std::is_trivially_move_assignable_v<Cmpt>) {
move_assignments.emplace(type.GetID(), [](void* dst, void* src) {
*static_cast<Cmpt*>(dst) = std::move(*static_cast<Cmpt*>(src));
});
}
if constexpr (!std::is_trivially_copy_constructible_v<Cmpt>) {
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));
});
}
}

template<typename Cmpt>
void RTDCmptTraits::Deregister() {
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_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");

UnsafeRegisterOne<Cmpt>();
}

template<typename Cmpt>
void CmptTraits::Deregister() {
constexpr TypeID type = TypeID_of<Cmpt>;

sizeofs.erase(type);
Expand Down
16 changes: 8 additions & 8 deletions src/core/Archetype.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ void Archetype::SetLayout() {
}
}

Archetype* Archetype::New(RTDCmptTraits& 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::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 };
Expand All @@ -143,7 +143,7 @@ Archetype* Archetype::New(RTDCmptTraits& rtdCmptTraits, std::pmr::memory_resourc
return rst;
}

Archetype* Archetype::Add(RTDCmptTraits& rtdCmptTraits, const Archetype* from, std::span<const TypeID> types) {
Archetype* Archetype::Add(CmptTraits& rtdCmptTraits, const Archetype* from, std::span<const TypeID> types) {
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());

Expand Down Expand Up @@ -271,9 +271,9 @@ std::size_t Archetype::Instantiate(Entity e, std::size_t srcIdx) {
}

std::tuple<
Ubpa::small_vector<Entity*, 16>,
Ubpa::small_vector<Ubpa::small_vector<CmptAccessPtr, 16>, 16>,
Ubpa::small_vector<std::size_t, 16>
Ubpa::small_vector<Entity*>,
Ubpa::small_vector<Ubpa::small_vector<CmptAccessPtr>>,
Ubpa::small_vector<std::size_t>
>
Archetype::Locate(std::span<const AccessTypeID> cmpts) const {
assert(std::find_if_not(cmpts.begin(), cmpts.end(), [this](const TypeID& type) { return cmptTraits.GetTypes().contains(type); }) == cmpts.end());
Expand All @@ -283,8 +283,8 @@ Archetype::Locate(std::span<const AccessTypeID> cmpts) const {
const std::size_t entityIdx = static_cast<std::size_t>(std::distance(cmptTraits.GetTypes().begin(), cmptTraits.GetTypes().find(TypeID_of<Entity>)));
const std::size_t offsetEntity = offsets[entityIdx];

Ubpa::small_vector<Ubpa::small_vector<CmptAccessPtr, 16>, 16> chunkCmpts(numChunk);
Ubpa::small_vector<Entity*, 16> chunkEntity(numChunk);
Ubpa::small_vector<Ubpa::small_vector<CmptAccessPtr>> chunkCmpts(numChunk);
Ubpa::small_vector<Entity*> chunkEntity(numChunk);

for (std::size_t i = 0; i < numChunk; i++) {
Chunk* chunk = chunks[i];
Expand All @@ -300,7 +300,7 @@ Archetype::Locate(std::span<const AccessTypeID> cmpts) const {
chunkEntity[i] = reinterpret_cast<Entity*>(data + offsetEntity);
}

Ubpa::small_vector<std::size_t, 16> sizes;
Ubpa::small_vector<std::size_t> sizes;
sizes.reserve(numType);
for (const auto& type : cmpts)
sizes.push_back(cmptTraits.GetTrait(type).size);
Expand Down
10 changes: 5 additions & 5 deletions src/core/Archetype.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,18 +25,18 @@ namespace Ubpa::UECS {
~Archetype();

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

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

// auto add Entity
static Archetype* Remove(const Archetype* from, std::span<const TypeID> types);

// Entity + Components
std::tuple<
small_vector<Entity*, 16>,
small_vector<small_vector<CmptAccessPtr, 16>, 16>,
small_vector<std::size_t, 16>
small_vector<Entity*>,
small_vector<small_vector<CmptAccessPtr>>,
small_vector<std::size_t>
>
Locate(std::span<const AccessTypeID> cmpts) const;

Expand Down
4 changes: 2 additions & 2 deletions src/core/ArchetypeCmptTraits.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

#include "ArchetypeCmptTraits.hpp"

#include <UECS/RTDCmptTraits.hpp>
#include <UECS/CmptTraits.hpp>

#include <UECS/EntityQuery.hpp>

Expand Down Expand Up @@ -51,7 +51,7 @@ ArchetypeCmptTraits::CmptTrait& ArchetypeCmptTraits::GetTrait(TypeID ID) noexcep
return cmpt_traits[GetTypeIndex(ID)];
}

void ArchetypeCmptTraits::Register(const RTDCmptTraits& rtdct, TypeID type) {
void ArchetypeCmptTraits::Register(const CmptTraits& rtdct, TypeID type) {
auto size_target = rtdct.GetSizeofs().find(type);
if (size_target == rtdct.GetSizeofs().end())
throw std::logic_error("ArchetypeCmptTraits::Register: RTDCmptTrait hasn't registered <TypeID>");
Expand Down
4 changes: 2 additions & 2 deletions src/core/ArchetypeCmptTraits.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
#include <span>

namespace Ubpa::UECS {
class RTDCmptTraits;
class CmptTraits;
struct EntityQuery;

// run-time static component traits
Expand Down Expand Up @@ -44,7 +44,7 @@ namespace Ubpa::UECS {
const CmptTrait& GetTrait(TypeID ID) const noexcept
{ return const_cast<ArchetypeCmptTraits*>(this)->GetTrait(ID); }

void Register(const RTDCmptTraits&, TypeID);
void Register(const CmptTraits&, TypeID);

void Deregister(TypeID) noexcept;

Expand Down
Loading

0 comments on commit 1636998

Please sign in to comment.