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
GameHostBase.cs
6using Microsoft.Extensions.Logging;
7
9
13public abstract class GameHostBase : IDisposable
14{
15 private bool _disposed;
16 private bool _initialized;
17 private bool _engineInitialized;
18 private bool _engineStarted;
19
20 private WidgetInputRouter? _widgetInputRouter;
21
25 public Engine Engine => Engine.Instance;
26
30 public Scene? Scene { get; protected set; }
31
35 protected WidgetInputRouter? WidgetInputRouter => _widgetInputRouter;
36
54 public void Initialize(
55 string? configPath = null,
56 bool? autoSaveConfig = null,
57 LogLevel logLevel = LogLevel.Warning)
58 => InitializeCore(configPath, autoSaveConfig, logLevel, configurationStore: null);
59
71 IEngineConfigurationStore configurationStore,
72 bool? autoSaveConfig = null,
73 LogLevel logLevel = LogLevel.Warning)
74 {
75 ArgumentNullException.ThrowIfNull(configurationStore);
76 InitializeCore(configPath: null, autoSaveConfig, logLevel, configurationStore);
77 }
78
79 private void InitializeCore(
80 string? configPath,
81 bool? autoSaveConfig,
82 LogLevel logLevel,
83 IEngineConfigurationStore? configurationStore)
84 {
87
89
90 ConfigureLogging(logLevel);
94
95 InitializeEngine(configPath, autoSaveConfig, configurationStore);
97
98 _initialized = true;
99
101 }
102
116 protected void InitializeWidgetInput(RenderSurfaceHostBase renderSurfaceHost)
117 {
118 ArgumentNullException.ThrowIfNull(renderSurfaceHost);
119
120 _widgetInputRouter?.Dispose();
121
122 var keyboardPoller = Engine.Input.KeyboardEventPoller;
123 var mousePoller = Engine.Input.MouseEventPoller;
124 var touchPoller = Engine.Input.TouchEventPoller;
125
126 mousePoller?.StartMonitoringMouse(
127 trackMouseMovement: true);
128
129 _widgetInputRouter = new WidgetInputRouter(
130 renderSurfaceHost,
131 keyboardPoller,
132 mousePoller,
133 touchPoller);
134
135 _widgetInputRouter.Start();
136 }
137
141 protected virtual void OnInitializing()
142 {
143 }
144
149 protected void ConfigureLogging(
150 LogLevel logLevel)
151 {
152 EngineLogger.SetLogLevel(logLevel);
153 }
154
158 protected abstract void ConfigurePlatform();
159
163 protected void ConfigureInput()
164 {
169
171 }
172
176 protected virtual void ConfigureKeyboard()
177 {
178 }
179
183 protected virtual void ConfigureMouse()
184 {
185 }
186
190 protected virtual void ConfigureGamepads()
191 {
192 }
193
197 protected virtual void ConfigureTouch()
198 {
199 }
200
208 protected virtual void OnInputConfigured()
209 {
210 }
211
215 protected void InitializeGameContent()
216 {
217 LoadContent();
219 BindScene();
220 OnSceneBound();
222 }
223
227 protected void LoadContent()
228 {
229 LoadAssets();
232 }
233
237 protected virtual void LoadAssets()
238 {
239 }
240
244 protected virtual void LoadTilesheets()
245 {
246 }
247
251 protected virtual void LoadAnimationCycles()
252 {
253 }
254
261 protected void CreateSceneGraph()
262 {
264 ?? throw new InvalidOperationException(
265 $"{nameof(CreateInitialScene)} returned null.");
266
269 }
270
274 protected virtual void OnSceneGraphCreated()
275 {
276 }
277
282 protected virtual Scene CreateInitialScene()
283 {
284 return Scene.Empty;
285 }
286
290 protected virtual void CreateInitialViews()
291 {
292 }
293
297 protected virtual void BindScene()
298 {
299 }
300
304 protected virtual void OnSceneBound()
305 {
306 }
307
311 protected void InitializeSceneObjects()
312 {
315 }
316
320 protected virtual void CreateSprites()
321 {
322 }
323
327 protected virtual void CreateDirectDrawings()
328 {
329 }
330
341 protected void InitializeEngine(
342 string? configPath,
343 bool? autoSaveConfig)
344 => InitializeEngine(configPath, autoSaveConfig, configurationStore: null);
345
356 protected void InitializeEngine(
357 string? configPath,
358 bool? autoSaveConfig,
359 IEngineConfigurationStore? configurationStore)
360 {
361 if (configurationStore is null)
362 {
363 Engine.Instance.Initialize(
364 configFileName: configPath,
365 autoSaveConfig: autoSaveConfig);
366 }
367 else
368 {
369 Engine.Instance.InitializeWithConfigurationStore(
370 configurationStore,
371 autoSaveConfig: autoSaveConfig);
372 }
373 _engineInitialized = true;
374
376 }
377
381 protected virtual void OnEngineInitialized()
382 {
383 }
384
392 protected void StartEngine()
393 {
394 var syncContext = GetSynchronizationContext()
395 ?? throw new InvalidOperationException(
396 $"{nameof(Initialize)} must be called on a thread with a current {nameof(SynchronizationContext)}.");
397
398 StartEngineCore(syncContext);
399 _engineStarted = true;
400
402 }
403
408 protected virtual void StartEngineCore(
409 SynchronizationContext syncContext)
410 {
411 Engine.Instance.Start(syncContext);
412 }
413
418 protected virtual SynchronizationContext? GetSynchronizationContext()
419 {
420 return SynchronizationContext.Current;
421 }
422
426 protected virtual void OnEngineStarted()
427 {
428 }
429
433 protected virtual void OnInitialized()
434 {
435 }
436
440 protected virtual void UnhookEvents()
441 {
442 }
443
447 protected void StopEngine()
448 {
450 _engineStarted = false;
451 }
452
456 protected virtual void StopEngineCore()
457 {
458 Engine.Instance.Stop();
459 }
460
464 protected void DisposeEngine()
465 {
466 Engine.Instance.Dispose();
467 _engineInitialized = false;
468 }
469
473 protected virtual void OnDisposing()
474 {
475 }
476
480 protected virtual void OnDisposed()
481 {
482 }
483
490 protected void EnsureNotInitialized()
491 {
492 if (_initialized)
493 {
494 throw new InvalidOperationException(
495 $"{GetType().Name} has already been initialized.");
496 }
497 }
498
505 protected void EnsureNotDisposed()
506 {
507 ObjectDisposedException.ThrowIf(_disposed, this);
508 }
509
517 public void Dispose()
518 {
519 if (_disposed)
520 return;
521
522 // Stop platform scheduling and wait for rendering before any hook can release
523 // native drawing resources. Stop alone only requests that the loop exit.
524 if (_engineStarted)
525 StopEngine();
526
527 if (_engineInitialized)
528 Engine.StopAndWait();
529
530 OnDisposing();
531
532 _widgetInputRouter?.Dispose();
533 _widgetInputRouter = null;
534
535 UnhookEvents();
536
537 if (_engineInitialized)
539
540 _disposed = true;
541
542 OnDisposed();
543
544 GC.SuppressFinalize(this);
545 }
546}
Provides a base class for hosting and managing the lifecycle of a Gondwana game application.
virtual void StopEngineCore()
Performs platform-specific engine shutdown work.
void InitializeEngine(string? configPath, bool? autoSaveConfig)
Initializes the Gondwana engine using the default file-backed configuration store.
virtual void LoadAssets()
Loads textures, sounds, and other game assets.
void ConfigurePlatform()
Configures platform-specific services, adapters, and render infrastructure.
void InitializeEngine(string? configPath, bool? autoSaveConfig, IEngineConfigurationStore? configurationStore)
Initializes the Gondwana engine.
virtual ? SynchronizationContext GetSynchronizationContext()
Gets the synchronization context used to start the engine.
virtual void OnInputConfigured()
Runs after all input devices have been configured.
void InitializeGameContent()
Initializes game-specific content, the scene graph, and scene objects.
void InitializeSceneObjects()
Creates sprites and direct drawings for the current scene.
virtual void ConfigureKeyboard()
Configures the keyboard input adapter.
void LoadContent()
Loads assets, tilesheets, and animation cycles.
virtual void CreateInitialViews()
Creates the initial views and viewports used to render the scene.
virtual void OnInitialized()
Runs after the full host initialization sequence has completed.
virtual void StartEngineCore(SynchronizationContext syncContext)
Starts the engine using the supplied synchronization context.
void DisposeEngine()
Disposes the engine instance.
virtual void OnDisposing()
Runs before managed resources are disposed.
virtual void OnInitializing()
Runs before the host initialization sequence begins.
void EnsureNotInitialized()
Ensures that the host has not already been initialized.
virtual void BindScene()
Binds the current scene to the platform render surface.
virtual void OnEngineInitialized()
Runs after the engine has been initialized but before it has been started.
virtual void OnEngineStarted()
Runs after the engine has been started.
void StopEngine()
Stops the engine during host disposal.
virtual void OnDisposed()
Runs after managed resources have been disposed.
virtual void LoadAnimationCycles()
Loads animation cycle definitions.
virtual void UnhookEvents()
Unhooks custom event handlers during disposal.
virtual void LoadTilesheets()
Loads tilesheet definitions.
virtual void OnSceneBound()
Runs after the current scene has been bound to the render surface host.
virtual void ConfigureGamepads()
Configures the gamepad manager.
virtual void CreateSprites()
Creates sprite objects for the current scene.
void Dispose()
Releases resources owned by the game host.
void CreateSceneGraph()
Creates the initial scene and its views.
Scene? Scene
Gets the current active scene.
virtual Scene CreateInitialScene()
Creates the initial scene for the game.
void Initialize(string? configPath=null, bool? autoSaveConfig=null, LogLevel logLevel=LogLevel.Warning)
Initializes the game host by configuring logging, platform services, input, game content,...
void ConfigureInput()
Configures keyboard, mouse, gamepad, and touch input.
virtual void ConfigureMouse()
Configures the mouse input adapter.
void StartEngine()
Starts the engine using the synchronization context returned by GetSynchronizationContext.
virtual void OnSceneGraphCreated()
Runs after the scene graph has been created but before the scene is bound.
virtual void CreateDirectDrawings()
Creates direct drawings and widgets for the current scene.
void ConfigureLogging(LogLevel logLevel)
Configures the logging level used by Gondwana.
void InitializeWithConfigurationStore(IEngineConfigurationStore configurationStore, bool? autoSaveConfig=null, LogLevel logLevel=LogLevel.Warning)
Initializes the game host using a caller-supplied configuration persistence store.
WidgetInputRouter? WidgetInputRouter
Gets the widget input router, if widget input has been initialized.
void InitializeWidgetInput(RenderSurfaceHostBase renderSurfaceHost)
Initializes widget input routing for the supplied render surface host.
Engine Engine
Gets the singleton instance of the Gondwana engine.
void EnsureNotDisposed()
Ensures that the host has not been disposed.
virtual void ConfigureTouch()
Configures the touch input adapter.
Represents a base class for hosting a render surface, providing functionality for managing rendering ...
Provides a persistence boundary for EngineConfiguration.