Skip to content

Commit

Permalink
chunk job
Browse files Browse the repository at this point in the history
  • Loading branch information
Ubpa committed Jul 31, 2020
1 parent 8a16514 commit 9fb76af
Show file tree
Hide file tree
Showing 25 changed files with 368 additions and 77 deletions.
6 changes: 3 additions & 3 deletions 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.9.8)
project(UECS VERSION 0.10.0)
message(STATUS "[Project] ${PROJECT_NAME}")

include(cmake/InitUCMake.cmake)
Expand All @@ -9,8 +9,8 @@ Ubpa_InitUCMake()
Ubpa_InitProject()

Ubpa_AddDep(UContainer 0.0.6)
Ubpa_AddDep(UTemplate 0.4.6)
Ubpa_AddDep(UGraphviz 0.1.1)
Ubpa_AddDep(UTemplate 0.4.6)
Ubpa_AddDep(UGraphviz 0.1.4)

Ubpa_AddSubDirsRec(include)
Ubpa_AddSubDirsRec(src)
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ int main() {
- [generate **frame graph** in **Graphviz**](src/test/12_framegraph/main.cpp)
- [performance test](src/test/13_performance/main.cpp)
- [serialize](src/test/14_serialize/main.cpp)
- [chunk job](src/test/15_chunk_job/main.cpp)
## Licensing
Expand Down
7 changes: 2 additions & 5 deletions doc/todo.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
- [x] `RTDCmptTraits` : **R**un-**T**ime **D**ynamic **C**omponent **T**raits
- [x] run-time dynamic `SystemFunc`
- [x] C-style API
- [x] chunk job
- [x] serialize (`IListner`)

### unimportant

Expand All @@ -39,11 +41,6 @@
- [ ] shared component
- [ ] system group

### not sure

- [ ] ChunkJob
- [ ] serialize

## tool

- [x] SysFuncGraph dump
Expand Down
29 changes: 29 additions & 0 deletions include/UECS/ChunkView.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#pragma once

#include "CmptType.h"

namespace Ubpa::UECS {
class Archetype;
struct Chunk;

class ChunkView {
public:
ChunkView(Archetype* archetype, size_t chunkIdx, Chunk* chunk)
: archetype{ archetype }, chunkIdx{ chunkIdx }, chunk{ chunk } {}

bool Contains(CmptType) const;
template<typename Cmpt>
bool Contains() const { return Contains(CmptType::Of<Cmpt>); }

// if not contain, return nullptr
void* GetCmptArray(CmptType) const;
template<typename Cmpt>
Cmpt* GetCmptArray() const { return reinterpret_cast<Cmpt*>(GetCmptArray(CmptType::Of<Cmpt>)); }
size_t EntityNum() const;

private:
Archetype* archetype;
size_t chunkIdx;
Chunk* chunk;
};
}
11 changes: 10 additions & 1 deletion include/UECS/CmptTag.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ namespace Ubpa::UECS {

// LastFrame -> Write -> Latest

enum class Mode {
enum class AccessMode {
LAST_FRAME,
WRITE,
LATEST
Expand Down Expand Up @@ -62,6 +62,15 @@ namespace Ubpa::UECS {
struct IsTaggedCmpt : IValue<bool, IsLastFrame_v<T> || IsWrite_v<T> || IsLatest_v<T>> {};
template<typename T>
static constexpr bool IsTaggedCmpt_v = IsTaggedCmpt<T>::value;

template<typename T>
static constexpr AccessMode AccessModeOf =
IsLastFrame_v<T> ? AccessMode::LAST_FRAME : (
IsWrite_v<T> ? AccessMode::WRITE : (
IsLatest_v<T> ? AccessMode::LAST_FRAME
: AccessMode::WRITE // default
)
);
}

#include "detail/CmptTag.inl"
17 changes: 12 additions & 5 deletions include/UECS/CmptType.h
Original file line number Diff line number Diff line change
@@ -1,30 +1,37 @@
#pragma once

#include "CmptTag.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) : hashcode{ id } {}
explicit constexpr CmptType(std::string_view type_name) : hashcode{ RuntimeTypeID(type_name) } {}
explicit constexpr CmptType(size_t id, AccessMode mode = AccessMode::WRITE)
: hashcode{ id }, mode{ mode } {}
explicit constexpr CmptType(std::string_view type_name, AccessMode mode = AccessMode::WRITE)
: hashcode{ RuntimeTypeID(type_name) }, mode{ mode } {}

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

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) }; }

template<typename Cmpt>
template<typename Cmpt> // non-tagged
constexpr bool Is() const noexcept { return hashcode == TypeID<Cmpt>; }

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;
AccessMode mode;
};
}

Expand Down
9 changes: 6 additions & 3 deletions include/UECS/EntityLocator.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

