From 83932d8e0bf44d892d90c59b20eeaa0a3316f49a Mon Sep 17 00:00:00 2001 From: Ubpa <641614112@qq.com> Date: Fri, 28 Aug 2020 16:04:53 +0800 Subject: [PATCH] non-parallel, world run system func directly --- doc/todo.md | 2 ++ include/UECS/EntityMngr.h | 1 + include/UECS/Schedule.h | 8 ++--- include/UECS/World.h | 44 +++++++++++++++++++++++++ include/UECS/detail/Schedule.inl | 8 ++--- include/UECS/detail/World.inl | 52 ++++++++++++++++++++++++++++++ src/core/EntityMngr.cpp | 18 +++++++++++ src/core/World.cpp | 22 +++++-------- src/test/04_filter/main.cpp | 1 + src/test/06_none_parallel/main.cpp | 4 +-- src/test/11_runtime_cmpt/main.cpp | 4 +-- src/test/12_framegraph/main.cpp | 1 + src/test/17_serial/main.cpp | 11 +++++-- 13 files changed, 148 insertions(+), 28 deletions(-) create mode 100644 include/UECS/detail/World.inl diff --git a/doc/todo.md b/doc/todo.md index b90cde9..87d0869 100644 --- a/doc/todo.md +++ b/doc/todo.md @@ -35,6 +35,8 @@ - [x] exception: invalid `Entity` - [x] lock `FilterChange` - [ ] `EntityMngr` `Query`-driven API +- [x] non-parallel job +- [x] world run system func directly - [x] `CmptsView` = `const EntityLocator* locator + void** cmpts` - [ ] pmr - [ ] batch create/instantiate (need benchmark) diff --git a/include/UECS/EntityMngr.h b/include/UECS/EntityMngr.h index 6b090a9..f4f99c4 100644 --- a/include/UECS/EntityMngr.h +++ b/include/UECS/EntityMngr.h @@ -115,6 +115,7 @@ namespace Ubpa::UECS { void GenEntityJob(World*, Job*, SystemFunc*) const; void GenChunkJob(World*, Job*, SystemFunc*) const; void GenJob(World*, Job*, SystemFunc*) const; + void AutoGen(World*, Job*, SystemFunc*) const; struct EntityInfo { Archetype* archetype{ nullptr }; diff --git a/include/UECS/Schedule.h b/include/UECS/Schedule.h index 431e3a5..5af2fab 100644 --- a/include/UECS/Schedule.h +++ b/include/UECS/Schedule.h @@ -37,10 +37,10 @@ namespace Ubpa::UECS { const SystemFunc* RegisterEntityJob( Func&&, std::string name, + bool isParallel = true, ArchetypeFilter = {}, CmptLocator = {}, - SingletonLocator = {}, - bool isParallel = true + SingletonLocator = {} ); // Func's argument list: @@ -53,8 +53,8 @@ namespace Ubpa::UECS { Func&&, std::string name, ArchetypeFilter = {}, - SingletonLocator = {}, - bool isParallel = true + bool isParallel = true, + SingletonLocator = {} ); // Func's argument list: diff --git a/include/UECS/World.h b/include/UECS/World.h index d56a6bb..e6b5fce 100644 --- a/include/UECS/World.h +++ b/include/UECS/World.h @@ -37,6 +37,46 @@ namespace Ubpa::UECS { void AddCommand(std::function command); + // Func's argument list: + // World* + // {LastFrame|Latest}> + // SingletonsView + // Entity + // size_t indexInQuery + // : [const] *... + // CmptsView + template + void RunEntityJob( + Func&&, + bool isParallel = true, + ArchetypeFilter = {}, + CmptLocator = {}, + SingletonLocator = {} + ); + + // Func's argument list: + // World* + // {LastFrame|Latest}> + // SingletonsView + // ChunkView (necessary) + template + void RunChunkJob( + Func&&, + ArchetypeFilter = {}, + bool isParallel = true, + SingletonLocator = {} + ); + + // Func's argument list: + // World* + // {LastFrame|Write|Latest}> + // SingletonsView + template + void RunJob( + Func&&, + SingletonLocator = {} + ); + private: mutable JobExecutor executor; Schedule schedule; @@ -50,6 +90,8 @@ namespace Ubpa::UECS { std::mutex commandBufferMutex; void RunCommands(); + void Run(SystemFunc*); + // ================================================== World(const World& world) = delete; World(World&& world) = delete; @@ -57,3 +99,5 @@ namespace Ubpa::UECS { World& operator=(const World& world) = delete; }; } + +#include "detail/World.inl" diff --git a/include/UECS/detail/Schedule.inl b/include/UECS/detail/Schedule.inl index 6c51435..dd7225e 100644 --- a/include/UECS/detail/Schedule.inl +++ b/include/UECS/detail/Schedule.inl @@ -5,10 +5,10 @@ namespace Ubpa::UECS { const SystemFunc* Schedule::RegisterEntityJob( Func&& func, std::string name, + bool isParallel, ArchetypeFilter filter, CmptLocator cmptLocator, - SingletonLocator singletonLocator, - bool isParallel + SingletonLocator singletonLocator ) { return Request( std::forward(func), @@ -26,8 +26,8 @@ namespace Ubpa::UECS { Func&& func, std::string name, ArchetypeFilter filter, - SingletonLocator singletonLocator, - bool isParallel + bool isParallel, + SingletonLocator singletonLocator ) { return Request( std::forward(func), diff --git a/include/UECS/detail/World.inl b/include/UECS/detail/World.inl new file mode 100644 index 0000000..28f4836 --- /dev/null +++ b/include/UECS/detail/World.inl @@ -0,0 +1,52 @@ +#pragma once + +namespace Ubpa::UECS { + template + void World::RunEntityJob( + Func&& func, + bool isParallel, + ArchetypeFilter filter, + CmptLocator cmptLocator, + SingletonLocator singletonLocator + ) { + SystemFunc sys{ + std::forward(func), + "", + std::move(filter), + std::move(cmptLocator), + std::move(singletonLocator), + std::move(isParallel) + }; + Run(&sys); + } + + template + void World::RunChunkJob( + Func&& func, + ArchetypeFilter filter, + bool isParallel, + SingletonLocator singletonLocator + ) { + SystemFunc sys{ + std::forward(func), + "", + std::move(filter), + std::move(singletonLocator), + std::move(isParallel) + }; + Run(&sys); + } + + template + void World::RunJob( + Func&& func, + SingletonLocator singletonLocator + ) { + SystemFunc sys{ + std::forward(func), + "", + std::move(singletonLocator) + }; + Run(&sys); + } +} diff --git a/src/core/EntityMngr.cpp b/src/core/EntityMngr.cpp index bc93b6d..afb340e 100644 --- a/src/core/EntityMngr.cpp +++ b/src/core/EntityMngr.cpp @@ -390,6 +390,24 @@ void EntityMngr::GenJob(World* w, Job* job, SystemFunc* sys) const { }); } +void EntityMngr::AutoGen(World* w, Job* job, SystemFunc* sys) const { + switch (sys->GetMode()) + { + case SystemFunc::Mode::Entity: + GenEntityJob(w, job, sys); + break; + case SystemFunc::Mode::Chunk: + GenChunkJob(w, job, sys); + break; + case SystemFunc::Mode::Job: + GenJob(w, job, sys); + break; + default: + assert("not support" && false); + break; + } +} + void EntityMngr::Accept(IListener* listener) const { listener->EnterEntityMngr(this); for (const auto& [ts, a] : ts2a) { diff --git a/src/core/World.cpp b/src/core/World.cpp index 360da62..621ba94 100644 --- a/src/core/World.cpp +++ b/src/core/World.cpp @@ -25,20 +25,7 @@ void World::Update() { for (const auto& [func, adjVs] : graph.GetAdjList()) { auto job = jobPool.Request(func->Name()); jobs.push_back(job); - switch (func->GetMode()) - { - case Ubpa::UECS::SystemFunc::Mode::Entity: - entityMngr.GenEntityJob(this, job, func); - break; - case Ubpa::UECS::SystemFunc::Mode::Chunk: - entityMngr.GenChunkJob(this, job, func); - break; - case Ubpa::UECS::SystemFunc::Mode::Job: - entityMngr.GenJob(this, job, func); - break; - default: - break; - } + entityMngr.AutoGen(this, job, func); table[func] = jobGraph.composed_of(*job); } @@ -57,6 +44,13 @@ string World::DumpUpdateJobGraph() const { return jobGraph.dump(); } +void World::Run(SystemFunc* sys) { + Job job; + JobExecutor executor; + entityMngr.AutoGen(this, &job, sys); + executor.run(job).wait(); +} + // after running Update UGraphviz::Graph World::GenUpdateFrameGraph() const { UGraphviz::Graph graph("Update Frame Graph", true); diff --git a/src/test/04_filter/main.cpp b/src/test/04_filter/main.cpp index a4f6d8d..e0a3230 100644 --- a/src/test/04_filter/main.cpp +++ b/src/test/04_filter/main.cpp @@ -27,6 +27,7 @@ class MySystem : public System { cout << e->val << endl; }, "test filter", + true, filter ); } diff --git a/src/test/06_none_parallel/main.cpp b/src/test/06_none_parallel/main.cpp index f88192c..40cd637 100644 --- a/src/test/06_none_parallel/main.cpp +++ b/src/test/06_none_parallel/main.cpp @@ -17,8 +17,8 @@ class MySystem : public System { ArchetypeFilter filter_w0, filter_w1; filter_w0.none = { CmptType::Of }; filter_w1.all = { CmptAccessType::Of }; - schedule.RegisterEntityJob([](B*) {}, "need B, none A", filter_w0); - schedule.RegisterEntityJob([](B*) {}, "need A, B", filter_w1);; + schedule.RegisterEntityJob([](B*) {}, "need B, none A", true, filter_w0); + schedule.RegisterEntityJob([](B*) {}, "need A, B", true, filter_w1);; } }; diff --git a/src/test/11_runtime_cmpt/main.cpp b/src/test/11_runtime_cmpt/main.cpp index d935d9a..51e4b95 100644 --- a/src/test/11_runtime_cmpt/main.cpp +++ b/src/test/11_runtime_cmpt/main.cpp @@ -29,13 +29,13 @@ class RTDSystem: public System{ auto luaCmpt = cmpts.GetCmpt(CmptAccessType{ "LuaCmpt", AccessMode::WRITE }); double& val = *reinterpret_cast(luaCmpt.Ptr()); val = 520.; - }, "write", ArchetypeFilter{}, locator_write); + }, "write", true, ArchetypeFilter{}, locator_write); schedule.RegisterEntityJob( [](CmptsView cmpts) { auto luaCmpt = cmpts.GetCmpt(CmptAccessType{ "LuaCmpt", AccessMode::LATEST }); const double& val = *reinterpret_cast(luaCmpt.Ptr()); cout << "value : " << val << endl; - }, "read", ArchetypeFilter{}, locator_read); + }, "read", true, ArchetypeFilter{}, locator_read); } }; diff --git a/src/test/12_framegraph/main.cpp b/src/test/12_framegraph/main.cpp index 31263ef..8952c3b 100644 --- a/src/test/12_framegraph/main.cpp +++ b/src/test/12_framegraph/main.cpp @@ -27,6 +27,7 @@ class MySystem : public System { .RegisterEntityJob( [](LastFrame a, Write b, Latest c) {}, "System Func", + true, filter ); } diff --git a/src/test/17_serial/main.cpp b/src/test/17_serial/main.cpp index 27d897b..e3d99b8 100644 --- a/src/test/17_serial/main.cpp +++ b/src/test/17_serial/main.cpp @@ -21,7 +21,7 @@ class PrintASystem : public System { }, "Spilt"); schedule.RegisterEntityJob([](const A*) { std::cout << "A" << std::endl; - }, "Serial Print A", {}, {}, {}, false); + }, "Serial Print A", false); schedule.Order("Parallel Print A", "Spilt"); schedule.Order("Spilt", "Serial Print A"); } @@ -37,11 +37,18 @@ int main() { w.entityMngr.cmptTraits.Register (); - for (size_t i = 0; i < 100; i++) { + for (size_t i = 0; i < 5; i++) { w.Update(); std::cout << "^^^^^^^^^^" << std::endl; } + for (size_t i = 0; i < 100; i++) + w.entityMngr.Create(); + + w.RunEntityJob([](Entity e) { + std::cout << e.Idx() << std::endl; + }, false); + std::cout << w.DumpUpdateJobGraph() << std::endl; std::cout << w.GenUpdateFrameGraph().Dump() << std::endl; }