Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions src/KappaDuck.Quack/Events/EventManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,19 @@ public static bool Wait(out Event e, TimeSpan? timeout = null)
return Native.SDL_WaitEventTimeout(out e, (int)timeout.Value.TotalMilliseconds);
}

/// <summary>
/// Creates an event watcher that invokes the specified callback function whenever an event is added to the event queue.
/// </summary>
/// <param name="callback">The callback function to be invoked when an event is added.</param>
public static EventWatcher Watch(Action<Event> callback)
{
return new EventWatcher((_, ref e) =>
{
callback(e);
return true;
});
}

private static void ThrowIfInvalidRange(EventType min, EventType? max)
{
if (max is null)
Expand Down
24 changes: 24 additions & 0 deletions src/KappaDuck.Quack/Events/EventWatcher.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// Copyright (c) KappaDuck. All rights reserved.
// The source code is licensed under MIT License.

namespace KappaDuck.Quack.Events;

/// <summary>
/// Represents an event watcher to monitor new events added to the event queue.
/// </summary>
/// <remarks>
/// You can dispose the watcher to stop monitoring events.
/// </remarks>
public sealed class EventWatcher : IDisposable
{
private readonly Native.EventFilter _callback;

internal EventWatcher(Native.EventFilter callback)
{
_callback = callback;
Native.SDL_AddEventWatch(_callback);
}

/// <inheritdoc/>
public void Dispose() => Native.SDL_RemoveEventWatch(_callback);
}
14 changes: 14 additions & 0 deletions src/KappaDuck.Quack/Interop/SDL/Native.Events.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@ namespace KappaDuck.Quack.Interop.SDL;

internal static partial class Native
{
[LibraryImport(SDL), UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
[DefaultDllImportSearchPaths(DllImportSearchPath.SafeDirectories)]
[return: MarshalAs(UnmanagedType.U1)]
internal static partial bool SDL_AddEventWatch(EventFilter callback, nint data = default);

[LibraryImport(SDL), UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
[DefaultDllImportSearchPaths(DllImportSearchPath.SafeDirectories)]
[return: MarshalAs(UnmanagedType.U1)]
Expand Down Expand Up @@ -48,6 +53,11 @@ internal static partial class Native
[return: MarshalAs(UnmanagedType.U1)]
internal static partial bool SDL_PushEvent(ref Event e);

[LibraryImport(SDL), UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
[DefaultDllImportSearchPaths(DllImportSearchPath.SafeDirectories)]
[return: MarshalAs(UnmanagedType.U1)]
internal static partial bool SDL_RemoveEventWatch(EventFilter callback, nint data = default);

[LibraryImport(SDL), UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
[DefaultDllImportSearchPaths(DllImportSearchPath.SafeDirectories)]
internal static partial void SDL_SetEventEnabled(EventType type, [MarshalAs(UnmanagedType.U1)] bool enabled);
Expand All @@ -61,4 +71,8 @@ internal static partial class Native
[DefaultDllImportSearchPaths(DllImportSearchPath.SafeDirectories)]
[return: MarshalAs(UnmanagedType.U1)]
internal static partial bool SDL_WaitEventTimeout(out Event e, int timeout);

[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.U1)]
internal delegate bool EventFilter(nint userdata, ref Event e);
}