Skip to content

Commit

Permalink
+ CmptAccessType, CmptAccessPtr
Browse files Browse the repository at this point in the history
  • Loading branch information
Ubpa committed Aug 24, 2020
1 parent 49f80df commit bc53e54
Show file tree
Hide file tree
Showing 37 changed files with 206 additions and 173 deletions.
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
cmake_minimum_required(VERSION 3.14 FATAL_ERROR)

project(UECS VERSION 0.11.7)
project(UECS VERSION 0.12.0)
message(STATUS "[Project] ${PROJECT_NAME}")

include(cmake/InitUCMake.cmake)
Expand Down
6 changes: 3 additions & 3 deletions include/UECS/ArchetypeFilter.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@
#include <set>

namespace Ubpa::UECS {
// filter Archetype with All, Any and None
// filter Archetype with all, any and none
struct ArchetypeFilter {
std::set<CmptType> all;
std::set<CmptType> any;
std::set<CmptAccessType> all;
std::set<CmptAccessType> any;
std::set<CmptType> none;

size_t HashCode() const noexcept;
Expand Down
6 changes: 3 additions & 3 deletions include/UECS/CmptLocator.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ namespace Ubpa::UECS {
// immutable
class CmptLocator {
public:
CmptLocator(const CmptType* types, size_t num);
CmptLocator(const CmptAccessType* types, size_t num);

CmptLocator();

Expand All @@ -23,13 +23,13 @@ namespace Ubpa::UECS {

size_t HashCode() const noexcept { return hashCode; }

const std::set<CmptType>& CmptTypes() const noexcept { return cmptTypes; }
const std::set<CmptAccessType>& CmptAccessTypes() const noexcept { return cmptTypes; }

bool operator==(const CmptLocator& rhs) const;
private:
size_t GenHashCode() const noexcept;

std::set<CmptType> cmptTypes;
std::set<CmptAccessType> cmptTypes;

size_t hashCode;
};
Expand Down
43 changes: 32 additions & 11 deletions include/UECS/CmptPtr.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,25 +8,45 @@ namespace Ubpa::UECS {
// CmptType + void*
class CmptPtr {
public:
CmptPtr(CmptType type, void* p) noexcept : type{ type }, p{ p }{}
constexpr CmptPtr(CmptType type, void* p) noexcept : type{ type }, p{ p }{}
template<typename Cmpt>
CmptPtr(Cmpt* p) noexcept : type{ CmptType::Of<Cmpt> }, p{ p }{}
constexpr CmptPtr(Cmpt* p) noexcept : type{ CmptType::Of<Cmpt> }, p{ p }{}

// unchecked
void* const& Ptr() const noexcept { return p; }
constexpr void* Ptr() const noexcept { return p; }

CmptType Type() const noexcept { return type; }
constexpr CmptType Type() const noexcept { return type; }

bool Valid() const noexcept { return p != nullptr; }
static constexpr CmptPtr Invalid() { return { CmptType::Invalid(), nullptr }; };
constexpr bool Valid() const noexcept { return p != nullptr && type.Valid(); }

// unchecked
template<typename Cmpt>
Cmpt* As() const noexcept { return reinterpret_cast<Cmpt*>(p); }
constexpr Cmpt* As() const noexcept { return reinterpret_cast<Cmpt*>(p); }
private:
CmptType type;
void* p;
};

// CmptAccessType + void*
class CmptAccessPtr {
public:
constexpr CmptAccessPtr(CmptType type, void* p, AccessMode mode) noexcept : accessType{ type, mode }, p{ p } {}
constexpr CmptAccessPtr(CmptAccessType accessType, void* p) noexcept : accessType{ accessType }, p{ p } {}
constexpr CmptAccessPtr(CmptPtr p, AccessMode mode) noexcept : accessType{ p.Type(), mode }, p{ p.Ptr() } {}
template<typename TaggedCmpt>
constexpr CmptAccessPtr(TaggedCmpt p) noexcept : accessType{ CmptAccessType::Of<TaggedCmpt> }, p{ CastToVoidPointer(p) } {}
explicit constexpr CmptAccessPtr(CmptPtr p) noexcept : CmptAccessPtr{ p, AccessMode::LATEST } {}

constexpr void* Ptr() const noexcept { return p; }

constexpr CmptAccessType AccessType() const noexcept { return accessType; }

static constexpr CmptAccessPtr Invalid() { return { CmptAccessType::Invalid(), nullptr }; };
constexpr bool Valid() const noexcept { return p != nullptr && accessType.Valid(); }

// check: type's access mode must be equal to <mode>
template<typename Cmpt, AccessMode mode>
auto As() const noexcept {
assert(type.GetAccessMode() == mode);
constexpr auto As() const noexcept {
assert(accessType.GetAccessMode() == mode);
if constexpr (mode == AccessMode::LAST_FRAME)
return LastFrame<Cmpt>{p};
else if constexpr (mode == AccessMode::WRITE)
Expand All @@ -43,7 +63,8 @@ namespace Ubpa::UECS {
static_assert(false);
}
private:
CmptType type;
friend class EntityMngr;
CmptAccessType accessType;
void* p;
};
}
14 changes: 11 additions & 3 deletions include/UECS/CmptTag.h
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,11 @@ namespace Ubpa::UECS {
const Cmpt* cmpt;
};

template<typename TaggedCmpt>
void* CastToVoidPointer(TaggedCmpt p) {
return const_cast<void*>(reinterpret_cast<const void*>(p));
}

// <Cmpt> (without read/write and singleton tag)
template<typename TaggedCmpt>
struct RemoveTag;
Expand Down Expand Up @@ -190,16 +195,19 @@ namespace Ubpa::UECS {
template<typename T>
static constexpr bool IsTaggedCmpt_v = IsTaggedCmpt<T>::value;

template<typename T>
static constexpr AccessMode AccessModeOf =
template<typename T, AccessMode defaultMode>
static constexpr AccessMode AccessModeOf_default =
IsLastFrame_v<T> ? AccessMode::LAST_FRAME : (
IsWrite_v<T> ? AccessMode::WRITE : (
IsLatest_v<T> ? AccessMode::LATEST : (
IsLastFrameSingleton_v<T> ? AccessMode::LAST_FRAME_SINGLETON : (
IsWriteSingleton_v<T> ? AccessMode::WRITE_SINGLETON : (
IsLatestSingleton_v<T> ? AccessMode::LATEST_SINGLETON :
AccessMode::WRITE // default
defaultMode
)))));

template<typename T>
static constexpr AccessMode AccessModeOf = AccessModeOf_default<T, AccessMode::LATEST>;
}

#include "detail/CmptTag.inl"
60 changes: 48 additions & 12 deletions include/UECS/CmptType.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,36 +2,72 @@

#include "CmptTag.h"

#include "detail/Util.h"

#include <UTemplate/TypeID.h>

namespace Ubpa::UECS {
// Component Type
// use a hashcode to distinguish different type
class CmptType {
public:
explicit constexpr CmptType(size_t id, AccessMode mode = AccessMode::WRITE) noexcept
: hashcode{ id }, mode{ mode } {}
explicit constexpr CmptType(std::string_view type_name, AccessMode mode = AccessMode::WRITE) noexcept
: hashcode{ RuntimeTypeID(type_name) }, mode{ mode } {}
explicit constexpr CmptType(size_t id) noexcept : hashcode{ id } {}
explicit constexpr CmptType(std::string_view type_name) noexcept : hashcode{ RuntimeTypeID(type_name) } {}

template<typename TaggedCmpt> // non-tagged component's access mode is AccessMode::WRITE
static constexpr CmptType Of = CmptType{ TypeID<RemoveTag_t<TaggedCmpt>>, AccessModeOf<TaggedCmpt> };
template<typename Cmpt, std::enable_if_t<!IsTaggedCmpt_v<Cmpt>, int> = 0>
static constexpr CmptType Of = CmptType{ TypeID<Cmpt> };

constexpr size_t HashCode() const noexcept { return hashcode; }

constexpr AccessMode GetAccessMode() const noexcept { return mode; }

static constexpr CmptType Invalid() noexcept { return CmptType{ static_cast<size_t>(-1) }; }
static constexpr CmptType Invalid() noexcept { return CmptType{ size_t_invalid }; }
constexpr bool Valid() const noexcept { return hashcode == size_t_invalid; }

template<typename Cmpt> // non-tagged
template<typename Cmpt, std::enable_if_t<!IsTaggedCmpt_v<Cmpt>, int> = 0>
constexpr bool Is() const noexcept { return hashcode == TypeID<Cmpt>; }

// only compare hash
constexpr bool operator<(const CmptType& rhs) const noexcept { return hashcode < rhs.hashcode; }
constexpr bool operator< (const CmptType& rhs) const noexcept { return hashcode < rhs.hashcode; }
constexpr bool operator<=(const CmptType& rhs) const noexcept { return hashcode <= rhs.hashcode; }
constexpr bool operator> (const CmptType& rhs) const noexcept { return hashcode > rhs.hashcode; }
constexpr bool operator>=(const CmptType& rhs) const noexcept { return hashcode >= rhs.hashcode; }
constexpr bool operator==(const CmptType& rhs) const noexcept { return hashcode == rhs.hashcode; }
constexpr bool operator!=(const CmptType& rhs) const noexcept { return hashcode != rhs.hashcode; }
private:
size_t hashcode;
};

// CmptType with AccessMode
class CmptAccessType {
public:
constexpr CmptAccessType(size_t id, AccessMode mode) noexcept
: type{ id }, mode{ mode } {}
constexpr CmptAccessType(std::string_view type_name, AccessMode mode) noexcept
: type{ RuntimeTypeID(type_name) }, mode{ mode } {}
constexpr CmptAccessType(CmptType type, AccessMode mode) noexcept
: type{ type }, mode{ mode } {}
explicit constexpr CmptAccessType(CmptType type) noexcept : CmptAccessType{ type, AccessMode::LATEST } {}

template<typename Cmpt, AccessMode mode = AccessMode::LATEST>
static constexpr CmptAccessType Of = CmptAccessType{ CmptType::Of<RemoveTag_t<Cmpt>>, AccessModeOf_default<Cmpt, mode> };

// same with CmptType's HashCode
constexpr size_t HashCode() const noexcept { return type.HashCode(); }
constexpr CmptType GetCmptType() const noexcept { return type; }
constexpr AccessMode GetAccessMode() const noexcept { return mode; }

constexpr operator CmptType()const noexcept { return type; }

static constexpr CmptAccessType Invalid() noexcept { return CmptAccessType{ size_t_invalid, AccessMode::LATEST }; }
constexpr bool Valid() const noexcept { return type.Valid(); }

// same with CmptType's operator<
constexpr bool operator< (const CmptAccessType& rhs) const noexcept { return type < rhs.type; }
constexpr bool operator<=(const CmptAccessType& rhs) const noexcept { return type <= rhs.type; }
constexpr bool operator> (const CmptAccessType& rhs) const noexcept { return type > rhs.type; }
constexpr bool operator>=(const CmptAccessType& rhs) const noexcept { return type >= rhs.type; }
constexpr bool operator==(const CmptAccessType& rhs) const noexcept { return type == rhs.type; }
constexpr bool operator!=(const CmptAccessType& rhs) const noexcept { return type != rhs.type; }
private:
CmptType type;
AccessMode mode;
};
}
Expand Down
8 changes: 4 additions & 4 deletions include/UECS/CmptsView.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,15 @@
namespace Ubpa::UECS {
class CmptsView {
public:
CmptsView(const CmptPtr* cmpts, size_t num) noexcept
CmptsView(const CmptAccessPtr* cmpts, size_t num) noexcept
: cmpts{ cmpts }, num{ num } {}

CmptPtr GetCmpt(CmptType) const noexcept;
CmptAccessPtr GetCmpt(CmptAccessType) const noexcept;

const CmptPtr* Components() const noexcept { return cmpts; }
const CmptAccessPtr* Components() const noexcept { return cmpts; }
size_t NumberOfComponents() const noexcept { return num; }
private:
const CmptPtr* cmpts;
const CmptAccessPtr* cmpts;
size_t num;
};
}
1 change: 1 addition & 0 deletions include/UECS/Entity.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ namespace Ubpa::UECS {
return idx < rhs.idx || (idx == rhs.idx && version < rhs.version);
}
static constexpr Entity Invalid() noexcept { return { size_t_invalid,size_t_invalid }; }
constexpr bool IsValid() const noexcept { return idx == size_t_invalid; }
private:
friend class EntityMngr;
friend class Archetype;
Expand Down
9 changes: 4 additions & 5 deletions include/UECS/EntityMngr.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,19 +44,18 @@ namespace Ubpa::UECS {
// use RTDCmptTraits
void Attach(Entity, const CmptType* types, size_t num);

// if not exist cmpt, attach with <Args>...
// else return it directly
// assert(Have(e, CmptType::Of<Cmpt>))
template<typename Cmpt, typename... Args>
Cmpt* Emplace(Entity, Args&&...);

void Detach(Entity, const CmptType* types, size_t num);

bool Have(Entity, CmptType) const;

// nullptr if not singleton
// nullptr if not containts <Cmpt>
template<typename Cmpt>
Cmpt* Get(Entity) const;
// nullptr if not singleton
// nullptr if not containts CmptType
CmptPtr Get(Entity, CmptType) const;

std::vector<CmptPtr> Components(Entity) const;
Expand All @@ -67,7 +66,7 @@ namespace Ubpa::UECS {

size_t EntityNum(const EntityQuery&) const;

std::tuple<bool, std::vector<CmptPtr>> LocateSingletons(const SingletonLocator&) const;
std::tuple<bool, std::vector<CmptAccessPtr>> LocateSingletons(const SingletonLocator&) const;

bool IsSingleton(CmptType) const;
Entity GetSingletonEntity(CmptType) const;
Expand Down
3 changes: 0 additions & 3 deletions include/UECS/EntityQuery.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,6 @@ namespace Ubpa::UECS {
ArchetypeFilter filter;
CmptLocator locator;

template<typename... AllCmpts, typename... AnyCmpts, typename... NoneCmpts, typename... Cmpts>
EntityQuery(TypeList<AllCmpts...>, TypeList<AnyCmpts...>, TypeList<NoneCmpts...>, TypeList<Cmpts...>);

EntityQuery(ArchetypeFilter filter = {}, CmptLocator locator = {})
:filter{ std::move(filter) }, locator{ std::move(locator) } {}

Expand Down
8 changes: 0 additions & 8 deletions include/UECS/Schedule.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,11 +70,7 @@ namespace Ubpa::UECS {

Schedule& LockFilter(std::string_view sys);

Schedule& InsertAll(std::string_view sys, CmptType);
Schedule& InsertAny(std::string_view sys, CmptType);
Schedule& InsertNone(std::string_view sys, CmptType);
Schedule& EraseAll(std::string_view sys, CmptType);
Schedule& EraseAny(std::string_view sys, CmptType);
Schedule& EraseNone(std::string_view sys, CmptType);

private:
Expand All @@ -101,11 +97,7 @@ namespace Ubpa::UECS {
std::unordered_map<size_t, size_t> sysFuncOrder;

struct FilterChange {
std::set<CmptType> insertAlls;
std::set<CmptType> insertAnys;
std::set<CmptType> insertNones;
std::set<CmptType> eraseAlls;
std::set<CmptType> eraseAnys;
std::set<CmptType> eraseNones;
};
std::unordered_map<size_t, FilterChange> sysFilterChange;
Expand Down
6 changes: 3 additions & 3 deletions include/UECS/SingletonLocator.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
namespace Ubpa::UECS {
class SingletonLocator {
public:
SingletonLocator(const CmptType* types, size_t num);
SingletonLocator(const CmptAccessType* types, size_t num);
SingletonLocator() = default;

template<typename Func>
Expand All @@ -18,12 +18,12 @@ namespace Ubpa::UECS {
template<typename Func>
SingletonLocator& Combine();

const std::set<CmptType>& SingletonTypes() const noexcept { return singletonTypes; }
const std::set<CmptAccessType>& SingletonTypes() const noexcept { return singletonTypes; }

bool HasWriteSingletonType() const noexcept;

private:
std::set<CmptType> singletonTypes;
std::set<CmptAccessType> singletonTypes;
};
}

Expand Down
8 changes: 4 additions & 4 deletions include/UECS/SingletonsView.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,15 @@
namespace Ubpa::UECS {
class SingletonsView {
public:
SingletonsView(const CmptPtr* singletons, size_t num)
SingletonsView(const CmptAccessPtr* singletons, size_t num)
: singletons{ singletons }, num{ num } {}

CmptPtr GetSingleton(CmptType) const;
CmptAccessPtr GetSingleton(CmptAccessType) const;

const CmptPtr* Singletons() const noexcept { return singletons; }
const CmptAccessPtr* Singletons() const noexcept { return singletons; }
size_t NumberOfSingletons() const noexcept { return num; }
private:
const CmptPtr* singletons;
const CmptAccessPtr* singletons;
size_t num;
};
}
2 changes: 1 addition & 1 deletion include/UECS/detail/Archetype.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ namespace Ubpa::UECS {
static Archetype* Remove(const Archetype* from, const CmptType* types, size_t num);

// Entity + Components
std::tuple<std::vector<Entity*>, std::vector<std::vector<CmptPtr>>, std::vector<size_t>>
std::tuple<std::vector<Entity*>, std::vector<std::vector<CmptAccessPtr>>, std::vector<size_t>>
Locate(const CmptLocator& locator) const;

// nullptr if not contains
Expand Down
2 changes: 1 addition & 1 deletion include/UECS/detail/Archetype.inl
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ namespace Ubpa::UECS {
static_assert(sizeof...(Cmpts) > 0);
static_assert(IsSet_v<TypeList<Entity, Cmpts...>>,
"<Cmpts>... must be different");
assert(!from->types.Contains(std::array{ CmptType::Of<Cmpts>... }));
assert(!(from->types.Contains(CmptType::Of<Cmpts>) &&...));

Archetype* rst = new Archetype{ from->entityMngr };

Expand Down
Loading

0 comments on commit bc53e54

Please sign in to comment.