Helios Engine
A modular ECS based data-oriented C++23 game engine framework
Loading...
Searching...
No Matches
sub_app.cpp
Go to the documentation of this file.
1
2#include <pch.hpp>
3
5
6#include <helios/app/app.hpp>
7#include <helios/app/details/profile.hpp>
9#include <helios/assert.hpp>
13#include <helios/log/logger.hpp>
14
15#include <mutex>
16#include <thread>
17
18#if defined(HELIOS_APP_ENABLE_PROFILE) && \
19 defined(HELIOS_MODULE_PROFILE_AVAILABLE)
20#include <format>
21#endif
22
23namespace helios::app {
24
28
29SubApp::SubApp(std::string name)
30 : name_(std::move(name)), runner_(RunOnceSubApp) {
32}
33
35 HELIOS_ASSERT(!IsUpdating(), "Cannot clear while sub-app is updating!");
36
37 world_.Clear();
38 scheduler_.Clear();
41 extract_fn_ = nullptr;
42 runner_ = RunOnceSubApp;
43 owner_app_ = nullptr;
44 async_loop_stop_.store(false, std::memory_order_release);
45}
46
47void SubApp::WaitUntilFullyIdle() const noexcept {
48 HELIOS_APP_PROFILE_SCOPE();
49 HELIOS_APP_PROFILE_ZONE_NAME(std::format(
50 "helios::app::SubApp::WaitUntilFullyIdle{{name: {}}}", GetName()));
51 HELIOS_APP_PROFILE_ZONE_TEXT(std::format(
52 "allow_overlapping_updates: {}, max_extraction_skips: {}, is_async: {}",
53 allow_overlapping_updates_, max_extraction_skips_, is_async_));
54
55 while (IsUpdating()) {
56 std::this_thread::yield();
57 }
58}
59
60bool SubApp::ShouldExit() const noexcept {
61 if (AsyncLoopStopRequested()) {
62 return true;
63 }
64
65 if (owner_app_ == nullptr) [[unlikely]] {
66 return false;
67 }
68
69 return owner_app_->ShouldExit().has_value();
70}
71
72bool SubApp::TryBeginUpdate() noexcept {
73 bool expected = false;
74 return is_updating_.compare_exchange_strong(expected, true,
75 std::memory_order_acq_rel);
76}
77
78void SubApp::RunUpdatePass(async::Executor& executor) {
79 if (!TryBeginUpdate()) [[unlikely]] {
80 log::Warn("Failed to update sub-app, update already in progress!");
81 return;
82 }
83
84 struct UpdateGuard {
85 SubApp& sub_app;
86
87 ~UpdateGuard() { sub_app.EndUpdate(); }
88 } guard{*this};
89
90 if (runner_) [[likely]] {
91 runner_(*this, executor);
92 return;
93 }
94
95 if (is_async_) {
96 while (!ShouldExit()) {
97 Update(executor);
98 }
99 return;
100 }
101
102 Update(executor);
103}
104
105void SubApp::RunStageUnchecked(async::Executor& executor,
106 ecs::StageTypeIndex stage, ecs::World& world) {
107 const std::scoped_lock lock(stage_run_mutex_);
108 BuildScheduler(executor);
109 scheduler_.RunStage(stage, world);
110}
111
112} // namespace helios::app
#define HELIOS_ASSERT(condition,...)
Assertion macro that aborts execution in debug builds.
Definition assert.hpp:259
void Clear()
Clears the sub-app world, ECS scheduler, and extract function.
Definition sub_app.cpp:34
void Update(async::Executor &executor)
Runs the configured update stage.
Definition sub_app.hpp:680
bool ShouldExit() const noexcept
Returns whether this sub-app should stop its update loop.
Definition sub_app.cpp:60
void BuildScheduler(async::Executor &executor)
Builds all ECS schedules when any are dirty.
Definition sub_app.hpp:716
SubApp()
Constructs a sub-app with built-in schedules registered.
Definition sub_app.cpp:25
bool IsUpdating() const noexcept
Returns whether an update is in flight.
Definition sub_app.hpp:522
void WaitUntilFullyIdle() const noexcept
Blocks until no update is in flight.
Definition sub_app.cpp:47
const std::string & GetName() const noexcept
Gets the human-readable sub-app name.
Definition sub_app.hpp:412
Manages worker threads and executes task graphs using work-stealing scheduling.
Definition executor.hpp:32
static constexpr TypeIndex From() noexcept
Constructs a TypeIndex from a type T.
void RegisterBuiltinSubAppSchedules(ecs::Scheduler &scheduler)
Registers built-in schedules for a sub-app ECS scheduler.
void RunOnceSubApp(SubApp &sub_app, async::Executor &executor)
Runs a single sub-app update stage.
Definition runners.hpp:152
constexpr UpdateStage kUpdateStage
Builtin stage for per-frame updates.
Definition schedules.hpp:26
utils::TypeIndex StageTypeIndex
Type index for stages.
Definition stage.hpp:12
void Warn(std::string_view message) noexcept
Logs a warning message with the default logger.
Definition logger.hpp:530
STL namespace.