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.
Loading...
Searching...
No Matches
Gondwana.Engine Class Referencesealed

Represents the core game engine singleton responsible for managing the main update loop, input systems, rendering, timing, and subsystem coordination. More...

Inheritance diagram for Gondwana.Engine:

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.

Detailed Description

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.

Definition at line 35 of file Engine.cs.

Member Function Documentation

◆ Dispose()

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:

  • Stopping the main engine loop
  • Waiting for the background thread to exit when disposal is initiated off the engine thread
  • Raising the Disposing event
  • Cleaning up input subsystems
  • Saving configuration changes when automatic saving is enabled
  • Stopping asynchronous logging and flushing queued entries if configured
  • Clearing timers and state
  • Raising the Disposed event

After disposal, the engine instance should not be used. To restart the engine, a new application session is required.

Definition at line 1404 of file Engine.cs.

◆ Initialize()

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:

  1. Raises the PreInitialization event (on the UI thread if available).
  2. Loads engine configuration settings from file using EngineConfigurationFile.Load.
  3. Loads any EngineState files declared in configuration.
  4. Initializes input subsystems for keyboard, mouse, and gamepad polling, if corresponding adapters are provided.
  5. Raises PostInitialization after all internal setup is complete.
  6. Marks the engine as initialized and raises InitializationComplete.

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:

  • Concurrent calls are prevented by internal _isInitializing and _isInitialized flags.
  • Events that must run on the UI thread are dispatched through UiDispatcher if available.
Parameters
configFileNameOptional path to a configuration file to load. If null, the default configuration is used.
autoSaveConfigOptional flag indicating whether configuration changes should be automatically saved back to disk.
keyboardAdapterOptional IKeyboardAdapter instance used to initialize the keyboard input subsystem.
mouseAdapterOptional IMouseAdapter instance used to initialize the mouse input subsystem.
touchAdapterOptional ITouchAdapter instance used to initialize the touch input subsystem.
gamepadManagerOptional IGamepadManager<T> instance used to initialize the gamepad subsystem. When null, an already configured EngineInputSystems.GamepadManager is preserved rather than cleared.
See also
Start(SynchronizationContext), Stop, EngineConfiguration, EngineState

◆ InitializeWithConfigurationStore()

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.

Parameters
configurationStoreConfiguration store owned by the engine after successful initialization.
autoSaveConfigOptional override for the store's IEngineConfigurationStore.AutoSave setting.
keyboardAdapterOptional keyboard input adapter.
mouseAdapterOptional mouse input adapter.
touchAdapterOptional touch input adapter.
gamepadManagerOptional gamepad manager.

Definition at line 324 of file Engine.cs.

◆ SaveConfiguration()

void Gondwana.Engine.SaveConfiguration ( )

Persists the current engine configuration through the store supplied during initialization.

Exceptions
InvalidOperationExceptionThrown when the engine has not yet been initialized with a configuration store.

Definition at line 431 of file Engine.cs.

◆ Start() [1/2]

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.

Exceptions
InvalidOperationExceptionThrown if SynchronizationContext.Current is null.
See also
Start(SynchronizationContext), Initialize, Stop

Definition at line 460 of file Engine.cs.

◆ Start() [2/2]

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:

  • The engine's main loop runs on a background task, not the UI thread.
  • All rendering and timing operations are controlled through Cycle.
  • The UiDispatcher guarantees that event notifications targeting the UI are executed safely on the originating thread.
Parameters
uiContextThe SynchronizationContext that defines the UI thread context to which UI-related operations and events will be dispatched.
Exceptions
InvalidOperationExceptionThrown if uiContext is null.
See also
Initialize, Stop, Cycle, UiDispatcher

Definition at line 510 of file Engine.cs.

◆ StartTimerDriven()

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.

Parameters
uiContextThe SynchronizationContext that defines the UI thread context to which UI-related operations and events will be dispatched.
Exceptions
ArgumentNullExceptionThrown if uiContext is null.
InvalidOperationExceptionThrown if initialization is currently in progress on another thread.
See also
Tick, Start(SynchronizationContext), Stop

Definition at line 593 of file Engine.cs.

◆ Stop()

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.

See also
Start(), Cycle, Dispose(), IsRunning

Definition at line 729 of file Engine.cs.

◆ StopAndWait()

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.

Exceptions
InvalidOperationExceptionCalled from the active background engine thread.

Definition at line 751 of file Engine.cs.

◆ Tick()

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.

See also
StartTimerDriven(SynchronizationContext), Stop

Definition at line 649 of file Engine.cs.

Property Documentation

◆ Configuration

