Skip to content

Commit d5d152a

Browse files
authored
Windowing & input (HLU) robustness improvements (#462)
1 parent e29d12b commit d5d152a

File tree

6 files changed

+36
-42
lines changed

6 files changed

+36
-42
lines changed

src/Input/Silk.NET.Input.Sdl/SdlInputContext.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -270,7 +270,8 @@ private void Update(double obj)
270270
gp.Update();
271271
}
272272

273-
Sdl.ThrowError();
273+
// There's actually nowhere here that will raise an SDL error that we cause.
274+
// Sdl.ThrowError();
274275
}
275276

276277
private void RefreshJoysticksAndGamepads()

src/Windowing/Silk.NET.SDL/SdlContext.cs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -99,9 +99,11 @@ private void AssertNotCreated()
9999
/// <inheritdoc cref="IGLContext" />
100100
public void Dispose()
101101
{
102-
AssertCreated();
103-
_sdl.GLDeleteContext(_ctx);
104-
_ctx = null;
102+
if (_ctx != null)
103+
{
104+
_sdl.GLDeleteContext(_ctx);
105+
_ctx = null;
106+
}
105107
}
106108

107109
/// <inheritdoc cref="IGLContext" />

src/Windowing/Silk.NET.Windowing.Common/Internals/ViewImplementationBase.cs

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ protected ViewImplementationBase(ViewOptions opts)
5454
// Property bases - these have extra functionality baked into their getters and setters
5555
protected abstract Vector2D<int> CoreSize { get; }
5656
protected abstract nint CoreHandle { get; }
57+
protected abstract bool CoreIsClosing { get; }
5758

5859
// Function bases - again extra functionality on top
5960
protected abstract void CoreInitialize(ViewOptions opts);
@@ -62,13 +63,11 @@ protected ViewImplementationBase(ViewOptions opts)
6263
// Other APIs implemented abstractly
6364
public abstract IGLContext? GLContext { get; }
6465
public abstract IVkSurface? VkSurface { get; }
65-
public abstract bool IsClosing { get; }
6666
public abstract VideoMode VideoMode { get; }
6767
public abstract bool IsEventDriven { get; set; }
6868
public abstract Vector2D<int> FramebufferSize { get; }
6969
public abstract void DoEvents();
7070
public abstract void ContinueEvents();
71-
public abstract void Dispose();
7271
public abstract Vector2D<int> PointToClient(Vector2D<int> point);
7372
public abstract Vector2D<int> PointToScreen(Vector2D<int> point);
7473
public abstract void Close();
@@ -113,14 +112,14 @@ public void Reset()
113112
{
114113
return;
115114
}
116-
115+
116+
IsInitialized = false;
117117
_renderStopwatch.Reset();
118118
_updateStopwatch.Reset();
119119
_lifetimeStopwatch.Reset();
120120
CoreReset();
121121
UnregisterCallbacks();
122122
Native = null;
123-
IsInitialized = false;
124123
}
125124

126125
// Game loop controls
@@ -197,6 +196,7 @@ public void DoUpdate()
197196
public INativeWindow? Native { get; private set; }
198197
public Vector2D<int> Size => IsInitialized ? CoreSize : default;
199198
public nint Handle => IsInitialized ? CoreHandle : 0;
199+
public bool IsClosing => !IsInitialized || CoreIsClosing; // IsClosing = true if window is reset halts game loop
200200
public GraphicsAPI API => _optionsCache.API;
201201
public double Time => _lifetimeStopwatch.Elapsed.TotalSeconds;
202202
public int? PreferredDepthBufferBits => _optionsCache.PreferredDepthBufferBits;
@@ -254,6 +254,12 @@ public Vector2D<int> PointToFramebuffer(Vector2D<int> point)
254254
Y = point.Y * (fSize.Y / aSize.Y)
255255
};
256256
}
257+
258+
public virtual void Dispose()
259+
{
260+
Reset();
261+
GC.SuppressFinalize(this);
262+
}
257263

258264
// Invoke system
259265
public object Invoke(Delegate d, params object[] args)

