diff --git a/include/UECS/EntityMngr.h b/include/UECS/EntityMngr.h index f4f99c4..a09bf79 100644 --- a/include/UECS/EntityMngr.h +++ b/include/UECS/EntityMngr.h @@ -112,9 +112,13 @@ namespace Ubpa::UECS { const std::set& QueryArchetypes(const EntityQuery&) const; mutable std::unordered_map> queryCache; + // if job is nullptr, direct run void GenEntityJob(World*, Job*, SystemFunc*) const; + // if job is nullptr, direct run void GenChunkJob(World*, Job*, SystemFunc*) const; + // if job is nullptr, direct run void GenJob(World*, Job*, SystemFunc*) const; + // if job is nullptr, direct run void AutoGen(World*, Job*, SystemFunc*) const; struct EntityInfo { diff --git a/src/core/EntityMngr.cpp b/src/core/EntityMngr.cpp index afb340e..3a7c3d2 100644 --- a/src/core/EntityMngr.cpp +++ b/src/core/EntityMngr.cpp @@ -268,6 +268,7 @@ void EntityMngr::GenEntityJob(World* w, Job* job, SystemFunc* sys) const { return; if (sys->IsParallel()) { + assert(job); size_t indexOffsetInQuery = 0; for (Archetype* archetype : QueryArchetypes(sys->entityQuery)) { auto [chunkEntity, chunkCmpts, sizes] = archetype->Locate(sys->entityQuery.locator); @@ -281,12 +282,13 @@ void EntityMngr::GenEntityJob(World* w, Job* job, SystemFunc* sys) const { size_t idxOffsetInChunk = i * chunkCapacity; size_t indexOffsetInQueryChunk = indexOffsetInQuery + idxOffsetInChunk; CmptsView chunkView{ cmpts.data(), cmpts.size() }; + SingletonsView singletonsView{ singletons.data(), singletons.size() }; size_t J = min(chunkCapacity, num - idxOffsetInChunk); for (size_t j = 0; j < J; j++) { (*sys)( w, - SingletonsView{ singletons.data(), singletons.size() }, + singletonsView, entities[j], indexOffsetInQueryChunk + j, chunkView @@ -301,7 +303,7 @@ void EntityMngr::GenEntityJob(World* w, Job* job, SystemFunc* sys) const { } } else { - job->emplace([this, singletons = std::move(singletons), sys, w]() { + auto work = [this, singletons = std::move(singletons), sys, w]() { size_t indexOffsetInQuery = 0; for (Archetype* archetype : QueryArchetypes(sys->entityQuery)) { auto [chunkEntity, chunkCmpts, sizes] = archetype->Locate(sys->entityQuery.locator); @@ -314,16 +316,17 @@ void EntityMngr::GenEntityJob(World* w, Job* job, SystemFunc* sys) const { size_t idxOffsetInChunk = i * chunkCapacity; size_t indexOffsetInQueryChunk = indexOffsetInQuery + idxOffsetInChunk; CmptsView chunkView{ chunkCmpts[i].data(), chunkCmpts[i].size() }; + SingletonsView singletonsView{ singletons.data(), singletons.size() }; size_t J = min(chunkCapacity, num - idxOffsetInChunk); for (size_t j = 0; j < J; j++) { (*sys)( w, - SingletonsView{ singletons.data(), singletons.size() }, + singletonsView, chunkEntity[i][j], indexOffsetInQueryChunk + j, chunkView - ); + ); for (size_t k = 0; k < chunkCmpts[i].size(); k++) reinterpret_cast(chunkCmpts[i][k].p) += sizes[k]; } @@ -331,7 +334,12 @@ void EntityMngr::GenEntityJob(World* w, Job* job, SystemFunc* sys) const { indexOffsetInQuery += num; } - }); + }; + + if (job) + job->emplace(std::move(work)); + else + work(); } } @@ -343,14 +351,16 @@ void EntityMngr::GenChunkJob(World* w, Job* job, SystemFunc* sys) const { return; if (sys->IsParallel()) { + assert(job != nullptr); for (Archetype* archetype : QueryArchetypes(sys->entityQuery)) { size_t chunkNum = archetype->ChunkNum(); + SingletonsView singletonsView{ singletons.data(), singletons.size() }; for (size_t i = 0; i < chunkNum; i++) { job->emplace([=, singletons = singletons]() { (*sys)( w, - SingletonsView{ singletons.data(), singletons.size() }, + singletonsView, ChunkView{ archetype, i } ); }); @@ -358,7 +368,7 @@ void EntityMngr::GenChunkJob(World* w, Job* job, SystemFunc* sys) const { } } else { - job->emplace([this, w, sys, singletons = std::move(singletons)]() { + auto work = [this, w, sys, singletons = std::move(singletons)]() { for (Archetype* archetype : QueryArchetypes(sys->entityQuery)) { size_t chunkNum = archetype->ChunkNum(); SingletonsView singletonsView{ singletons.data(), singletons.size() }; @@ -371,7 +381,12 @@ void EntityMngr::GenChunkJob(World* w, Job* job, SystemFunc* sys) const { ); } } - }); + }; + + if (job) + job->emplace(std::move(work)); + else + work(); } } @@ -382,12 +397,17 @@ void EntityMngr::GenJob(World* w, Job* job, SystemFunc* sys) const { if (!success) return; - job->emplace([=, singletons = std::move(singletons)]() { + auto work = [=, singletons = std::move(singletons)]() { (*sys)( w, SingletonsView{ singletons.data(), singletons.size() } ); - }); + }; + + if (job) + job->emplace(std::move(work)); + else + work(); } void EntityMngr::AutoGen(World* w, Job* job, SystemFunc* sys) const { diff --git a/src/core/World.cpp b/src/core/World.cpp index 621ba94..be78adc 100644 --- a/src/core/World.cpp +++ b/src/core/World.cpp @@ -45,10 +45,14 @@ string World::DumpUpdateJobGraph() const { } void World::Run(SystemFunc* sys) { - Job job; - JobExecutor executor; - entityMngr.AutoGen(this, &job, sys); - executor.run(job).wait(); + if (sys->IsParallel()) { + Job job; + JobExecutor executor; + entityMngr.AutoGen(this, &job, sys); + executor.run(job).wait(); + } + else + entityMngr.AutoGen(this, nullptr, sys); } // after running Update