EngineConfiguration Gondwana.Engine.Configuration
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.

Definition at line 927 of file Engine.cs.

◆ CyclesPerSecond

double Gondwana.Engine.CyclesPerSecond
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.

Definition at line 872 of file Engine.cs.

◆ EngineDispatcher

IEngineDispatcher Gondwana.Engine.EngineDispatcher = new EngineDispatcher()
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.

Returns
The result.

Definition at line 802 of file Engine.cs.

◆ FramesPerSecond

double Gondwana.Engine.FramesPerSecond
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.

Definition at line 891 of file Engine.cs.

◆ Input

EngineInputSystems Gondwana.Engine.Input = new()
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.

Definition at line 968 of file Engine.cs.

◆ Instance

Engine Gondwana.Engine.Instance
staticget

Gets the singleton instance of the Engine.

The globally shared Engine instance.

This property provides thread-safe access to the engine instance using lazy initialization. The instance is created on first access and persists for the application lifetime.

Definition at line 49 of file Engine.cs.

◆ IsDisposed

bool Gondwana.Engine.IsDisposed = false
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.

Definition at line 978 of file Engine.cs.

◆ IsDisposing

bool Gondwana.Engine.IsDisposing
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.

Definition at line 988 of file Engine.cs.

◆ IsInitialized

bool Gondwana.Engine.IsInitialized
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.

Definition at line 812 of file Engine.cs.

◆ IsInitializing

bool Gondwana.Engine.IsInitializing
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.

Definition at line 822 of file Engine.cs.

◆ IsRunning

bool Gondwana.Engine.IsRunning
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.

Definition at line 832 of file Engine.cs.

◆ Logger

ILogger<Engine> Gondwana.Engine.Logger
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.

Definition at line 59 of file Engine.cs.

◆ Managers

EngineManagers Gondwana.Engine.Managers = new()
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.

Definition at line 947 of file Engine.cs.

◆ Profiler

Diagnostics.RuntimeProfiler Gondwana.Engine.Profiler = new()
get

Opt-in runtime CPU measurements and bounded history, independent of CPS notifications.

Each consumer owns a disposable collection request. Queries return detached data.

Definition at line 228 of file Engine.cs.

◆ State

EngineState Gondwana.Engine.State = new EngineState()
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.

Definition at line 908 of file Engine.cs.

◆ TotalSecondsEngineRunning

double Gondwana.Engine.TotalSecondsEngineRunning
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.

Definition at line 852 of file Engine.cs.

◆ TotalTicksEngineRunning

long Gondwana.Engine.TotalTicksEngineRunning
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.

Definition at line 842 of file Engine.cs.

◆ UiDispatcher

IUiDispatcher? Gondwana.Engine.UiDispatcher
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.

Definition at line 791 of file Engine.cs.

Event Documentation

◆ AfterBackgroundTasksExecute

Action? Gondwana.Engine.AfterBackgroundTasksExecute

Occurs immediately after DoBackgroundTasks(long) has completed.

Use this event to perform custom actions or monitoring after all background updates (timers, input, animations, surface refreshes, etc.) have been processed.

Definition at line 160 of file Engine.cs.

◆ AfterFrameRender

Action? Gondwana.Engine.AfterFrameRender

Occurs immediately after DoForegroundTasks(long) completes within each engine cycle.

Use this event to perform logic that depends on a completed render frame, such as post-render effects, profiling, or scheduling background jobs.

Definition at line 182 of file Engine.cs.

◆ BeforeBackgroundTasksExecute

Action? Gondwana.Engine.BeforeBackgroundTasksExecute

Occurs immediately before DoBackgroundTasks(long) executes within each engine cycle.

Use this event to inject custom background logic such as diagnostics, AI updates, or subsystem polling prior to the engine's own background operations.

Definition at line 149 of file Engine.cs.

◆ BeforeFrameRender

Action? Gondwana.Engine.BeforeFrameRender

Occurs immediately before DoForegroundTasks(long) executes within each engine cycle.

Use this event to perform per-frame setup tasks prior to rendering or to update game state that must occur before foreground drawing.

Definition at line 171 of file Engine.cs.

◆ CPSCalculated

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.

Definition at line 200 of file Engine.cs.

◆ Disposed

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.

Definition at line 220 of file Engine.cs.

◆ Disposing

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.

Definition at line 210 of file Engine.cs.

◆ InitializationComplete

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.

Definition at line 138 of file Engine.cs.

◆ PostInitialization

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.

Definition at line 123 of file Engine.cs.

◆ PreInitialization

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.

Definition at line 103 of file Engine.cs.