src/Windowing/Silk.NET.Windowing.Common/Internals/WindowImplementationBase.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ Vector2D<int> IWindowProperties.Size
9797

9898
bool IWindow.IsClosing
9999
{
100-
get => IsClosing;
100+
get => CoreIsClosing;
101101
set => IsClosingSettable = value;
102102
}
103103

src/Windowing/Silk.NET.Windowing.Glfw/GlfwWindow.cs

Lines changed: 17 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,10 @@
1414

1515
namespace Silk.NET.Windowing.Glfw
1616
{
17-
internal unsafe class GlfwWindow : WindowImplementationBase, IGLContext, IVkSurface
17+
internal unsafe class GlfwWindow : WindowImplementationBase, IVkSurface
1818
{
1919
internal readonly GLFW.Glfw _glfw;
2020
internal WindowHandle* _glfwWindow;
21-
private string _localTitleCache; // glfw doesn't let us get the window title.
22-
private readonly GlfwWindow? _parent;
23-
private readonly GlfwMonitor? _initialMonitor;
2421

2522
// Callbacks
2623
private GlfwCallbacks.WindowPosCallback? _onMove;
@@ -31,8 +28,14 @@ internal unsafe class GlfwWindow : WindowImplementationBase, IGLContext, IVkSurf
3128
private GlfwCallbacks.WindowFocusCallback? _onFocusChanged;
3229
private GlfwCallbacks.WindowIconifyCallback? _onMinimized;
3330
private GlfwCallbacks.WindowMaximizeCallback? _onMaximized;
31+
32+
// Other variables
33+
private readonly GlfwWindow? _parent;
34+
private readonly GlfwMonitor? _initialMonitor;
3435
private Vector2D<int> _nonFullscreenPosition;
3536
private Vector2D<int> _nonFullscreenSize;
37+
private string _localTitleCache; // glfw doesn't let us get the window title.
38+
private GlfwContext? _glContext;
3639

3740
public GlfwWindow(WindowOptions optionsCache, GlfwWindow? parent, GlfwMonitor? monitor) : base(optionsCache)
3841
{
@@ -48,11 +51,11 @@ protected override Vector2D<int> CoreSize
4851
get
4952
{
5053
_glfw.GetWindowSize(_glfwWindow, out var width, out var height);
51-
return new Vector2D<int>(width, height);
54+
return new(width, height);
5255
}
5356
}
5457

55-
protected override unsafe Rectangle<int> CoreBorderSize
58+
protected override Rectangle<int> CoreBorderSize
5659
{
5760
get
5861
{
@@ -84,7 +87,9 @@ protected override void CoreReset()
8487
}
8588

8689
public override IGLContext? GLContext
87-
=> API.API == ContextAPI.OpenGL || API.API == ContextAPI.OpenGLES ? this : null;
90+
=> API.API == ContextAPI.OpenGL || API.API == ContextAPI.OpenGLES
91+
? _glContext ??= new(_glfw, _glfwWindow, this)
92+
: null;
8893

8994
public override IVkSurface? VkSurface => API.API == ContextAPI.Vulkan && _glfw.VulkanSupported() ? this : null;
9095

@@ -109,7 +114,7 @@ protected override Vector2D<int> CorePosition
109114
get
110115
{
111116
_glfw.GetWindowPos(_glfwWindow, out var x, out var y);
112-
return new Vector2D<int>(x, y);
117+
return new(x, y);
113118
}
114119
set => _glfw.SetWindowPos(_glfwWindow, value.X, value.Y);
115120
}
@@ -326,7 +331,6 @@ protected override void CoreInitialize(WindowOptions opts)
326331
{
327332
null => null,
328333
_ when share is GlfwContext glfwContext => (WindowHandle*) glfwContext.Handle,
329-
_ when share is GlfwWindow glfwWindow => glfwWindow._glfwWindow,
330334
_ => throw new ArgumentException("The given shared context should be a GlfwContext or GlfwWindow")
331335
}
332336
);
@@ -373,7 +377,7 @@ public override void SetWindowIcon(ReadOnlySpan<RawImage> icons)
373377
var icon = icons[i];
374378
// ReSharper disable once StackAllocInsideLoop
375379
Span<byte> iconMemory = stackalloc byte[icon.Pixels.Length];
376-
images[i] = new Image
380+
images[i] = new()
377381
{
378382
Width = icon.Width, Height = icon.Height,
379383
Pixels = (byte*) Unsafe.AsPointer(ref iconMemory[0])
@@ -390,7 +394,6 @@ public override void SetWindowIcon(ReadOnlySpan<RawImage> icons)
390394
public override IWindow CreateWindow(WindowOptions opts) => new GlfwWindow(opts, this, null);
391395

392396
public override IWindowHost? Parent => (IWindowHost?) _parent ?? Monitor;
393-
public IGLContextSource? Source => (IGLContextSource?) GLContext;
394397
public override IGLContext? SharedContext { get; }
395398

396399

@@ -486,7 +489,7 @@ private static int IndexOf<T>(T** array, T* target, int count)
486489
return -1;
487490
}
488491

489-
public override bool IsClosing => _glfw.WindowShouldClose(_glfwWindow);
492+
protected override bool CoreIsClosing => _glfw.WindowShouldClose(_glfwWindow);
490493

491494
public override VideoMode VideoMode
492495
=> IsInitialized ? CachedVideoMode = Monitor?.VideoMode ?? CachedVideoMode : CachedVideoMode;
@@ -498,7 +501,7 @@ public override Vector2D<int> FramebufferSize
498501
get
499502
{
500503
_glfw.GetFramebufferSize(_glfwWindow, out var width, out var height);
501-
return new Vector2D<int>(width, height);
504+
return new(width, height);
502505
}
503506
}
504507

