Helios Engine 0.1.0
A modular ECS based data-oriented C++23 game engine
 
Loading...
Searching...
No Matches
helios::app::App Class Reference

Application class. More...

#include <app.hpp>

Public Types

using RunnerFn = std::function< AppExitCode(App &)>
 
using ExtractFn = std::function< void(const ecs::World &, ecs::World &)>
 

Public Member Functions

 App ()
 
 App (size_t worker_thread_count)
 Constructs an App with a specific number of worker threads.
 
 App (const App &)=delete
 
 App (App &&)=delete
 
 ~App ()
 Destructor that ensures all async work is completed before destruction.
 
Appoperator= (const App &)=delete
 
Appoperator= (App &&)=delete
 
void Clear ()
 Clears the application state, removing all data.
 
void Initialize ()
 Initializes the application and its subsystems.
 
void Update ()
 Updates the application and its subsystems.
 
AppExitCode Run ()
 Runs the application with the given arguments.
 
void WaitForOverlappingUpdates ()
 Waits for all overlapping sub-app updates to complete.
 
template<SubAppTrait T>
void WaitForOverlappingUpdates (T sub_app={})
 Waits for overlapping updates of a specific sub-app type to complete.
 
void WaitForOverlappingUpdates (const SubApp &sub_app)
 Waits for overlapping updates of a specific sub-app instance to complete.
 
void TickTime () noexcept
 Updates the Time resource for the current frame.
 
template<SubAppTrait T>
auto AddSubApp (this auto &&self, T sub_app={}) -> decltype(std::forward< decltype(self)>(self))
 Adds a new sub-application of type T.
 
template<SubAppTrait T>
auto AddSubApp (this auto &&self, SubApp sub_app, T sub_app_tag={}) -> decltype(std::forward< decltype(self)>(self))
 Adds an existing sub-application instance.
 
template<ModuleTrait T>
auto AddModule (this auto &&self) -> decltype(std::forward< decltype(self)>(self))
 Adds a module to the main sub-app.
 
template<ModuleTrait... Modules>
requires (sizeof...(Modules) > 1 && utils::UniqueTypes<Modules...>)
auto AddModules (this auto &&self) -> decltype(std::forward< decltype(self)>(self))
 Adds multiple modules to the main sub-app.
 
auto AddDynamicModule (this auto &&self, DynamicModule module) -> decltype(std::forward< decltype(self)>(self))
 Adds a dynamic module to the main sub-app, taking ownership.
 
template<ecs::SystemTrait T, ScheduleTrait Schedule>
auto AddSystem (this auto &&self, Schedule schedule={}) -> decltype(std::forward< decltype(self)>(self))
 Adds a system to the specified schedule in the main sub-app.
 
template<ecs::SystemTrait... Systems, ScheduleTrait Schedule>
requires (sizeof...(Systems) > 1 && utils::UniqueTypes<Systems...>)
auto AddSystems (this auto &&self, Schedule schedule={}) -> decltype(std::forward< decltype(self)>(self))
 Adds multiple systems to the specified schedule in the main sub-app.
 
template<ecs::SystemTrait... Systems, ScheduleTrait Schedule>
requires (sizeof...(Systems) > 0 && utils::UniqueTypes<Systems...>)
auto AddSystemsBuilder (this auto &&self, Schedule schedule={}) -> SystemConfig< Schedule, Systems... >
 
template<ecs::SystemTrait T, ScheduleTrait Schedule>
auto AddSystemBuilder (this auto &&self, Schedule schedule={}) -> SystemConfig< Schedule, T >
 Adds a single system with fluent configuration builder.
 
template<SystemSetTrait Set, ScheduleTrait Schedule>
auto ConfigureSet (this auto &&self, Schedule schedule={}) -> SystemSetConfig< Schedule, Set >
 
template<ecs::ResourceTrait T>
auto InsertResource (this auto &&self, T &&resource) -> decltype(std::forward< decltype(self)>(self))
 Inserts a resource into the main sub-app.
 
template<ecs::ResourceTrait T, typename... Args>
requires std::constructible_from<T, Args...>
auto EmplaceResource (this auto &&self, Args &&... args) -> decltype(std::forward< decltype(self)>(self))
 Emplaces a resource into the main sub-app's world.
 
template<ecs::EventTrait T>
auto AddEvent (this auto &&self) -> decltype(std::forward< decltype(self)>(self))
 Registers an event type for use in the main sub-app.
 
template<ecs::EventTrait... Events>
requires (sizeof...(Events) > 1)
auto AddEvents (this auto &&self) -> decltype(std::forward< decltype(self)>(self))
 Registers multiple event types for use in the main sub-app.
 
auto SetRunner (this auto &&self, RunnerFn runner) noexcept -> decltype(std::forward< decltype(self)>(self))
 Sets runner function for the application.
 
template<SubAppTrait T>
auto SetSubAppExtraction (this auto &&self, ExtractFn extract_fn) -> decltype(std::forward< decltype(self)>(self))
 Sets extraction function for a sub-app.
 
template<SubAppTrait T>
bool ContainsSubApp () const noexcept
 Checks if a sub app of type T exists in main sub-app.
 
template<ModuleTrait T>
bool ContainsModule () const noexcept
 Checks if a module of type T exists in main sub-app.
 
bool ContainsDynamicModule (ModuleTypeId module_id) const noexcept
 Checks if a dynamic module with the given ID exists.
 
template<ecs::SystemTrait T>
bool ContainsSystem () const noexcept
 Checks if a system of type T exists in any schedule of main sub-app.
 
template<ecs::SystemTrait T, ScheduleTrait Schedule>
bool ContainsSystem (Schedule schedule={}) const noexcept
 Checks if a system of type T exists in the specified schedule of main sub-app.
 
bool IsInitialized () const noexcept
 Checks if the app has been initialized.
 
bool IsRunning () const noexcept
 Checks if the app is currently running.
 
template<ecs::ResourceTrait T>
bool HasResource () const noexcept
 Checks if a resource exists in main sub_app.
 
template<ecs::EventTrait T>
bool HasEvent () const noexcept
 Checks if a event is registered in main sub_app.
 
size_t ModuleCount () const noexcept
 Gets the number of modules in main sub-app.
 
size_t SystemCount () const noexcept
 Gets the total number of systems across all schedules in main sub-app.
 
