![]() |
Gondwana Game Engine Development (master) - 2.6.1
Gondwana is a cross-platform 2.5D game and rendering engine written in C#/.NET 8. It provides fine-grained control over rendering, timing, and scene composition, with built-in support for parallax, z-ordering, pixel overhang, collision detection, and particle effects. Gondwana targets desktop and web platforms using SkiaSharp for graphics and pluggable audio backends for desktop and browser targets.
|
Represents the core game engine singleton responsible for managing the main update loop, input systems, rendering, timing, and subsystem coordination. More...
Public Member Functions | |
| void | Initialize (string? configFileName=null, bool? autoSaveConfig=null, IKeyboardAdapter? keyboardAdapter=null, IMouseAdapter? mouseAdapter=null, ITouchAdapter? touchAdapter=null, IGamepadManager< IGamepadAdapter >? gamepadManager=null) |
| Performs one-time or on-demand initialization of the Engine instance, loading configuration, state files, and input adapters required for execution. | |
| void | InitializeWithConfigurationStore (IEngineConfigurationStore configurationStore, bool? autoSaveConfig=null, IKeyboardAdapter? keyboardAdapter=null, IMouseAdapter? mouseAdapter=null, ITouchAdapter? touchAdapter=null, IGamepadManager< IGamepadAdapter >? gamepadManager=null) |
| Initializes the engine using a caller-supplied configuration persistence store. | |
| void | SaveConfiguration () |
| Persists the current engine configuration through the store supplied during initialization. | |
| void | Start () |
| Starts the Engine using the current thread's SynchronizationContext. | |
| void | Start (SynchronizationContext uiContext) |
| Starts the Engine main loop using the provided SynchronizationContext, initializing the engine if it has not yet been started. | |
| void | StartTimerDriven (SynchronizationContext uiContext) |
| Starts the Engine in timer-driven mode using the provided SynchronizationContext, without spawning a background thread. | |
| void | Tick () |
| Advances the timer-driven engine by one externally presented frame. | |
| void | Stop () |
| Stops the Engine main loop and halts all ongoing processing. | |
| void | StopAndWait () |
| Stops the engine and waits for its background cycle to finish before returning. Resources used by rendering can then be released without racing that cycle. | |
| void | Dispose () |
| Releases all resources used by the Engine and stops all subsystems. | |
Properties | |
| static Engine | Instance [get] |
| Gets the singleton instance of the Engine. | |
| static ILogger< Engine > | Logger [get] |
| Gets the logger instance used by the engine for diagnostic and informational messages. | |
| Diagnostics.RuntimeProfiler | Profiler = new() [get] |
| Opt-in runtime CPU measurements and bounded history, independent of CPS notifications. | |
| IUiDispatcher? | UiDispatcher [get] |
| Gets the UI dispatcher used for marshalling operations to the UI thread. | |
| IEngineDispatcher | EngineDispatcher = new EngineDispatcher() [get] |
| Gets the engine dispatcher used for marshalling operations to the engine's background thread. | |
| bool | IsInitialized [get] |
| Gets a value indicating whether the engine has completed its initialization sequence. | |
| bool | IsInitializing [get] |
| Gets a value indicating whether the engine is currently in the process of initializing. | |
| bool | IsRunning [get] |
| Gets a value indicating whether the engine's main loop is currently executing. | |
| long | TotalTicksEngineRunning [get] |
| Gets the total number of high-resolution timer ticks that have elapsed since the engine started. | |
| double | TotalSecondsEngineRunning [get] |
| Gets the total number of seconds that have elapsed since the engine started. | |
| double | CyclesPerSecond [get] |
| Gets the current gross cycles per second rate. | |
| double | FramesPerSecond [get] |
| Gets the current net frames per second rate. | |
| EngineState | State = new EngineState() [get] |
| Gets the engine's persistent state container for storing arbitrary key-value data. | |
| EngineConfiguration | Configuration [get] |
| Gets the current engine configuration settings. | |
| EngineManagers | Managers = new() [get] |
| Gets the collection of resource managers for audio, SVG, sprites, fonts, tilesheets, and direct drawing. | |
| EngineInputSystems | Input = new() [get] |
| Gets the collection of input subsystems for keyboard, mouse, touch, and gamepad input. | |
| bool | IsDisposed = false [get] |
| Gets a value indicating whether the engine has been disposed. | |
| bool | IsDisposing [get] |
| Gets a value indicating whether the engine is currently executing its disposal sequence. | |
Events | |
| Action? | PreInitialization |
| Occurs immediately before the engine begins its internal initialization sequence. | |
| Action? | PostInitialization |
| Occurs after all internal initialization routines have completed, but before InitializationComplete is raised. | |
| Action? | InitializationComplete |
| Occurs after all initialization steps and post-initialization logic have completed. | |
| Action? | BeforeBackgroundTasksExecute |
| Occurs immediately before DoBackgroundTasks(long) executes within each engine cycle. | |
| Action? | AfterBackgroundTasksExecute |
| Occurs immediately after DoBackgroundTasks(long) has completed. | |
| Action? | BeforeFrameRender |
| Occurs immediately before DoForegroundTasks(long) executes within each engine cycle. | |
| Action? | AfterFrameRender |
| Occurs immediately after DoForegroundTasks(long) completes within each engine cycle. | |
| Action< CyclesPerSecondCalculatedEventArgs >? | CPSCalculated |
| Occurs whenever cycles-per-second (CPS) and frames-per-second (FPS) metrics are calculated. | |
| Action? | Disposing |
| Raised when Dispose() begins the explicit disposal sequence. | |
| Action? | Disposed |
| Raised after the engine has completed explicit disposal. | |
Represents the core game engine singleton responsible for managing the main update loop, input systems, rendering, timing, and subsystem coordination.
The Engine class is implemented as a thread-safe singleton and provides centralized access to all major engine subsystems including input polling, scene management, rendering, and collision detection.
Typical usage involves calling Initialize to configure the engine, then Start(SynchronizationContext) to begin the main loop, and finally Stop followed by Dispose for cleanup.
| void Gondwana.Engine.Dispose | ( | ) |
Releases all resources used by the Engine and stops all subsystems.
This method performs an orderly shutdown of the engine, including:
After disposal, the engine instance should not be used. To restart the engine, a new application session is required.
| void Gondwana.Engine.Initialize | ( | string? | configFileName = null, |
| bool? | autoSaveConfig = null, | ||
| IKeyboardAdapter? | keyboardAdapter = null, | ||
| IMouseAdapter? | mouseAdapter = null, | ||
| ITouchAdapter? | touchAdapter = null, | ||
| IGamepadManager< IGamepadAdapter >? | gamepadManager = null ) |
Performs one-time or on-demand initialization of the Engine instance, loading configuration, state files, and input adapters required for execution.
This method is responsible for preparing all core systems of the engine prior to starting the main loop. It performs the following operations in order:
This method is automatically invoked by Start(SynchronizationContext) if the engine has not yet been initialized. It is safe to call multiple times, but subsequent calls will return immediately once initialization has been completed or is in progress.
Thread-safe guarantees:
_isInitializing and _isInitialized flags. | configFileName | Optional path to a configuration file to load. If null, the default configuration is used. |
| autoSaveConfig | Optional flag indicating whether configuration changes should be automatically saved back to disk. |
| keyboardAdapter | Optional IKeyboardAdapter instance used to initialize the keyboard input subsystem. |
| mouseAdapter | Optional IMouseAdapter instance used to initialize the mouse input subsystem. |
| touchAdapter | Optional ITouchAdapter instance used to initialize the touch input subsystem. |
| gamepadManager | Optional IGamepadManager<T> instance used to initialize the gamepad subsystem. When null, an already configured EngineInputSystems.GamepadManager is preserved rather than cleared. |
| void Gondwana.Engine.InitializeWithConfigurationStore | ( | IEngineConfigurationStore | configurationStore, |
| bool? | autoSaveConfig = null, | ||
| IKeyboardAdapter? | keyboardAdapter = null, | ||
| IMouseAdapter? | mouseAdapter = null, | ||
| ITouchAdapter? | touchAdapter = null, | ||
| IGamepadManager< IGamepadAdapter >? | gamepadManager = null ) |
Initializes the engine using a caller-supplied configuration persistence store.
| configurationStore | Configuration store owned by the engine after successful initialization. |
| autoSaveConfig | Optional override for the store's IEngineConfigurationStore.AutoSave setting. |
| keyboardAdapter | Optional keyboard input adapter. |
| mouseAdapter | Optional mouse input adapter. |
| touchAdapter | Optional touch input adapter. |
| gamepadManager | Optional gamepad manager. |
| void Gondwana.Engine.SaveConfiguration | ( | ) |
| void Gondwana.Engine.Start | ( | ) |
Starts the Engine using the current thread's SynchronizationContext.
This overload is intended for convenience when starting the engine from the UI thread. It retrieves the current SynchronizationContext and forwards it to Start(SynchronizationContext).
The engine must be started from a thread that has a valid SynchronizationContext, typically the primary UI thread. If no synchronization context is available, an InvalidOperationException is thrown.
| InvalidOperationException | Thrown if SynchronizationContext.Current is null. |
| void Gondwana.Engine.Start | ( | SynchronizationContext | uiContext | ) |
Starts the Engine main loop using the provided SynchronizationContext, initializing the engine if it has not yet been started.
This method is the entry point for runtime execution. It ensures the engine is fully initialized before beginning the continuous background processing loop. The loop runs on a separate worker thread and repeatedly invokes Cycle, yielding between iterations to allow cooperative multitasking.
The uiContext argument establishes the UiDispatcher used for posting events and callbacks to the UI thread. All UI-bound events such as PreInitialization, PostInitialization, InitializationComplete, and CPSCalculated will be marshalled through this dispatcher when available.
If the engine is already running, this method returns immediately without taking further action.
Threading behavior:
| uiContext | The SynchronizationContext that defines the UI thread context to which UI-related operations and events will be dispatched. |
| InvalidOperationException | Thrown if uiContext is null. |
| void Gondwana.Engine.StartTimerDriven | ( | SynchronizationContext | uiContext | ) |
Starts the Engine in timer-driven mode using the provided SynchronizationContext, without spawning a background thread.
This overload is designed for environments where a background thread is not viable, such as single-threaded WebAssembly (WASM) runtimes. Instead of spawning a Task to drive the loop, it binds the EngineDispatcher to the calling thread and returns immediately. The caller is then responsible for advancing the engine by calling Tick for each presentation opportunity (for example, browser requestAnimationFrame). Each call may perform multiple fixed simulation updates but no more than one foreground render.
Unlike Start(SynchronizationContext), this method will throw if initialization is already in progress, because waiting for it to complete (via ManualResetEventSlim.Wait) is not safe on a single-threaded runtime.
| uiContext | The SynchronizationContext that defines the UI thread context to which UI-related operations and events will be dispatched. |
| ArgumentNullException | Thrown if uiContext is null. |
| InvalidOperationException | Thrown if initialization is currently in progress on another thread. |
| void Gondwana.Engine.Stop | ( | ) |
Stops the Engine main loop and halts all ongoing processing.
This method cleanly terminates the engine's background execution cycle started by Start(SynchronizationContext). It sets IsRunning to false, signaling the loop in Cycle to exit on the next iteration.
Stop() does not immediately dispose of resources or clear state. It simply halts ongoing updates and rendering, allowing the engine's subsystems (timers, surfaces, input pollers, etc.) to remain intact for later reuse or inspection.
To fully clean up and release all managed resources, call Dispose after stopping the engine.
This method is thread-safe and may be called from any thread.
| void Gondwana.Engine.StopAndWait | ( | ) |
Stops the engine and waits for its background cycle to finish before returning. Resources used by rendering can then be released without racing that cycle.
Call from the hosting thread, outside an engine callback. Timer-driven hosts must stop their platform timer and call this between ticks on the timer's thread. This does not dispose engine state. Unlike Stop, it blocks until an in-flight background cycle completes, even if Stop was already called.
| InvalidOperationException | Called from the active background engine thread. |
| void Gondwana.Engine.Tick | ( | ) |
Advances the timer-driven engine by one externally presented frame.
This method is intended for use with the timer-driven startup path initiated by StartTimerDriven(SynchronizationContext). The caller (typically a platform timer or browser requestAnimationFrame) should invoke this method once per presentation opportunity. Elapsed time is accumulated into zero or more fixed simulation steps, capped by EngineConfiguration.MaxTimerDrivenSimulationSteps, followed by at most one foreground render.
If the engine is not currently running, this method returns immediately without performing any work.
|
get |
Gets the current engine configuration settings.
An EngineConfiguration instance containing all engine settings.
This property provides thread-safe access to the engine's configuration, which is loaded during Initialize from a configuration file or default values.
Configuration settings control behavior such as target frame rate, logging mode, sampling intervals, and other core engine parameters.
|
get |
Gets the current gross cycles per second rate.
The number of complete engine cycles executed per second, including throttled cycles.
This metric reflects all simulation updates, regardless of whether a foreground render was performed. In timer-driven mode a single Tick may contribute zero or multiple updates. It represents the update frequency for background tasks such as input polling, timers, and animations.
This value is updated at the interval specified by EngineConfiguration.SamplingTimeForCPS.
|
get |
Gets the engine dispatcher used for marshalling operations to the engine's background thread.
An IEngineDispatcher instance bound to the engine's update loop thread.
This dispatcher allows external code to safely post work items that should execute on the engine's dedicated background thread, ensuring thread-safe access to engine state.
|
get |
Gets the current net frames per second rate.
The number of complete render frames presented per second.
This metric reflects only cycles that resulted in a foreground render operation, as controlled by EngineConfiguration.TargetFPS. It represents the actual visual frame rate delivered to the user.
This value is updated at the interval specified by EngineConfiguration.SamplingTimeForCPS.
|
get |
Gets the collection of input subsystems for keyboard, mouse, touch, and gamepad input.
An EngineInputSystems instance providing access to all engine input subsystems.
This property provides centralized access to input event pollers and managers for keyboard, mouse, touch, and gamepad devices. Use the nested properties to access specific subsystems such as EngineInputSystems.KeyboardEventPoller, EngineInputSystems.MouseEventPoller, EngineInputSystems.TouchEventPoller, EngineInputSystems.GamepadEventPoller, and EngineInputSystems.GamepadManager.
Input adapters must be provided during Initialize for the corresponding input subsystems to become available.
|
staticget |
|
get |
Gets a value indicating whether the engine has been disposed.
true if Dispose has completed; otherwise, false.
Once this property is true, the engine instance should not be used further. All managed resources have been released and subsystems have been shut down.
|
get |
Gets a value indicating whether the engine is currently executing its disposal sequence.
true if disposal is in progress; otherwise, false.
This property is set to true at the start of Dispose and can be used by subsystems to detect when cleanup is underway.
|
get |
Gets a value indicating whether the engine has completed its initialization sequence.
true if initialization is complete; otherwise, false.
This property returns true after Initialize has successfully completed all setup operations and raised the InitializationComplete event.
|
get |
Gets a value indicating whether the engine is currently in the process of initializing.
true if initialization is in progress; otherwise, false.
This property is true between the start of Initialize and the completion of all initialization steps. It is used to prevent concurrent initialization attempts.
|
get |
Gets a value indicating whether the engine's main loop is currently executing.
true if the engine loop is active; otherwise, false.
This property is set to true when Start(SynchronizationContext) is called and remains true until Stop is invoked or the engine is disposed.
|
staticget |
Gets the logger instance used by the engine for diagnostic and informational messages.
An ILogger<TCategoryName> instance configured for the Engine type.
This logger is used internally by the engine to report initialization status, errors, warnings, and other runtime information.
|
get |
Gets the collection of resource managers for audio, SVG, sprites, fonts, tilesheets, and direct drawing.
An EngineManagers instance providing access to all engine resource managers.
This property provides centralized access to subsystem managers responsible for loading and managing various types of game resources. Use the nested properties to access specific managers such as EngineManagers.AudioResources, EngineManagers.SvgResources, EngineManagers.Sprites, EngineManagers.Fonts, EngineManagers.Tilesheets, and EngineManagers.DirectDrawings.
|
get |
|
get |
Gets the engine's persistent state container for storing arbitrary key-value data.
An EngineState instance that persists across engine sessions.
The State container provides a convenient mechanism for storing game-specific configuration, player progress, or other persistent data that should survive between application runs.
State can be loaded from and saved to disk using the methods provided by the EngineState class.
|
get |
Gets the total number of seconds that have elapsed since the engine started.
The elapsed time in seconds as a floating-point value.
This value is derived from TotalTicksEngineRunning and provides a convenient measure of total runtime duration.
|
get |
Gets the total number of high-resolution timer ticks that have elapsed since the engine started.
The elapsed ticks as measured by HighResTimer.
This value represents elapsed time in the native resolution of the high-resolution timer. Use TotalSecondsEngineRunning for a time value in seconds.
|
get |
Gets the UI dispatcher used for marshalling operations to the UI thread.
An IUiDispatcher instance if the engine was started with a valid SynchronizationContext; otherwise, null.
This dispatcher is established when Start(SynchronizationContext) is called and is used to post events and operations that must execute on the UI thread.
| Action? Gondwana.Engine.AfterBackgroundTasksExecute |
| Action? Gondwana.Engine.AfterFrameRender |
| Action? Gondwana.Engine.BeforeBackgroundTasksExecute |
| Action? Gondwana.Engine.BeforeFrameRender |
| Action<CyclesPerSecondCalculatedEventArgs>? Gondwana.Engine.CPSCalculated |
Occurs whenever cycles-per-second (CPS) and frames-per-second (FPS) metrics are calculated.
Raised at a regular interval defined by EngineConfiguration.SamplingTimeForCPS. Provides a snapshot of gross and net cycle rates, total elapsed time, and sample interval through a CyclesPerSecondCalculatedEventArgs payload.
This event is posted to the UI thread when a UiDispatcher is available.
| Action? Gondwana.Engine.Disposed |
Raised after the engine has completed explicit disposal.
Fired only when Dispose() is called (never from the finalizer). Indicates all managed cleanup has completed and IsDisposed is true. If a UiDispatcher is available, this event is posted to the UI thread.
| Action? Gondwana.Engine.Disposing |
Raised when Dispose() begins the explicit disposal sequence.
Fired only when Dispose() is called (never from the finalizer). Handlers run before managed cleanup while engine state is still readable. If a UiDispatcher is available, this event is posted to the UI thread.
| Action? Gondwana.Engine.InitializationComplete |
Occurs after all initialization steps and post-initialization logic have completed.
This event is raised at the end of Initialize, every time the method is called. It signifies that the engine and its subsystems are fully active and ready for runtime operations.
If a UiDispatcher is available, this event is posted to the UI thread; otherwise, it executes on the calling thread.
| Action? Gondwana.Engine.PostInitialization |
Occurs after all internal initialization routines have completed, but before InitializationComplete is raised.
This event is raised once per engine lifetime, following successful configuration loading, state restoration, and adapter setup.
Use this event for post-initialization logic that depends on fully loaded engine settings but precedes runtime activation.
If a UiDispatcher is available, this event is posted to the UI thread; otherwise, it executes on the calling thread.
| Action? Gondwana.Engine.PreInitialization |
Occurs immediately before the engine begins its internal initialization sequence.
This event is raised once per engine lifetime, the first time Initialize is called. It provides an early hook for systems that must perform setup prior to configuration loading or input subsystem initialization.
If a UiDispatcher is available, this event is posted to the UI thread; otherwise, it executes on the calling thread.