namespace Ubpa::UECS {
// locate components in function's argument list for Archetype
// TODO: combine with a system function's locator
class EntityLocator {
public:
template<typename TaggedCmptList>
Expand All @@ -16,9 +17,11 @@ namespace Ubpa::UECS {
template<typename... LastFrameCmpts, typename... WriteCmpts, typename... LatestCmpts>
EntityLocator(TypeList<LastFrameCmpts...>, TypeList<WriteCmpts...>, TypeList<LatestCmpts...>);

EntityLocator(std::set<CmptType> lastFrameCmpts = {},
EntityLocator(
std::set<CmptType> lastFrameCmpts = {},
std::set<CmptType> writeFrameCmpts = {},
std::set<CmptType> latestCmpts = {});
std::set<CmptType> latestCmpts = {}
);

size_t HashCode() const noexcept { return hashCode; }

Expand All @@ -27,7 +30,7 @@ namespace Ubpa::UECS {
const std::set<CmptType>& LatestCmptTypes() const noexcept { return latestCmptTypes; }
const std::set<CmptType>& CmptTypes() const noexcept { return cmptTypes; }

Mode GetCmptTagMode(CmptType type) const;
AccessMode GetCmptTagMode(CmptType type) const;

bool operator==(const EntityLocator& locator) const noexcept;
private:
Expand Down
3 changes: 2 additions & 1 deletion include/UECS/EntityMngr.h
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,8 @@ namespace Ubpa::UECS {
typename = std::enable_if_t<(std::is_same_v<CmptTypes, CmptType>&&...)>>
void AttachWithoutInit(Entity, CmptTypes...);

void GenJob(Job* job, SystemFunc* sys) const;
void GenEntityJob(Job* job, SystemFunc* sys) const;
void GenChunkJob(Job* job, SystemFunc* sys) const;

struct EntityInfo {
Archetype* archetype{ nullptr };
Expand Down
14 changes: 7 additions & 7 deletions include/UECS/RTDCmptsView.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,28 +17,28 @@ namespace Ubpa::UECS {
// for read/write control
class CmptHandle {
public:
CmptHandle(CmptType type, void* cmpt, Mode mode)
CmptHandle(CmptType type, void* cmpt, AccessMode mode)
: type{ type }, cmpt{ cmpt }, mode{ mode }{}

CmptType GetCmptType() const noexcept { return type; }
Mode GetMode() const noexcept { return mode; }
AccessMode GetMode() const noexcept { return mode; }

CmptCPtr AsLastFrame() const noexcept {
assert(mode == Mode::LAST_FRAME);
assert(mode == AccessMode::LAST_FRAME);
return { type, cmpt };
}
CmptPtr AsWrite() const noexcept {
assert(mode == Mode::WRITE);
assert(mode == AccessMode::WRITE);
return { type, cmpt };
}
CmptCPtr AsLatest() const noexcept {
assert(mode == Mode::LATEST);
assert(mode == AccessMode::LATEST);
return { type, cmpt };
}
private:
CmptType type;
void* cmpt;
Mode mode;
AccessMode mode;
};

// forward
Expand Down Expand Up @@ -69,7 +69,7 @@ namespace Ubpa::UECS {
EntityLocator* locator;
std::set<CmptType>::iterator typeIter;
void* const* ptr_cmpt;
mutable CmptHandle handle{ CmptType::Invalid(), nullptr, Mode{} };
mutable CmptHandle handle{ CmptType::Invalid(), nullptr, AccessMode{} };
};

RTDCmptsView(EntityLocator* locator, void** cmpts)
Expand Down
2 changes: 1 addition & 1 deletion include/UECS/Schedule.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ namespace Ubpa::UECS {
std::vector<SystemFunc*> latestSysFuncs;
};
friend struct detail::Schedule_::Compiler;
std::unordered_map<CmptType, CmptSysFuncs> cmptSysFuncsMap;
std::unordered_map<CmptType, CmptSysFuncs> GenCmptSysFuncsMap() const;

SysFuncGraph GenSysFuncGraph() const;

Expand Down
50 changes: 41 additions & 9 deletions include/UECS/SystemFunc.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include "EntityQuery.h"
#include "Entity.h"
#include "RTDCmptsView.h"
#include "ChunkView.h"

#include <functional>

Expand All @@ -13,12 +14,18 @@ namespace Ubpa::UECS {
// name must be unique in global
// query.filter can be change dynamically by other <System> with Schedule
// [system function kind] (distinguish by argument list)
// 1. per entity function: [[const] Entity e, ] [size_t indexInQuery, ] <Tagged_Component>...
// - - tagged component: {LastFrame|Write|Latest}<Component>
// 2. job: empty argument list
// 3. runtime dynamic function: RTDCmptsView
// 1. per entity function: [[const] Entity e] [size_t indexInQuery] [RTDCmptsView] <tagged-component>...
// * <tagged-component>: {LastFrame|Write|Latest}<Component>
// 2. chunk: ChunkView
// 3. job: empty argument list
class SystemFunc {
public:
enum class Mode {
Entity,
Chunk,
Job,
};

EntityQuery query;

template<typename Func>
Expand All @@ -35,21 +42,46 @@ namespace Ubpa::UECS {
size_t HashCode() const noexcept { return hashCode; }

void operator()(Entity e, size_t entityIndexInQuery, RTDCmptsView rtdcmpts) {
return func(e, entityIndexInQuery, rtdcmpts);
assert(mode == Mode::Entity);
return func(
e,
entityIndexInQuery,
rtdcmpts,
ChunkView{nullptr, size_t_invalid, nullptr}
);
}

void operator()(ChunkView chunkView) {
assert(mode == Mode::Chunk);
return func(
Entity::Invalid(),
size_t_invalid,
RTDCmptsView{nullptr, nullptr},
chunkView
);
}

void operator()() {
assert(mode == Mode::Job);
return func(
Entity::Invalid(),
size_t_invalid,
RTDCmptsView{ nullptr, nullptr },
ChunkView{nullptr, size_t_invalid, nullptr}
);
}

// no arguments <Func>
bool IsJob() const noexcept { return isJob; }
Mode GetMode() const noexcept { return mode; }

bool operator==(const SystemFunc& func) const noexcept { return name == func.name; }
private:
template<typename Func, typename ArgList>
SystemFunc(Func&& func, std::string name, EntityFilter filter, ArgList);

std::function<void(Entity, size_t, RTDCmptsView)> func;
std::function<void(Entity, size_t, RTDCmptsView, ChunkView)> func;

std::string name;
bool isJob;
Mode mode;
size_t hashCode; // after name
};
}
Expand Down
2 changes: 1 addition & 1 deletion include/UECS/World.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ namespace Ubpa::UECS {

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

void Accept(IListener* listener) const;

Expand Down
5 changes: 5 additions & 0 deletions include/UECS/detail/Archetype.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,10 @@ namespace Ubpa::UECS {
// Entity + Components
std::tuple<std::vector<Entity*>, std::vector<std::vector<void*>>, std::vector<size_t>>
Locate(const std::set<CmptType>& cmptTypes) const;

void* Locate(size_t chunkIdx, CmptType) const;

Chunk* GetChunk(size_t chunkIdx) const { return chunks[chunkIdx]; }

void* At(CmptType type, size_t idx) const;

Expand Down Expand Up @@ -88,6 +92,7 @@ namespace Ubpa::UECS {
size_t CmptNum() const noexcept { return types.size() - 1; }

size_t EntityNum() const noexcept { return entityNum; }
size_t EntityNumOfChunk(size_t chunkIdx) const noexcept;
size_t ChunkNum() const noexcept { return chunks.size(); }
size_t ChunkCapacity() const noexcept { return chunkCapacity; }

Expand Down
5 changes: 5 additions & 0 deletions include/UECS/detail/ChunkView.inl
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#pragma once

namespace Ubpa::UECS {

}
2 changes: 1 addition & 1 deletion include/UECS/detail/CmptTag.inl
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@ namespace Ubpa::UECS {
}

namespace Ubpa::UECS {
template<typename Cmpt> struct RemoveTag : IType<Cmpt> {}; // default
template<typename Cmpt> struct RemoveTag<const Cmpt*> : IType<Cmpt> {};
template<typename Cmpt> struct RemoveTag<Cmpt*> : IType<Cmpt> {};
template<typename Cmpt> struct RemoveTag<LastFrame<Cmpt>> : IType<Cmpt> {};
template<> struct RemoveTag<void**> : IType<void**> {};

template<typename T> struct DecayTag : IType<T> {};
// template<typename Cmpt> struct DecayTag<Cmpt*> : IType<Cmpt*> {};
Expand Down
7 changes: 0 additions & 7 deletions include/UECS/detail/Schedule.inl
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,6 @@ namespace Ubpa::UECS {
void Schedule::Request(Args&&... args) {
SystemFunc* sysFunc = sysFuncPool.Request(std::forward<Args>(args)...);
sysFuncs.emplace(sysFunc->HashCode(), sysFunc);
const auto& locator = sysFunc->query.locator;
for (const auto& type : locator.LastFrameCmptTypes())
cmptSysFuncsMap[type].lastFrameSysFuncs.push_back(sysFunc);
for (const auto& type : locator.WriteCmptTypes())
cmptSysFuncsMap[type].writeSysFuncs.push_back(sysFunc);
for (const auto& type : locator.LatestCmptTypes())
cmptSysFuncsMap[type].latestSysFuncs.push_back(sysFunc);
}

inline Schedule::Schedule(EntityMngr* entityMngr, SystemMngr* systemMngr)
Expand Down
Loading

0 comments on commit 9fb76af

Please sign in to comment.