template<ScheduleTrait Schedule>
size_t SystemCount (Schedule schedule={}) const noexcept
 Gets the number of systems in the specified schedule of main sub-app.
 
template<SubAppTrait T>
SubAppGetSubApp () noexcept
 Gets a sub-application by type.
 
template<SubAppTrait T>
const SubAppGetSubApp () const noexcept
 Gets a sub-application by type (const version).
 
SubAppGetMainSubApp () noexcept
 Gets the main sub-application.
 
const SubAppGetMainSubApp () const noexcept
 Gets the main sub-application (const version).
 
const ecs::WorldGetMainWorld () const noexcept
 Gets the main world.
 
async::ExecutorGetExecutor () noexcept
 Gets the async executor.
 
const async::ExecutorGetExecutor () const noexcept
 Gets the async executor (const version).
 

Detailed Description

Application class.

Manages the application lifecycle, including initialization, updating, and shutdown.

Note
Not thread-safe.
Examples
/home/runner/work/HeliosEngine/HeliosEngine/src/modules/example/include/helios/example/example.hpp.

Definition at line 97 of file app.hpp.

Member Typedef Documentation

◆ ExtractFn

◆ RunnerFn

Constructor & Destructor Documentation

◆ App() [1/4]

helios::app::App::App ( )
Examples
/home/runner/work/HeliosEngine/HeliosEngine/src/core/include/helios/core/app/app.hpp.

Definition at line 22 of file app.cpp.

22: runner_(DefaultRunnerWrapper) {}

◆ App() [2/4]

helios::app::App::App ( size_t  worker_thread_count)
explicit

Constructs an App with a specific number of worker threads.

Parameters
worker_thread_countNumber of worker threads for the executor

Definition at line 24 of file app.cpp.

24: executor_(worker_thread_count), runner_(DefaultRunnerWrapper) {}

◆ App() [3/4]

helios::app::App::App ( const App )
delete

◆ App() [4/4]

helios::app::App::App ( App &&  )
delete

◆ ~App()

helios::app::App::~App ( )

Destructor that ensures all async work is completed before destruction.

Waits for all overlapping updates and pending executor tasks to complete.

Examples
/home/runner/work/HeliosEngine/HeliosEngine/src/core/include/helios/core/app/app.hpp.

Definition at line 26 of file app.cpp.

26 {
27 // Ensure we're not running (should already be false if properly shut down)
28 is_running_.store(false, std::memory_order_release);
29
30 // Wait for any pending overlapping sub-app updates
32
33 // Wait for all pending executor tasks to complete
34 executor_.WaitForAll();
35}
void WaitForOverlappingUpdates()
Waits for all overlapping sub-app updates to complete.
Definition app.cpp:172
void WaitForAll()
Blocks until all submitted tasks complete.
Definition executor.hpp:298

Member Function Documentation

◆ AddDynamicModule()

auto helios::app::App::AddDynamicModule ( this auto &&  self,
DynamicModule  module 
) -> decltype(std::forward<decltype(self)>(self))
inline

Adds a dynamic module to the main sub-app, taking ownership.

Modules can add their own systems, resources, and sub-apps. The App takes ownership of the module via move semantics.

Warning
Triggers an assertion if app is initialized or running.
Parameters
moduleDynamic module to add (moved)
Returns
Reference to app for method chaining
Examples
/home/runner/work/HeliosEngine/HeliosEngine/src/core/include/helios/core/app/app.hpp.

Definition at line 670 of file app.hpp.

671 {
672 const std::string_view name = module.GetModuleName();
673 const ModuleTypeId id = module.GetModuleId();
674
675 HELIOS_ASSERT(!self.IsInitialized(), "Failed to add module '{}': Cannot add modules after app initialization!", name);
676 HELIOS_ASSERT(!self.IsRunning(), "Failed to add module '{}': Cannot add modules while app is running!", name);
677 HELIOS_ASSERT(module.Loaded(), "Failed to add module '{}': Module is not loaded!", name);
678
679 // Check both static and dynamic module maps for duplicates
680 if (self.module_index_map_.contains(id) || self.dynamic_module_index_map_.contains(id)) [[unlikely]] {
681 HELIOS_WARN("Module '{}' already exists in app!", name);
682 return std::forward<decltype(self)>(self);
683 }
684
685 self.dynamic_module_index_map_[id] = self.dynamic_modules_.size();
686 self.dynamic_modules_.push_back(std::move(module));
687 return std::forward<decltype(self)>(self);
688}
#define HELIOS_ASSERT(condition,...)
Assertion macro that aborts execution in debug builds.
Definition assert.hpp:140
#define HELIOS_WARN(...)
Definition logger.hpp:687
size_t ModuleTypeId
Definition module.hpp:84

◆ AddEvent()

template<ecs::EventTrait T>
auto helios::app::App::AddEvent ( this auto &&  self) -> decltype(std::forward<decltype(self)>(self))
inline

Registers an event type for use in the main sub-app.

Events must be registered before they can be written or read.

Warning
Triggers assertion if app is initialized or running.
Template Parameters
TEvent type
Returns
Reference to app for method chaining
Examples
/home/runner/work/HeliosEngine/HeliosEngine/src/core/include/helios/core/app/app.hpp.

Definition at line 742 of file app.hpp.

