Application¶
The Application class is the core of Evoker Engine. It manages the main application lifecycle, window creation, rendering loop, and coordinate all major systems.
Overview¶
The Application class is a singleton that:
- Creates and manages the application window
- Initializes Vulkan rendering context
- Manages the layer stack for organizing game logic
- Coordinates the update and render loops
- Handles input system initialization
- Manages scenes and resources
- Dispatches events to layers
Creating an Application¶
using EvokerEngine.Core;
// Create application with default settings (1280x720)
var app = new Application("My Game");
// Or specify custom window size
var app = new Application("My Game", 1920, 1080);
// Push layers to add functionality
app.PushLayer(new GameLayer());
app.PushOverlay(new UILayer());
// Run the application (blocks until window closes)
app.Run();
Application Lifecycle¶
1. Initialization (Constructor)¶
When you create an Application instance:
- Sets up the singleton instance
- Creates the main scene
- Configures window options for Vulkan
- Creates the window using Silk.NET
- Registers event callbacks
2. Loading (OnLoad)¶
Called once when the window is ready:
- Initializes input systems (keyboard, mouse, gamepad)
- Sets up input event callbacks
- Initializes Vulkan context
- Creates the swapchain
- Resets the time system
- Calls
OnAttach()on all layers
3. Update Loop (OnUpdate)¶
Called every frame:
- Updates Time system (delta time, FPS)
- Calls
OnUpdate()on all layers - Updates the active scene
- Skipped when window is minimized
4. Render Loop (OnRender)¶
Called every frame:
- Calls
OnRender()on all layers - Performs rendering operations
- Skipped when window is minimized
5. Shutdown (OnClose)¶
Called when the application closes:
- Cleans up swapchain
- Cleans up Vulkan context
- Unloads all resources
- Calls
OnDetach()on all layers
Properties¶
Instance¶
Gets the singleton Application instance. Throws exception if not created.
Window¶
Gets the application window. Used to query window size, title, etc.
VulkanContext¶
Gets the Vulkan rendering context for advanced rendering operations.
ActiveScene¶
Gets the currently active scene containing entities and components.
ResourceManager¶
Gets the resource manager for loading and managing assets.
Methods¶
Run()¶
Starts the application main loop. This method blocks until the window is closed.
Example:
var app = new Application("My Game");
app.PushLayer(new GameLayer());
app.Run(); // Blocks here until window closes
Close()¶
Closes the application and exits the main loop.
Example:
public override void OnEvent(Event e)
{
if (e is KeyPressedEvent keyEvent && keyEvent.KeyCode == Key.Escape)
{
Application.Instance.Close();
}
}
PushLayer()¶
Adds a layer to the layer stack. Layers are processed in the order they're added.
Example:
PushOverlay()¶
Adds an overlay layer. Overlays are always processed after regular layers and rendered on top.
Example:
Event Handling¶
The Application automatically dispatches events to layers in reverse order (top to bottom). This allows overlays to handle events first.
Events dispatched:
- Window events:
WindowResizeEvent,WindowCloseEvent - Keyboard events:
KeyPressedEvent,KeyReleasedEvent - Mouse events:
MouseButtonPressedEvent,MouseButtonReleasedEvent,MouseMovedEvent,MouseScrolledEvent - Gamepad events:
GamepadButtonPressedEvent,GamepadButtonReleasedEvent
Complete Example¶
using EvokerEngine.Core;
using Silk.NET.Input;
namespace MyGame;
class Program
{
static void Main(string[] args)
{
var app = new Application("My Awesome Game", 1280, 720);
app.PushLayer(new GameLayer());
app.Run();
}
}
class GameLayer : Layer
{
private Entity _player;
public GameLayer() : base("Game Layer") { }
public override void OnAttach()
{
Logger.Info("Game layer attached");
// Create player entity
var scene = Application.Instance.ActiveScene;
_player = scene.CreateEntity("Player");
var transform = scene.Registry.AddComponent<TransformComponent>(_player);
transform.Position = new Vector3(0, 0, 0);
}
public override void OnUpdate(float deltaTime)
{
var scene = Application.Instance.ActiveScene;
var transform = scene.Registry.GetComponent<TransformComponent>(_player);
// Move player with WASD
float speed = 5f * deltaTime;
if (Input.IsKeyPressed(Key.W))
transform.Position += new Vector3(0, 0, -speed);
if (Input.IsKeyPressed(Key.S))
transform.Position += new Vector3(0, 0, speed);
if (Input.IsKeyPressed(Key.A))
transform.Position += new Vector3(-speed, 0, 0);
if (Input.IsKeyPressed(Key.D))
transform.Position += new Vector3(speed, 0, 0);
}
public override void OnRender()
{
// Render game objects
}
public override void OnEvent(Event e)
{
if (e is KeyPressedEvent keyEvent)
{
if (keyEvent.KeyCode == Key.Escape)
{
Application.Instance.Close();
}
}
}
public override void OnDetach()
{
Logger.Info("Game layer detached");
}
}
Best Practices¶
✅ Do's¶
- Create only one Application instance
- Use
Application.Instanceto access the singleton - Push layers in the correct order (gameplay first, UI last)
- Handle window resize events to update camera/viewport
- Clean up resources in
OnDetach()
❌ Don'ts¶
- Don't create multiple Application instances
- Don't block the update/render loops with long operations
- Don't directly access window callbacks (use events instead)
- Don't forget to call
Run()after setup
Platform Support¶
The Application class works seamlessly across all supported platforms:
- Windows: Win32 surface, DirectInput
- Linux: XCB/Wayland surface, evdev input
- macOS: Metal surface, IOKit input
- iOS: Metal surface, UIKit input
- Android: Android surface, native input
Platform detection is automatic - no special code required!
See Also¶
- Layers - Layer system documentation
- Events - Event system documentation
- Scene Management - Scene and entity management