@@ -516,12 +519,6 @@ public override void DoEvents()
516519

517520
public override void ContinueEvents() => _glfw.PostEmptyEvent();
518521

519-
public override void Dispose()
520-
{
521-
Reset();
522-
GC.SuppressFinalize(this);
523-
}
524-
525522
public nint GetProcAddress(string proc, int? slot = default)
526523
{
527524
var ret = _glfw.GetProcAddress(proc);
@@ -567,7 +564,7 @@ protected override void RegisterCallbacks()
567564

568565
_onFramebufferResize = (window, width, height) =>
569566
{
570-
FramebufferResize?.Invoke(new Vector2D<int>(width, height));
567+
FramebufferResize?.Invoke(new(width, height));
571568
};
572569

573570
_onClosing = window => Closing?.Invoke();
@@ -690,12 +687,6 @@ protected override void UnregisterCallbacks()
690687
Reset();
691688
}
692689

693-
public bool IsCurrent => _glfw.GetCurrentContext() == _glfwWindow;
694-
public void SwapInterval(int interval) => _glfw.SwapInterval(interval);
695-
public void SwapBuffers() => _glfw.SwapBuffers(_glfwWindow);
696-
public void MakeCurrent() => _glfw.MakeContextCurrent(_glfwWindow);
697-
public void Clear() => _glfw.MakeContextCurrent(null);
698-
699690
public VkNonDispatchableHandle Create<T>(VkHandle instance, T* allocator) where T : unmanaged
700691
{
701692
var surface = stackalloc VkNonDispatchableHandle[1];

src/Windowing/Silk.NET.Windowing.Sdl/SdlView.cs

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ public SdlView(void* nativeHandle, IGLContext? ctx, SdlPlatform platform) : base
6262
internal SDL.Sdl Sdl { get; }
6363
internal SDL.Window* SdlWindow { get; private set; }
6464
internal bool IsClosingVal { get; set; }
65-
public override bool IsClosing => IsClosingVal;
65+
protected override bool CoreIsClosing => IsClosingVal;
6666
public override bool IsEventDriven { get; set; }
6767
public List<Event> Events { get; } = new List<Event>();
6868
protected SdlView? ParentView { get; }
@@ -274,12 +274,6 @@ private void ClearEvents()
274274
}
275275
}
276276

277-
public override void Dispose()
278-
{
279-
Reset();
280-
GC.SuppressFinalize(this);
281-
}
282-
283277
~SdlView()
284278
{
285279
Reset();

0 commit comments

Comments
 (0)