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
DirectDrawingManager.cs
1using System.Collections.Concurrent;
2using System.Collections.ObjectModel;
3using System.Drawing;
6
8
41public sealed class DirectDrawingManager : IDisposable
42{
43 // ---- Singleton ----
44 private static readonly Lazy<DirectDrawingManager> _instance =
45 new(() => new DirectDrawingManager());
46
51 public static DirectDrawingManager Instance => _instance.Value;
52
53 // ---- Storage (instance-level) ----
54 private readonly ConcurrentDictionary<string, IDirectDrawable> _directDrawings =
55 new(StringComparer.Ordinal);
56
57 private DirectDrawingManager() { }
58
77 public ReadOnlyCollection<IDirectDrawable> DirectDrawings =>
78 new ReadOnlyCollection<IDirectDrawable>([.. _directDrawings.Values]);
79
91 public int Count => _directDrawings.Count;
92
113 {
114 return name is null ? null : _directDrawings.TryGetValue(name, out IDirectDrawable? d) ? d : null;
115 }
116
135 public void ClearAll()
136 {
137 var toDispose = _directDrawings.Values.ToArray();
138 foreach (var d in toDispose)
139 d.Dispose(); // removal happens via event handler
140 }
141
157 public void Clear(string name)
158 {
159 if (string.IsNullOrEmpty(name)) return;
160 if (_directDrawings.TryGetValue(name, out var d))
161 d.Dispose();
162 }
163
182 internal void UpdateAll(long tick)
183 {
184 // Snapshot to avoid races while iterating (consistent with RenderAll).
185 var snapshot = _directDrawings.Values.ToArray();
186
187 foreach (var drawing in snapshot)
188 drawing.Update(tick);
189 }
190
212 internal void AddOrReplace(IDirectDrawable drawing)
213 {
214 if (drawing is null)
215 throw new ArgumentNullException(nameof(drawing));
216
217 var name = drawing.Nickname!.ToString();
218
219 _directDrawings.AddOrUpdate(
220 name,
221 // Add case
222 key =>
223 {
224 drawing.Disposing += OnDrawingDisposing;
225 return drawing;
226 },
227 // Update case
228 (key, existing) =>
229 {
230 // Unsubscribe old instance
231 existing.Disposing -= OnDrawingDisposing;
232
233 // Dispose it
234 existing.Dispose();
235
236 // Wire up new one
237 drawing.Disposing += OnDrawingDisposing;
238 return drawing;
239 });
240 }
241
242 private static readonly IComparer<DirectDrawingBase> _defaultComparer =
243 Comparer<DirectDrawingBase>.Create((Comparison<DirectDrawingBase>)((a, b) =>
244 {
245 if (a == null && b == null) return 0;
246 if (a == null) return -1;
247 if (b == null) return 1;
248
249 // First compare ZOrder
250 int z = a.ZOrder.CompareTo(b.ZOrder);
251 if (z != 0) return z;
252
253 // If ZOrder equal, fall back to Name
254 return string.Compare(a.Nickname, b.Nickname, StringComparison.Ordinal);
255 }));
256
257 private void OnDrawingDisposing(object? sender, IDirectDrawable drawing)
258 {
259 _directDrawings.TryRemove(drawing.Nickname!, out _);
260 drawing.Disposing -= OnDrawingDisposing;
261 }
262
263 #region helper methods
264
265 internal bool HasVisibleDrawingForLayer(
266 SceneLayer layer,
267 Rectangle worldRect)
268 {
269 foreach (var value in _directDrawings.Values)
270 {
271 if (value is DirectDrawingBase drawing &&
272 drawing.Visible &&
273 drawing.Mode == DirectDrawingMode.SceneLayer &&
274 ReferenceEquals(drawing.SceneLayer, layer) &&
275 drawing.WorldBounds.IntersectsWith(worldRect))
276 {
277 return true;
278 }
279 }
280
281 return false;
282 }
283
309 public IReadOnlyList<DirectDrawingBase> GetDrawingsForLayer(SceneLayer layer)
310 {
311 if (layer is null)
312 return Array.Empty<DirectDrawingBase>();
313
314 // Snapshot to avoid races while iterating (consistent with UpdateAll / Render patterns).
315 var snapshot = _directDrawings.Values.ToArray();
316
317 var result = snapshot
318 .OfType<DirectDrawingBase>()
319 .Where(d =>
320 d.Mode == DirectDrawingMode.SceneLayer &&
321 ReferenceEquals(d.SceneLayer, layer))
322 .ToList();
323
324 result.Sort(_defaultComparer);
325 return result;
326 }
327
354 public IReadOnlyList<DirectDrawingBase> GetDrawingsForView(View view)
355 {
356 if (view is null)
357 return Array.Empty<DirectDrawingBase>();
358
359 var snapshot = _directDrawings.Values.ToArray();
360
361 var result = snapshot
362 .OfType<DirectDrawingBase>()
363 .Where(d =>
364 d.Mode == DirectDrawingMode.View &&
365 ReferenceEquals(d.View, view))
366 .ToList();
367
368 result.Sort(_defaultComparer);
369 return result;
370 }
371
375 public void Dispose()
376 {
377 ClearAll();
378 }
379
380 #endregion helper methods
381}
Provides the base implementation for direct drawing objects that can be rendered to the backbuffer wi...
int Count
Gets the current number of registered direct drawings.
static DirectDrawingManager Instance
Gets the singleton instance of the direct drawing manager.
void Clear(string name)
Disposes and removes a specific direct drawing by its nickname.
IReadOnlyList< DirectDrawingBase > GetDrawingsForView(View view)
Returns all direct drawings associated with a specific view, ordered by Z-order then nickname.
IReadOnlyList< DirectDrawingBase > GetDrawingsForLayer(SceneLayer layer)
Returns all direct drawings associated with a specific scene layer, ordered by Z-order then nickname.
IDirectDrawable? GetDirectDrawing(string name)
Retrieves a direct drawing by its nickname.
ReadOnlyCollection< IDirectDrawable > DirectDrawings
Gets a read-only snapshot of all currently registered direct drawings.
void ClearAll()
Disposes and removes all registered direct drawings.
void Dispose()
Releases all registered direct drawings managed by this instance.
Represents any drawable object (movable or static) that can render directly to a RenderSurfaceHost,...
DirectDrawingMode
Specifies where direct drawing operations are applied within the rendering pipeline.
@ View
Performs direct drawing at the view level using screen-space coordinates.
@ SceneLayer
Performs direct drawing within a scene layer using world-space coordinates.