Application Module
The Application module serves as the entry point and lifecycle coordinator for Astra applications. It orchestrates the initialization of all other modules and manages the main application loop.
Purpose
The Application module provides:
- A centralized entry point for Astra applications
- Lifecycle management (initialization, start, run, shutdown)
- Main loop coordination
- Global singleton access throughout the engine
Key Components
Application Class
The Application class is a singleton created via a static factory method. It is not meant to be subclassed.
Public API:
static Application* init()- creates the instance and initializes all subsystemsvoid start()- activates runtime subsystems (window, engine, systems)void run()- runs the main loop; blocks until window closes, then deletes the instancestatic Application* get()- returns the singleton pointerstatic void end()- explicit teardown (alternative torun()exit)
Architecture
Singleton Pattern
The Application uses a static factory (init()) to create the singleton. The constructor is private, preventing direct instantiation or subclassing:
namespace astralix {
class Application {
public:
static Application* init();
void start();
void run();
static Application* get();
static void end();
private:
Application() {};
~Application();
static Application* m_instance;
};
}Initialization Sequence
init() initializes subsystems in this order:
EventDispatcherEventSchedulerTimeProjectManagerEngineSystemManagerWindowManager
Start Sequence
start() activates the runtime subsystems after initialization:
WindowManager::start()- opens the windowEngine::start()- starts the ECS engineSystemManager::start()- starts all registered systems
Main Loop
run() executes the following each frame until the window closes:
while window is open:
time->update()
wm->update()
scheduler POST_FRAME events
system->fixed_update(1/60)
system->update(deltaTime)
scheduler IMMEDIATE events
wm->swap()
// on exit: ~Application() ends Engine, Time, WindowManagerShutdown
The destructor (~Application) handles cleanup automatically in this order:
Engine::end()Time::end()WindowManager::end()
It is invoked either when run() exits (window closed) or when end() is called explicitly.
Usage Pattern
Creating an Application
#include "application.hpp"
using namespace astralix;
int main() {
Application* app = Application::init();
app->start();
app->run(); // blocks until window closes, then cleans up
return 0;
}Accessing from Anywhere
Application* app = Application::get();Explicit Teardown
For headless or non-loop scenarios, call end() instead of run():
Application* app = Application::init();
app->start();
// ... do work ...
Application::end();File Locations
src/modules/application/
├── application.hpp # Application class declaration
└── application.cpp # Application implementationRelated Modules
- Engine - initialized and torn down by Application
- Window - managed via WindowManager
- Project - managed via ProjectManager
Best Practices
- Call in order: always
init()→start()→run(); do not skip steps - Don't subclass: Application has no virtual hooks; extend behavior through systems and the ECS
- No manual shutdown needed:
run()cleans up on exit; only useend()for non-loop scenarios - Access via
get(): use the singleton accessor rather than caching the pointer across frames