742 {
743 HELIOS_ASSERT(!self.IsInitialized(), "Failed to add event '{}': Cannot add events after app initialization!",
745
746 HELIOS_ASSERT(!self.IsRunning(), "Failed to add event '{}': Cannot add events while app is running!",
748
749 if (self.template HasEvent<T>()) [[unlikely]] {
750 HELIOS_WARN("Event '{}' is already exist in app!", ecs::EventNameOf<T>());
751 return std::forward<decltype(self)>(self);
752 }
753
754 self.GetMainSubApp().template AddEvent<T>();
755 return std::forward<decltype(self)>(self);
756}
BasicQuery< World, Allocator, Components... > Query
Type alias for query with mutable world access.
Definition query.hpp:2481

◆ AddEvents()

template<ecs::EventTrait... Events>
requires (sizeof...(Events) > 1)
auto helios::app::App::AddEvents ( this auto &&  self) -> decltype(std::forward<decltype(self)>(self))
inline

Registers multiple event types for use in the main sub-app.

Warning
Triggers assertion if app is initialized or running.
Template Parameters
EventsEvent types to register
Returns
Reference to app for method chaining
Examples
/home/runner/work/HeliosEngine/HeliosEngine/src/core/include/helios/core/app/app.hpp.

Definition at line 760 of file app.hpp.

760 {
761 HELIOS_ASSERT(!self.IsInitialized(), "Failed to add events: Cannot add events after app initialization!");
762 HELIOS_ASSERT(!self.IsRunning(), "Failed to add events: Cannot add events while app is running!");
763
764 self.GetMainSubApp().template AddEvents<Events...>();
765 return std::forward<decltype(self)>(self);
766}
auto AddEvents(this auto &&self) -> decltype(std::forward< decltype(self)>(self))
Registers multiple event types for use in the main sub-app.
Definition app.hpp:760

◆ AddModule()

template<ModuleTrait T>
auto helios::app::App::AddModule ( this auto &&  self) -> decltype(std::forward<decltype(self)>(self))
inline

Adds a module to the main sub-app.

Modules can add their own systems, resources, and sub-apps.

Warning
Triggers an assertion if app is initialized or running.
Template Parameters
TModule type
Returns
Reference to app for method chaining
Examples
/home/runner/work/HeliosEngine/HeliosEngine/src/core/include/helios/core/app/app.hpp, and /home/runner/work/HeliosEngine/HeliosEngine/src/modules/example/include/helios/example/example.hpp.

Definition at line 640 of file app.hpp.

640 {
641 HELIOS_ASSERT(!self.IsInitialized(), "Failed to add module '{}': Cannot add modules after app initialization!",
642 ModuleNameOf<T>());
643
644 HELIOS_ASSERT(!self.IsRunning(), "Failed to add module '{}': Cannot add modules while app is running!",
645 ModuleNameOf<T>());
646
647 // module->Build(self); // Will be called after all modules are added
648 constexpr ModuleTypeId id = ModuleTypeIdOf<T>();
649 if (self.module_index_map_.contains(id)) [[unlikely]] {
650 HELIOS_WARN("Module '{}' is already exist in app!", ModuleNameOf<T>());
651 return std::forward<decltype(self)>(self);
652 }
653
654 self.module_index_map_[id] = self.modules_.size();
655 auto module = std::make_unique<T>();
656 self.modules_.push_back(std::move(module));
657 return std::forward<decltype(self)>(self);
658}

◆ AddModules()

template<ModuleTrait... Modules>
requires (sizeof...(Modules) > 1 && utils::UniqueTypes<Modules...>)
auto helios::app::App::AddModules ( this auto &&  self) -> decltype(std::forward<decltype(self)>(self))
inline

Adds multiple modules to the main sub-app.

Warning
Triggers an assertion if app is initialized or running.
Template Parameters
ModulesModule types
Returns
Reference to app for method chaining
Examples
/home/runner/work/HeliosEngine/HeliosEngine/src/core/include/helios/core/app/app.hpp.

Definition at line 662 of file app.hpp.

662 {
663 HELIOS_ASSERT(!self.IsInitialized(), "Failed to add modules: Cannot add modules after app initialization!");
664 HELIOS_ASSERT(!self.IsRunning(), "Failed to add modules: Cannot add modules while app is running!");
665
666 (self.template AddModule<Modules>(), ...);
667 return std::forward<decltype(self)>(self);
668}

◆ AddSubApp() [1/2]

template<SubAppTrait T>
auto helios::app::App::AddSubApp ( this auto &&  self,
SubApp  sub_app,
sub_app_tag = {} 
) -> decltype(std::forward<decltype(self)>(self))
inline

Adds an existing sub-application instance.

Warning
Triggers an assertion if app is initialized or running.
Template Parameters
TSub-application type
Parameters
sub_appSub-application instance to add
sub_app_tagSub-app type tag
Returns
Reference to app for method chaining

Definition at line 611 of file app.hpp.

612 {
613 HELIOS_ASSERT(!self.IsInitialized(), "Failed to add sub app '{}': Cannot add sub apps after app initialization!",
614 SubAppNameOf<T>());
615
616 HELIOS_ASSERT(!self.IsRunning(), "Failed to add sub app '{}': Cannot add sub apps while app is running!",
617 SubAppNameOf<T>());
618
619 constexpr SubAppTypeId id = SubAppTypeIdOf<T>();
620 if (self.sub_app_index_map_.contains(id)) [[unlikely]] {
621 HELIOS_WARN("Sub app '{}' is already exist in app!", SubAppNameOf<T>());
622 return std::forward<decltype(self)>(self);
623 }
624
625 // Set overlapping updates flag based on trait before adding
626 constexpr bool allow_overlapping = SubAppAllowsOverlappingUpdates<T>();
627 sub_app.SetAllowOverlappingUpdates(allow_overlapping);
628
629 // Set max overlapping updates based on trait
630 constexpr size_t max_overlapping = SubAppMaxOverlappingUpdates<T>();
631 sub_app.SetMaxOverlappingUpdates(max_overlapping);
632
633 self.sub_app_index_map_[id] = self.sub_apps_.size();
634 self.sub_apps_.push_back(std::move(sub_app));
635
636 return std::forward<decltype(self)>(self);
637}
size_t SubAppTypeId
Type alias for sub-app type IDs.
Definition sub_app.hpp:128

◆ AddSubApp() [2/2]

template<SubAppTrait T>
auto helios::app::App::AddSubApp ( this auto &&  self,
sub_app = {} 
) -> decltype(std::forward<decltype(self)>(self))
inline

Adds a new sub-application of type T.

Warning
Triggers an assertion if app is initialized or running.
Template Parameters
TSub-application type
Parameters
sub_appSub-app type tag
Returns
Reference to app for method chaining
Examples
/home/runner/work/HeliosEngine/HeliosEngine/src/core/include/helios/core/app/app.hpp.

Definition at line 583 of file app.hpp.

583 {
584 HELIOS_ASSERT(!self.IsInitialized(), "Failed to add sub app '{}': Cannot add sub apps after app initialization!",
585 SubAppNameOf<T>());
586
587 HELIOS_ASSERT(!self.IsRunning(), "Failed to add sub app '{}': Cannot add sub apps while app is running!",
588 SubAppNameOf<T>());
589
590 constexpr SubAppTypeId id = SubAppTypeIdOf<T>();
591 if (self.sub_app_index_map_.contains(id)) [[unlikely]] {
592 HELIOS_WARN("Sub app '{}' is already exist in app!", SubAppNameOf<T>());
593 return std::forward<decltype(self)>(self);
594 }
595
596 self.sub_app_index_map_[id] = self.sub_apps_.size();
597 self.sub_apps_.emplace_back();
598
599 // Set overlapping updates flag based on trait
600 constexpr bool allow_overlapping = SubAppAllowsOverlappingUpdates<T>();
601 self.sub_apps_.back().SetAllowOverlappingUpdates(allow_overlapping);
602
603 // Set max overlapping updates based on trait
604 constexpr size_t max_overlapping = SubAppMaxOverlappingUpdates<T>();
605 self.sub_apps_.back().SetMaxOverlappingUpdates(max_overlapping);
606
607 return std::forward<decltype(self)>(self);
608}

◆ AddSystem()

template<ecs::SystemTrait T, ScheduleTrait Schedule>
auto helios::app::App::AddSystem ( this auto &&  self,
Schedule  schedule = {} 
) -> decltype(std::forward<decltype(self)>(self))
inline

Adds a system to the specified schedule in the main sub-app.

Warning
Triggers an assertion if app is initialized or running.
Template Parameters
TSystem type
ScheduleSchedule type
Parameters
scheduleSchedule to add system to
Returns
Reference to app for method chaining
Examples
/home/runner/work/HeliosEngine/HeliosEngine/src/core/include/helios/core/app/app.hpp.

Definition at line 691 of file app.hpp.

691 {
692 HELIOS_ASSERT(!self.IsInitialized(), "Failed to add system '{}': Cannot add systems after app initialization!",
694
695 HELIOS_ASSERT(!self.IsRunning(), "Failed to add system '{}': Cannot add systems while app is running!",
697
698 if (self.template ContainsSystem<T>(schedule)) [[unlikely]] {
699 HELIOS_WARN("System '{}' is already exist in app schedule '{}'!", ecs::SystemNameOf<T>(),
700 ScheduleNameOf<Schedule>());
701 return std::forward<decltype(self)>(self);
702 }
703
704 self.GetMainSubApp().template AddSystem<T>(schedule);
705 return std::forward<decltype(self)>(self);
706}

◆ AddSystemBuilder()

template<ecs::SystemTrait T, ScheduleTrait Schedule>
auto helios::app::App::AddSystemBuilder ( this auto &&  self,
Schedule  schedule = {} 
) -> SystemConfig<Schedule, T>
inline

Adds a single system with fluent configuration builder.

Returns a builder that allows chaining configuration methods.

Warning
Triggers an assertion if app is initialized or running.
Template Parameters
TSystem type to add
ScheduleSchedule type
Parameters
scheduleSchedule to add system to
Returns
SystemConfig builder for fluent configuration
Examples
/home/runner/work/HeliosEngine/HeliosEngine/src/core/include/helios/core/app/app.hpp.

Definition at line 867 of file app.hpp.

867 {
868 HELIOS_ASSERT(!self.IsInitialized(), "Failed to add system '{}': Cannot add system after app initialization!",
870 HELIOS_ASSERT(!self.IsRunning(), "Failed to add system '{}': Cannot add system while app is running!",
872
873 return self.GetMainSubApp().template AddSystemBuilder<T>(schedule);
874}

◆ AddSystems()

template<ecs::SystemTrait... Systems, ScheduleTrait Schedule>
requires (sizeof...(Systems) > 1 && utils::UniqueTypes<Systems...>)
auto helios::app::App::AddSystems ( this auto &&  self,
Schedule  schedule = {} 
) -> decltype(std::forward<decltype(self)>(self))
inline

Adds multiple systems to the specified schedule in the main sub-app.

Warning
Triggers an assertion if app is initialized or running.
Template Parameters
SystemsSystem types
ScheduleSchedule type
Parameters
scheduleSchedule to add systems to
Returns
Reference to app for method chaining
Examples
/home/runner/work/HeliosEngine/HeliosEngine/src/core/include/helios/core/app/app.hpp.

Definition at line 710 of file app.hpp.

710 {
711 HELIOS_ASSERT(!self.IsInitialized(), "Failed to add systems: Cannot add systems after app initialization!");
712 HELIOS_ASSERT(!self.IsRunning(), "Failed to add systems: Cannot add systems while app is running!");
713
714 self.GetMainSubApp().template AddSystems<Systems...>(schedule);
715 return std::forward<decltype(self)>(self);
716}
auto AddSystems(this auto &&self, Schedule schedule={}) -> decltype(std::forward< decltype(self)>(self))
Adds multiple systems to the specified schedule in the main sub-app.
Definition app.hpp:710

◆ AddSystemsBuilder()

template<ecs::SystemTrait... Systems, ScheduleTrait Schedule>
requires (sizeof...(Systems) > 0 && utils::UniqueTypes<Systems...>)
auto helios::app::App::AddSystemsBuilder ( this auto &&  self,
Schedule  schedule = {} 
) -> SystemConfig<Schedule, Systems...>
inline
Examples
/home/runner/work/HeliosEngine/HeliosEngine/src/core/include/helios/core/app/app.hpp.

Definition at line 859 of file app.hpp.

859 {
860 HELIOS_ASSERT(!self.IsInitialized(), "Failed to add systems: Cannot add systems after app initialization!");
861 HELIOS_ASSERT(!self.IsRunning(), "Failed to add systems: Cannot add systems while app is running!");
862
863 return self.GetMainSubApp().template AddSystemsBuilder<Systems...>(schedule);
864}
auto AddSystemsBuilder(this auto &&self, Schedule schedule={}) -> SystemConfig< Schedule, Systems... >
Definition app.hpp:859

◆ Clear()

void helios::app::App::Clear ( )

Clears the application state, removing all data.

Warning
Triggers assertion if app is running.
Examples
/home/runner/work/HeliosEngine/HeliosEngine/src/core/include/helios/core/app/app.hpp.

Definition at line 37 of file app.cpp.

37 {
38 HELIOS_ASSERT(!IsRunning(), "Failed to clear app: Cannot clear app while it is running!");
39
40 WaitForOverlappingUpdates(); // Ensure all async work is done
41 sub_app_overlapping_futures_.clear();
42 main_sub_app_.Clear();
43 sub_apps_.clear();
44 sub_app_index_map_.clear();
45
46 is_initialized_ = false;
47}
bool IsRunning() const noexcept
Checks if the app is currently running.
Definition app.hpp:430
void Clear()
Clears the sub-app, removing all data.
Definition sub_app.hpp:512

◆ ConfigureSet()

template<SystemSetTrait Set, ScheduleTrait Schedule>
auto helios::app::App::ConfigureSet ( this auto &&  self,
Schedule  schedule = {} 
) -> SystemSetConfig<Schedule, Set>
inline
Examples
/home/runner/work/HeliosEngine/HeliosEngine/src/core/include/helios/core/app/app.hpp.

Definition at line 877 of file app.hpp.

877 {
878 HELIOS_ASSERT(!self.IsInitialized(), "Failed to configure set '{}': Cannot configure set after app initialization!",
879 SystemSetNameOf<Set>());
880 HELIOS_ASSERT(!self.IsRunning(), "Failed to configure set '{}': Cannot configure set while app is running!",
881 SystemSetNameOf<Set>());
882
883 return self.GetMainSubApp().template ConfigureSet<Set>(schedule);
884}

◆ ContainsDynamicModule()

bool helios::app::App::ContainsDynamicModule ( ModuleTypeId  module_id) const
inlinenoexcept

Checks if a dynamic module with the given ID exists.

Parameters
module_idModule type ID
Returns
True if module exists, false otherwise
Examples
/home/runner/work/HeliosEngine/HeliosEngine/src/core/include/helios/core/app/app.hpp.

Definition at line 815 of file app.hpp.

815 {
816 return dynamic_module_index_map_.contains(module_id);
817}

◆ ContainsModule()

template<ModuleTrait T>
bool helios::app::App::ContainsModule ( ) const
inlinenoexcept

Checks if a module of type T exists in main sub-app.

Template Parameters
TModule type
Returns
True if module exists, false otherwise
Examples
/home/runner/work/HeliosEngine/HeliosEngine/src/core/include/helios/core/app/app.hpp.

Definition at line 810 of file app.hpp.

810 {
811 constexpr ModuleTypeId id = ModuleTypeIdOf<T>();
812 return module_index_map_.contains(id) || dynamic_module_index_map_.contains(id);
813}

◆ ContainsSubApp()

template<SubAppTrait T>
bool helios::app::App::ContainsSubApp ( ) const
inlinenoexcept

Checks if a sub app of type T exists in main sub-app.

Template Parameters
TSubApp type
Returns
True if sub app exists, false otherwise
Examples
/home/runner/work/HeliosEngine/HeliosEngine/src/core/include/helios/core/app/app.hpp.

Definition at line 804 of file app.hpp.

804 {
805 constexpr SubAppTypeId id = SubAppTypeIdOf<T>();
806 return sub_app_index_map_.contains(id);
807}

◆ ContainsSystem() [1/2]

template<ecs::SystemTrait T>
bool helios::app::App::ContainsSystem ( ) const
inlinenoexcept

Checks if a system of type T exists in any schedule of main sub-app.

Template Parameters
TSystem type
Returns
True if system exists, false otherwise
Examples
/home/runner/work/HeliosEngine/HeliosEngine/src/core/include/helios/core/app/app.hpp.

Definition at line 404 of file app.hpp.

404 {
405 return main_sub_app_.ContainsSystem<T>();
406 }
bool ContainsSystem() const noexcept
Checks if a system of type T is in any schedule.
Definition sub_app.hpp:380

◆ ContainsSystem() [2/2]

template<ecs::SystemTrait T, ScheduleTrait Schedule>
bool helios::app::App::ContainsSystem ( Schedule  schedule = {}) const
inlinenoexcept

Checks if a system of type T exists in the specified schedule of main sub-app.

Template Parameters
TSystem type
ScheduleSchedule type
Parameters
scheduleSchedule to check
Returns
True if system exists, false otherwise

Definition at line 416 of file app.hpp.

416 {}) const noexcept {
417 return main_sub_app_.ContainsSystem<T>(schedule);
418 }

◆ EmplaceResource()

template<ecs::ResourceTrait T, typename... Args>
requires std::constructible_from<T, Args...>
auto helios::app::App::EmplaceResource ( this auto &&  self,
Args &&...  args 
) -> decltype(std::forward<decltype(self)>(self))
inline

Emplaces a resource into the main sub-app's world.

Warning
Triggers assertion if app is initialized or running.
Template Parameters
TResource type
ArgsConstructor argument types
Parameters
argsArguments to forward to resource constructor
Returns
Reference to app for method chaining
Examples
/home/runner/work/HeliosEngine/HeliosEngine/src/core/include/helios/core/app/app.hpp.

Definition at line 729 of file app.hpp.

729 {
730 HELIOS_ASSERT(!self.IsInitialized(),
731 "Failed to emplace resource '{}': Cannot add resources after app initialization!",
733
734 HELIOS_ASSERT(!self.IsRunning(), "Failed to emplace resource '{}': Cannot add resources while app is running!",
736
737 self.GetMainSubApp().template EmplaceResource<T>(std::forward<Args>(args)...);
738 return std::forward<decltype(self)>(self);
739}

◆ GetExecutor() [1/2]

const async::Executor & helios::app::App::GetExecutor ( ) const
inlinenoexcept

Gets the async executor (const version).

Returns
Const reference to the async executor

Definition at line 522 of file app.hpp.

522{ return executor_; }

◆ GetExecutor() [2/2]

async::Executor & helios::app::App::GetExecutor ( )
inlinenoexcept

Gets the async executor.

Returns
Reference to the async executor
Examples
/home/runner/work/HeliosEngine/HeliosEngine/src/core/include/helios/core/app/app.hpp.

Definition at line 516 of file app.hpp.

516{ return executor_; }

◆ GetMainSubApp() [1/2]

const SubApp & helios::app::App::GetMainSubApp ( ) const
inlinenoexcept

Gets the main sub-application (const version).

Returns
Const reference to the main sub-application

Definition at line 504 of file app.hpp.

504{ return main_sub_app_; }

◆ GetMainSubApp() [2/2]

SubApp & helios::app::App::GetMainSubApp ( )
inlinenoexcept

Gets the main sub-application.

Returns
Reference to the main sub-application
Examples
/home/runner/work/HeliosEngine/HeliosEngine/src/core/include/helios/core/app/app.hpp.

Definition at line 498 of file app.hpp.

498{ return main_sub_app_; }

◆ GetMainWorld()

const ecs::World & helios::app::App::GetMainWorld ( ) const
inlinenoexcept

Gets the main world.

Returns
Reference to the main world
Examples
/home/runner/work/HeliosEngine/HeliosEngine/src/core/include/helios/core/app/app.hpp.

Definition at line 510 of file app.hpp.

510{ return main_sub_app_.GetWorld(); }
const ecs::World & GetWorld() const noexcept
Gets const reference to this sub-app's world.
Definition sub_app.hpp:449

◆ GetSubApp() [1/2]

template<SubAppTrait T>
const SubApp & helios::app::App::GetSubApp ( ) const
inlinenoexcept

Gets a sub-application by type (const version).

Warning
Triggers an assertion if the sub-app does not exist.
Template Parameters
TSub-application type
Returns
Const reference to the sub-application

Definition at line 829 of file app.hpp.

829 {
830 constexpr SubAppTypeId id = SubAppTypeIdOf<T>();
831 const auto it = sub_app_index_map_.find(id);
832 HELIOS_ASSERT(it != sub_app_index_map_.end(), "Failed to get sub app '{}': Sub app does not exist!",
833 SubAppNameOf<T>());
834 return sub_apps_.at(it->second);
835}

◆ GetSubApp() [2/2]

template<SubAppTrait T>
SubApp & helios::app::App::GetSubApp ( )
inlinenoexcept

Gets a sub-application by type.

Warning
Triggers an assertion if the sub-app does not exist. Reference might be invalidated due to reallocation of storage after addition of new sub apps.
Template Parameters
TSub-application type
Returns
Reference to the sub-application
Examples
/home/runner/work/HeliosEngine/HeliosEngine/src/core/include/helios/core/app/app.hpp.

Definition at line 820 of file app.hpp.

820 {
821 constexpr SubAppTypeId id = SubAppTypeIdOf<T>();
822 const auto it = sub_app_index_map_.find(id);
823 HELIOS_ASSERT(it != sub_app_index_map_.end(), "Failed to get sub app '{}': Sub app does not exist!",
824 SubAppNameOf<T>());
825 return sub_apps_.at(it->second);
826}

◆ HasEvent()

template<ecs::EventTrait T>
bool helios::app::App::HasEvent ( ) const
inlinenoexcept

Checks if a event is registered in main sub_app.

Template Parameters
TEvent type
Returns
True if event exists, false otherwise
Examples
/home/runner/work/HeliosEngine/HeliosEngine/src/core/include/helios/core/app/app.hpp.

Definition at line 448 of file app.hpp.

448 {
449 return main_sub_app_.HasEvent<T>();
450 }
bool HasEvent() const noexcept
Checks if an event type is registered in this sub-app.
Definition sub_app.hpp:412

◆ HasResource()

template<ecs::ResourceTrait T>
bool helios::app::App::HasResource ( ) const
inlinenoexcept

Checks if a resource exists in main sub_app.

Template Parameters
TResource type
Returns
True if resource exists, false otherwise
Examples
/home/runner/work/HeliosEngine/HeliosEngine/src/core/include/helios/core/app/app.hpp.

Definition at line 438 of file app.hpp.

438 {
439 return main_sub_app_.HasResource<T>();
440 }
bool HasResource() const noexcept
Checks if a resource of type T exists in this sub-app.
Definition sub_app.hpp:402

◆ Initialize()

void helios::app::App::Initialize ( )

Initializes the application and its subsystems.

Called before the main loop starts. Spawns tasks on the executor for parallel initialization.

Note
Automaticly called in Run().
Warning
Triggers assertion if app is already initialized or running.
Examples
/home/runner/work/HeliosEngine/HeliosEngine/src/core/include/helios/core/app/app.hpp.

Definition at line 116 of file app.cpp.

116 {
117 HELIOS_ASSERT(!IsInitialized(), "Failed to initialize: App is already initialized!");
118 HELIOS_ASSERT(!IsRunning(), "Failed to initialize: Cannot initialize while app is running!");
119
120 async::TaskGraph initialization_graph;
121 initialization_graph.EmplaceTask([this]() {
122 main_sub_app_.BuildScheduler();
123 main_sub_app_.ExecuteStage<helios::app::StartUpStage>(executor_);
124 main_sub_app_.GetWorld().Update();
125 });
126
127 initialization_graph.ForEach(sub_apps_, [this](const SubApp& sub_app_ref) mutable {
128 // Need non-const access to modify sub_app
129 auto& sub_app = const_cast<SubApp&>(sub_app_ref);
130
131 sub_app.BuildScheduler();
132 sub_app.ExecuteStage<helios::app::StartUpStage>(executor_);
133 sub_app.GetWorld().Update();
134 });
135
136 auto future = executor_.Run(initialization_graph);
137
138 update_graph_.ForEach(sub_apps_, [this](const SubApp& sub_app_ref) mutable {
139 if (sub_app_ref.AllowsOverlappingUpdates()) {
140 return;
141 }
142
143 // Need non-const access to modify sub_app
144 auto& sub_app = const_cast<SubApp&>(sub_app_ref);
145 sub_app.Extract(main_sub_app_.GetWorld());
146 sub_app.Update(executor_);
147 });
148
149 future.Wait();
150
151 is_initialized_ = true;
152}
bool IsInitialized() const noexcept
Checks if the app has been initialized.
Definition app.hpp:424
void BuildScheduler()
Builds execution graphs for all schedules.
Definition sub_app.hpp:575
void ExecuteStage(async::Executor &executor)
Executes all schedules in a specific stage.
Definition sub_app.hpp:589
auto Run(TaskGraph &graph) -> Future< void >
Runs a task graph once.
Definition executor.hpp:57
Task ForEach(const R &range, C &&callable)
Creates a parallel for-each task over the given range.
void Update()
Flushes buffer of pending operations.
Definition world.hpp:627
StartUpStage - application initialization phase.
Definition schedules.hpp:26

◆ InsertResource()

template<ecs::ResourceTrait T>
auto helios::app::App::InsertResource ( this auto &&  self,
T &&  resource 
) -> decltype(std::forward<decltype(self)>(self))
inline

Inserts a resource into the main sub-app.

Warning
Triggers assertion if app is initialized or running.
Template Parameters
TResource type
Parameters
resourceResource to insert
Returns
Reference to app for method chaining
Examples
/home/runner/work/HeliosEngine/HeliosEngine/src/core/include/helios/core/app/app.hpp.

Definition at line 719 of file app.hpp.

719 {
720 HELIOS_ASSERT(!self.IsInitialized(), "Failed to insert resource '{}': Cannot add resources after app initialization!",
722
723 self.GetMainSubApp().InsertResource(std::forward<T>(resource));
724 return std::forward<decltype(self)>(self);
725}

◆ IsInitialized()

bool helios::app::App::IsInitialized ( ) const
inlinenoexcept

Checks if the app has been initialized.

Returns
True if initialized, false otherwise
Examples
/home/runner/work/HeliosEngine/HeliosEngine/src/core/include/helios/core/app/app.hpp.

Definition at line 424 of file app.hpp.

424{ return is_initialized_; }

◆ IsRunning()

bool helios::app::App::IsRunning ( ) const
inlinenoexcept

Checks if the app is currently running.

Returns
True if running, false otherwise
Examples
/home/runner/work/HeliosEngine/HeliosEngine/src/core/include/helios/core/app/app.hpp.

Definition at line 430 of file app.hpp.

430{ return is_running_.load(std::memory_order_acquire); }

◆ ModuleCount()

size_t helios::app::App::ModuleCount ( ) const
inlinenoexcept

Gets the number of modules in main sub-app.

Returns
Number of modules
Examples
/home/runner/work/HeliosEngine/HeliosEngine/src/core/include/helios/core/app/app.hpp.

Definition at line 456 of file app.hpp.

456{ return modules_.size() + dynamic_modules_.size(); }

◆ operator=() [1/2]

App & helios::app::App::operator= ( App &&  )
delete

◆ operator=() [2/2]

App & helios::app::App::operator= ( const App )
delete

◆ Run()

AppExitCode helios::app::App::Run ( )

Runs the application with the given arguments.

Warning
Triggers assertion if app is initialized or running.
Returns
Exit code of the application.
Examples
/home/runner/work/HeliosEngine/HeliosEngine/src/core/include/helios/core/app/app.hpp.

Definition at line 49 of file app.cpp.

49 {
50 HELIOS_ASSERT(!IsRunning(), "Failed to run: App is already running!");
51
52 HELIOS_INFO("Starting application...");
53
54 // Register built-in resources and events if not already registered
55 RegisterBuiltins();
56
57 BuildModules();
58 FinishModules();
59 Initialize();
60
61 // Run the application using the provided runner function
62 is_running_.store(true, std::memory_order_release);
63 const AppExitCode exit_code = runner_(*this);
64 is_running_.store(false, std::memory_order_release);
65
66 HELIOS_INFO("Cleaning up application...");
67 CleanUp();
68
69 executor_.WaitForAll();
70
71 DestroyModules();
72
73 // Reset state
74 is_initialized_ = false;
75 sub_app_overlapping_futures_.clear();
76 main_sub_app_.Clear();
77 sub_apps_.clear();
78 sub_app_index_map_.clear();
79
80 HELIOS_INFO("Application exiting with code: {}", std::to_underlying(exit_code));
81 return exit_code;
82}
void Initialize()
Initializes the application and its subsystems.
Definition app.cpp:116
#define HELIOS_INFO(...)
Definition logger.hpp:685
AppExitCode
Application exit codes.
Definition app.hpp:87

◆ SetRunner()

auto helios::app::App::SetRunner ( this auto &&  self,
RunnerFn  runner 
) -> decltype(std::forward<decltype(self)>(self))
inlinenoexcept

Sets runner function for the application.

Warning
Triggers assertion if app is initialized, running, or runner is null.
Parameters
runnerA move-only function that takes an App reference and returns an AppExitCode.
Returns
Reference to app for method chaining
Examples
/home/runner/work/HeliosEngine/HeliosEngine/src/core/include/helios/core/app/app.hpp.

Definition at line 768 of file app.hpp.

768 {
769 HELIOS_ASSERT(!self.IsInitialized(), "Failed to set runner: Cannot set runner after app initialization!");
770 HELIOS_ASSERT(!self.IsRunning(), "Failed to set runner: Cannot set runner while app is running!");
771
772 HELIOS_ASSERT(runner, "Failed to set runner: Runner function cannot be null!");
773
774 self.runner_ = std::move(runner);
775 return std::forward<decltype(self)>(self);
776}

◆ SetSubAppExtraction()

template<SubAppTrait T>
auto helios::app::App::SetSubAppExtraction ( this auto &&  self,
ExtractFn  extract_fn 
) -> decltype(std::forward<decltype(self)>(self))
inline

Sets extraction function for a sub-app.

The extraction function is called before the sub-app's Update to copy data from the main world.

Warning
Triggers assertion if app is initialized, running, extraction function is null, or sub-app doesn't exist.
Template Parameters
TSub-application type
Parameters
extract_fnFunction that takes main world and sub-app world references
Returns
Reference to app for method chaining
Examples
/home/runner/work/HeliosEngine/HeliosEngine/src/core/include/helios/core/app/app.hpp.

Definition at line 779 of file app.hpp.

780 {
782 !self.IsInitialized(),
783 "Failed to set extraction function for sub app '{}': Cannot set extraction function after app initialization!",
784 SubAppNameOf<T>());
785
787 !self.IsRunning(),
788 "Failed to set extraction function for sub app '{}': Cannot set extraction function while app is running!",
789 SubAppNameOf<T>());
790
791 HELIOS_ASSERT(extract_fn, "Failed to set extraction function for sub app '{}': Extraction function cannot be null!",
792 SubAppNameOf<T>());
793
794 constexpr SubAppTypeId id = SubAppTypeIdOf<T>();
795 const auto it = self.sub_app_index_map_.find(id);
796 HELIOS_ASSERT(it != self.sub_app_index_map_.end(),
797 "Failed to set extraction function for sub app '{}': Sub app does not exist!", SubAppNameOf<T>());
798
799 self.sub_apps_.at(it->second).SetExtractFunction(std::move(extract_fn));
800 return std::forward<decltype(self)>(self);
801}

◆ SystemCount() [1/2]

size_t helios::app::App::SystemCount ( ) const
inlinenoexcept

Gets the total number of systems across all schedules in main sub-app.

Returns
Total number of systems
Examples
/home/runner/work/HeliosEngine/HeliosEngine/src/core/include/helios/core/app/app.hpp.

Definition at line 462 of file app.hpp.

462{ return main_sub_app_.SystemCount(); }
size_t SystemCount() const noexcept
Gets the total number of systems across all schedules.
Definition sub_app.hpp:432

◆ SystemCount() [2/2]

template<ScheduleTrait Schedule>
size_t helios::app::App::SystemCount ( Schedule  schedule = {}) const
inlinenoexcept

Gets the number of systems in the specified schedule of main sub-app.

Template Parameters
ScheduleSchedule type
Parameters
scheduleSchedule to query
Returns
Number of systems in the schedule

Definition at line 471 of file app.hpp.

471 {}) const noexcept {
472 return main_sub_app_.SystemCount(schedule);
473 }

◆ TickTime()

void helios::app::App::TickTime ( )
noexcept

Updates the Time resource for the current frame.

Should be called at the beginning of each frame by the runner. Does nothing if Time resource is not registered.

Examples
/home/runner/work/HeliosEngine/HeliosEngine/src/core/include/helios/core/app/app.hpp.

Definition at line 206 of file app.cpp.

206 {
207 if (main_sub_app_.GetWorld().HasResource<Time>()) [[likely]] {
208 main_sub_app_.GetWorld().WriteResource<Time>().Tick();
209 }
210}
bool HasResource() const
Checks if a resource exists.
Definition world.hpp:534
T & WriteResource()
Gets reference to a resource.
Definition world.hpp:933

◆ Update()

void helios::app::App::Update ( )

Updates the application and its subsystems.

Calls Update on the main sub-app and all registered sub-apps. Spawns async tasks as needed.

Note
Should not be called directly - use the runner function instead.
Warning
Triggers assertion if app is not initialized.
Examples
/home/runner/work/HeliosEngine/HeliosEngine/src/core/include/helios/core/app/app.hpp.

Definition at line 84 of file app.cpp.

84 {
85 // Clean up completed per-sub-app overlapping futures using cached ready flags
86 for (auto& [index, futures] : sub_app_overlapping_futures_) {
87 std::erase_if(futures, [](details::TrackedFuture& tracked) { return tracked.IsReady(); });
88 }
89
90 // Update main sub-app (synchronous)
91 main_sub_app_.Update(executor_);
92
93 // Process non-overlapping sub-apps
94 auto non_overlapping_future = executor_.Run(update_graph_);
95
96 // Launch overlapping sub-apps asynchronously (non-blocking)
97 for (size_t i = 0; i < sub_apps_.size(); ++i) {
98 auto& sub_app = sub_apps_[i];
99 if (!sub_app.AllowsOverlappingUpdates()) {
100 continue;
101 }
102
103 // Capture by reference is safe: App lifetime exceeds sub-app updates
104 auto future = executor_.Async([this, &sub_app]() {
105 sub_app.Extract(main_sub_app_.GetWorld());
106 sub_app.Update(executor_);
107 });
108
109 // Store as TrackedFuture for optimized ready-state tracking
110 sub_app_overlapping_futures_[i].push_back(details::TrackedFuture{.future = future.share(), .ready = false});
111 }
112
113 non_overlapping_future.Wait();
114}
void Update(async::Executor &executor)
Updates this sub-app by executing all scheduled systems.
Definition sub_app.hpp:521
auto Async(C &&callable) -> std::future< std::invoke_result_t< C > >
Creates an asynchronous task that runs the given callable.
Definition executor.hpp:225

◆ WaitForOverlappingUpdates() [1/3]

void helios::app::App::WaitForOverlappingUpdates ( )

Waits for all overlapping sub-app updates to complete.

Can be called explicitly when synchronization is needed. Automatically called during CleanUp().

Examples
/home/runner/work/HeliosEngine/HeliosEngine/src/core/include/helios/core/app/app.hpp.

Definition at line 172 of file app.cpp.

172 {
173 for (auto& [index, futures] : sub_app_overlapping_futures_) {
174 for (auto& tracked : futures) {
175 tracked.Wait();
176 }
177 futures.clear();
178 }
179}

◆ WaitForOverlappingUpdates() [2/3]

void helios::app::App::WaitForOverlappingUpdates ( const SubApp sub_app)

Waits for overlapping updates of a specific sub-app instance to complete.

Can be called explicitly when synchronization is needed for a specific sub-app.

Parameters
sub_appReference to the sub-app to wait for

Definition at line 181 of file app.cpp.

181 {
182 // Find the sub-app index by comparing addresses
183 auto sub_app_index = static_cast<size_t>(-1);
184 for (size_t i = 0; i < sub_apps_.size(); ++i) {
185 if (&sub_apps_[i] == &sub_app) {
186 sub_app_index = i;
187 break;
188 }
189 }
190
191 if (sub_app_index == static_cast<size_t>(-1)) [[unlikely]] {
192 return; // Sub-app not found
193 }
194
195 const auto futures_it = sub_app_overlapping_futures_.find(sub_app_index);
196 if (futures_it == sub_app_overlapping_futures_.end()) {
197 return; // No overlapping futures for this sub-app
198 }
199
200 for (auto& tracked : futures_it->second) {
201 tracked.Wait();
202 }
203 futures_it->second.clear();
204}

◆ WaitForOverlappingUpdates() [3/3]

template<SubAppTrait T>
void helios::app::App::WaitForOverlappingUpdates ( sub_app = {})
inline

Waits for overlapping updates of a specific sub-app type to complete.

Can be called explicitly when synchronization is needed for a specific sub-app.

Template Parameters
TSub-app type
Parameters
sub_appSub-app type tag

Definition at line 838 of file app.hpp.

838 {
839 constexpr SubAppTypeId id = SubAppTypeIdOf<T>();
840 const auto it = sub_app_index_map_.find(id);
841 if (it == sub_app_index_map_.end()) [[unlikely]] {
842 return; // Sub-app doesn't exist
843 }
844
845 const size_t index = it->second;
846 const auto futures_it = sub_app_overlapping_futures_.find(index);
847 if (futures_it == sub_app_overlapping_futures_.end()) {
848 return; // No overlapping futures for this sub-app
849 }
850
851 for (auto& tracked : futures_it->second) {
852 tracked.Wait();
853 }
854 futures_it->second.clear();
855}