Skip to content

Commit 4888320

Browse files
committed
Finish documenting API & split out files
1 parent f5b5f1c commit 4888320

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

57 files changed

+2510
-1157
lines changed

sources/Input/Input/Button.cs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
namespace Silk.NET.Input;
2+
3+
/// <summary>
4+
/// Represents a button the user can push.
5+
/// </summary>
6+
/// <param name="Name">The name of the button.</param>
7+
/// <param name="IsDown">Whether the user is pushing the button.</param>
8+
/// <param name="Pressure">
9+
/// The pressure with which the user is pushing the button, where <c>0.0</c> is the smallest measurable pressure and
10+
/// <c>1.0</c> is the largest measurable pressure.
11+
/// </param>
12+
/// <typeparam name="T">
13+
/// The button type (e.g. <see cref="JoystickButton"/>, <see cref="PointerButton"/>, etc).
14+
/// </typeparam>
15+
public readonly record struct Button<T>(T Name, bool IsDown, float Pressure) where T : struct, Enum
16+
{
17+
/// <summary>
18+
/// Collapses this <see cref="Button{T}"/> struct into just its <see cref="IsDown"/> value.
19+
/// </summary>
20+
/// <param name="state">The button state.</param>
21+
/// <returns>The <see cref="IsDown"/> value.</returns>
22+
public static implicit operator bool(Button<T> state) => state.IsDown;
23+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
using System.Diagnostics;
2+
3+
namespace Silk.NET.Input;
4+
5+
/// <summary>
6+
/// Contains information pertaining to a button state change (e.g. press, depress, etc).
7+
/// </summary>
8+
/// <param name="Device">The device on which the button being pressed or depressed resides.</param>
9+
/// <param name="Timestamp">
10+
/// The timestamp (as retrieved from <see cref="Stopwatch.GetTimestamp"/>) at which the event occurred.
11+
/// </param>
12+
/// <param name="Button">The new state of the button being pressed or depressed.</param>
13+
/// <param name="Previous">The previous state of the button.</param>
14+
/// <typeparam name="T">The button type e.g. <see cref="JoystickButton"/>, <see cref="PointerButton"/>, etc.</typeparam>
15+
public readonly record struct ButtonChangedEvent<T>(IButtonDevice<T> Device, long Timestamp, Button<T> Button, Button<T> Previous) where T : struct, Enum;
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
namespace Silk.NET.Input;
2+
3+
/// <summary>
4+
/// An implementation of <see cref="IReadOnlyList{T}"/> providing utility APIs for getting a <see cref="Button{T}"/>
5+
/// given a button name <typeparamref name="T"/>, that is optimised for storing <see cref="Button{T}"/>s with the
6+
/// given button name type <typeparamref name="T"/> using the most memory-efficient mechanism available.
7+
/// </summary>
8+
/// <typeparam name="T">
9+
/// The button type (e.g. <see cref="JoystickButton"/>, <see cref="PointerButton"/>, etc).
10+
/// </typeparam>
11+
public struct ButtonReadOnlyList<T> : IReadOnlyList<Button<T>> where T : struct, Enum
12+
{
13+
/// <summary>
14+
/// Creates an <see cref="ButtonReadOnlyList{T}"/> from a <see cref="IReadOnlyList{T}"/>.
15+
/// </summary>
16+
/// <param name="other">The list to copy.</param>
17+
public ButtonReadOnlyList(IReadOnlyList<Button<T>> other);
18+
19+
/// <summary>
20+
/// Gets the state for the button with the given name.
21+
/// </summary>
22+
/// <param name="name">The button name.</param>
23+
public Button<T> this[T name] { get; }
24+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
using System.Diagnostics;
2+
3+
namespace Silk.NET.Input;
4+
5+
/// <summary>
6+
/// Contains information pertaining to a device connection or disconnection event.
7+
/// </summary>
8+
/// <param name="Device">The device that has disconnected or connected.</param>
9+
/// <param name="Timestamp">
10+
/// The timestamp (as retrieved from <see cref="Stopwatch.GetTimestamp"/>) at which the event occurred.
11+
/// </param>
12+
/// <param name="IsConnected">Whether the device has connected (<c>true</c>) or disconnected (<c>false</c>).</param>
13+
public readonly record struct ConnectionEvent(IInputDevice Device, long Timestamp, bool IsConnected);

sources/Input/Input/CursorModes.cs

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
namespace Silk.NET.Input;
2+
3+
/// <summary>
4+
/// Enumerates the modes in which a mouse cursor can operate.
5+
/// </summary>
6+
/// <remarks>
7+
/// <see cref="IPointerDevice"/> implementations for <see cref="IMouse"/> implementations typically have two
8+
/// <see cref="IPointerDevice.Targets"/>:
9+
/// <list type="bullet">
10+
/// <item>
11+
/// <term>Bounded <see cref="IPointerTarget"/></term>
12+
/// <description>
13+
/// An <see cref="IPointerTarget"/> that is bounded to the desktop environment i.e. the
14+
/// <see cref="IPointerTarget.Bounds"/> are not infinite and reflect the total screen space that is available to the
15+
/// running application in window coordinates. This is typically the sum of all monitor resolutions, with the positions
16+
/// being defined using an implementation-defined mechanism. The window bounds operate in this same coordinate space.
17+
/// It is highly unlikely that you will be unable to determine the individual points for multiple mice on this target,
18+
/// as desktop environments typically aggregate all movement from all mice into a single <see cref="TargetPoint"/>.
19+
/// This target is used for every cursor mode except <see cref="Unbounded"/>.
20+
/// </description>
21+
/// </item>
22+
/// <item>
23+
/// <term>Unbounded <see cref="IPointerTarget"/></term>
24+
/// <description>
25+
/// An <see cref="IPointerTarget"/> that is unbounded and operates in an arbitrary coordinate space. This target is used
26+
/// for <b>raw mouse mode</b> and points on this target represent the net mouse movement from a mouse. Implementations
27+
/// are more likely to be able to give multiple <see cref="TargetPoint"/>s for each mouse when this target is used. This
28+
/// target is used when the <see cref="Unbounded"/> cursor mode is enabled. <see cref="IPointerTarget.Bounds"/> will
29+
/// represent an infinitely large unbounded target.
30+
/// </description>
31+
/// </item>
32+
/// </list>
33+
/// </remarks>
34+
[Flags]
35+
public enum CursorModes
36+
{
37+
/// <summary>
38+
/// The cursor is visible to the user and operating within the bounds of the <b>desktop environment</b>. The
39+
/// coordinates received are in desktop coordinates, operating in the same coordinate space as the window
40+
/// position/size.
41+
/// </summary>
42+
Normal = 1 << 0,
43+
44+
/// <summary>
45+
/// The cursor is visible to the user but is constrained to the <b>window's client area</b>. The coordinates
46+
/// received are in desktop coordinates, operating in the same coordinate space as the window position/size.
47+
/// The <see cref="IPointerTarget"/> bounded to the desktop environment is used.
48+
/// </summary>
49+
Confined = 1 << 1,
50+
51+
/// <summary>
52+
/// The cursor is invisible to the user and is <b>unconstrained/unbounded</b>. The coordinates received are
53+
/// arbitrary values that have no bounds representing the net mouse movement since entering into this cursor mode.
54+
/// The unbounded <see cref="IPointerTarget"/> is used. This is the equivalent of <b>raw mouse mode</b>.
55+
/// </summary>
56+
Unbounded = 1 << 2,
57+
}

sources/Input/Input/CursorStyles.cs

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
namespace Silk.NET.Input;
2+
3+
/// <summary>
4+
/// Enumerates the cursor styles with which the desktop environment should render the cursor.
5+
/// </summary>
6+
[Flags]
7+
public enum CursorStyles
8+
{
9+
/// <summary>
10+
/// The cursor should be rendered using its default image.
11+
/// </summary>
12+
Default,
13+
14+
/// <summary>
15+
/// The cursor should be rendered using an arrow cursor image.
16+
/// </summary>
17+
Arrow = 1 << 0,
18+
19+
/// <summary>
20+
/// The cursor should be rendered using an I-beam cursor image, which is used to show where the text cursor appears
21+
/// when the mouse is clicked.
22+
/// </summary>
23+
IBeam = 1 << 1,
24+
25+
/// <summary>
26+
/// The cursor should be rendered using a crosshair cursor image.
27+
/// </summary>
28+
Crosshair = 1 << 2,
29+
30+
/// <summary>
31+
/// The cursor should be rendered using a hand cursor image, typically used when hovering over a web link.
32+
/// </summary>
33+
Hand = 1 << 3,
34+
35+
/// <summary>
36+
/// The cursor should be rendered using a two-headed horizontal sizing cursor image.
37+
/// </summary>
38+
HResize = 1 << 4,
39+
40+
/// <summary>
41+
/// The cursor should be rendered using a two-headed vertical sizing cursor image.
42+
/// </summary>
43+
VResize = 1 << 5,
44+
45+
/// <summary>
46+
/// The cursor should not be rendered.
47+
/// </summary>
48+
/// <remarks>
49+
/// When <see cref="CursorModes.Unbounded"/> is used, the cursor ceases to exist anyway. As such, while the
50+
/// <see cref="ICursorConfiguration.Style"/> property may not reflect this (as it is retained across changes to
51+
/// <see cref="ICursorConfiguration.Mode"/> and just ignored when <see cref="CursorModes.Unbounded"/> is used),
52+
/// <see cref="ICursorConfiguration.Style"/> can be implied as being <see cref="CursorStyles.Hidden"/> when
53+
/// <see cref="CursorModes.Unbounded"/> is used.
54+
/// </remarks>
55+
Hidden = 1 << 6,
56+
57+
/// <summary>
58+
/// The cursor should be rendered using a custom application-provided image.
59+
/// </summary>
60+
Custom = 1 << 7,
61+
}

sources/Input/Input/CustomCursor.cs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
namespace Silk.NET.Input;
2+
3+
/// <summary>
4+
/// Represents a custom image for a mouse cursor.
5+
/// </summary>
6+
public readonly ref struct CustomCursor
7+
{
8+
/// <summary>
9+
/// The number of pixels in the X axis.
10+
/// </summary>
11+
public int Width { get; init; }
12+
13+
/// <summary>
14+
/// The number of pixels in the Y axis.
15+
/// </summary>
16+
public int Height { get; init; }
17+
18+
/// <summary>
19+
/// The row-major 32-bit RGBA pixel data (i.e. 8 bytes for each colour component).
20+
/// </summary>
21+
public ReadOnlySpan<int> Data { get; init; } // Rgba32
22+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
using System.Collections;
2+
3+
namespace Silk.NET.Input;
4+
5+
/// <summary>
6+
/// Represents a list that has exactly two elements.
7+
/// </summary>
8+
/// <typeparam name="T">The element type.</typeparam>
9+
public readonly struct DualReadOnlyList<T> : IReadOnlyList<T>
10+
{
11+
/// <summary>
12+
/// The first/leftmost element.
13+
/// </summary>
14+
public readonly T Left;
15+
16+
/// <summary>
17+
/// The second/rightmost element.
18+
/// </summary>
19+
public readonly T Right;
20+
21+
/// <inheritdoc />
22+
public IEnumerator<T> GetEnumerator()
23+
{
24+
yield return Left;
25+
yield return Right;
26+
}
27+
28+
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
29+
30+
/// <inheritdoc />
31+
public int Count => 2;
32+
33+
/// <inheritdoc />
34+
public T this[int index] => index switch {
35+
0 => Left,
36+
1 => Right,
37+
_ => throw new IndexOutOfRangeException()
38+
};
39+
}

sources/Input/Input/GamepadState.cs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
using System.Numerics;
2+
3+
namespace Silk.NET.Input;
4+
5+
/// <summary>
6+
/// Contains user input received from an <see cref="IGamepad"/>.
7+
/// </summary>
8+
public class GamepadState
9+
{
10+
/// <summary>
11+
/// Gets the gamepad button state denoting the buttons being pressed or depressed.
12+
/// </summary>
13+
public ButtonReadOnlyList<JoystickButton> Buttons { get; }
14+
15+
/// <summary>
16+
/// Gets the state of the twin sticks on the gamepad.
17+
/// </summary>
18+
public DualReadOnlyList<Vector2> Thumbsticks { get; }
19+
20+
/// <summary>
21+
/// Gets the state of the triggers on the gamepad.
22+
/// </summary>
23+
public DualReadOnlyList<float> Triggers { get; }
24+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
using System.Diagnostics;
2+
using System.Numerics;
3+
4+
namespace Silk.NET.Input;
5+
6+
/// <summary>
7+
/// Contains information pertaining to the movement of a thumbstick.
8+
/// </summary>
9+
/// <param name="Gamepad">The gamepad on which the thumbstick resides.</param>
10+
/// <param name="Timestamp">
11+
/// The timestamp (as retrieved from <see cref="Stopwatch.GetTimestamp"/>) at which the event occurred.
12+
/// </param>
13+
/// <param name="Value">
14+
/// The new position of the thumbstick, where each axis is between <c>-1.0</c> and <c>1.0</c>.
15+
/// </param>
16+
/// <param name="Delta">The change in <see cref="Value"/> as a result of this event.</param>
17+
public readonly record struct GamepadThumbstickMoveEvent(IGamepad Gamepad, long Timestamp, Vector2 Value, Vector2 Delta);
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
using System.Diagnostics;
2+
3+
namespace Silk.NET.Input;
4+
5+
/// <summary>
6+
/// Contains information pertaining to the movement of a trigger.
7+
/// </summary>
8+
/// <param name="Gamepad">The gamepad on which the trigger resides.</param>
9+
/// <param name="Timestamp">
10+
/// The timestamp (as retrieved from <see cref="Stopwatch.GetTimestamp"/>) at which the event occurred.
11+
/// </param>
12+
/// <param name="Axis">The index of the trigger that has moved.</param>
13+
/// <param name="Value">
14+
/// The new value of the trigger, between <c>0.0</c> (fully depressed) and <c>1.0</c> (fully pressed).
15+
/// </param>
16+
/// <param name="Delta">The change in <see cref="Value"/> as a result of this event.</param>
17+
public readonly record struct GamepadTriggerMoveEvent(IGamepad Gamepad, long Timestamp, int Axis, float Value, float Delta);

sources/Input/Input/Gamepads.cs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
namespace Silk.NET.Input;
2+
3+
/// <summary>
4+
/// Represents a collection of <see cref="IGamepad"/>s from which input events can be received.
5+
/// </summary>
6+
public partial class Gamepads : IReadOnlyList<IGamepad>
7+
{
8+
/// <summary>
9+
/// Raised when state pertaining to a pushable button on the gamepad changes (e.g. button up, button down).
10+
/// </summary>
11+
public event Action<ButtonChangedEvent<JoystickButton>>? ButtonChanged;
12+
13+
/// <summary>
14+
/// Raised when a thumbstick on the gamepad moves.
15+
/// </summary>
16+
public event Action<GamepadThumbstickMoveEvent>? ThumbstickMove;
17+
18+
/// <summary>
19+
/// Raised when a trigger on the gamepad moves.
20+
/// </summary>
21+
public event Action<GamepadTriggerMoveEvent>? TriggerMove;
22+
}

sources/Input/Input/IButtonDevice.cs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
namespace Silk.NET.Input;
2+
3+
/// <summary>
4+
/// Represents an input device that has buttons.
5+
/// </summary>
6+
/// <typeparam name="T">The type of buttons the input device has.</typeparam>
7+
public interface IButtonDevice<T> : IInputDevice where T: struct, Enum
8+
{
9+
/// <summary>
10+
/// Gets the current button state for this device.
11+
/// </summary>
12+
/// <remarks>
13+
/// Only updated when <see cref="IInputBackend.Update"/> is called.
14+
/// </remarks>
15+
ButtonReadOnlyList<T> State { get; }
16+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
namespace Silk.NET.Input;
2+
3+
/// <summary>
4+
/// An <see cref="IInputHandler"/> that also receives <see cref="IButtonDevice{T}"/> events.
5+
/// </summary>
6+
/// <typeparam name="T">The device's button type.</typeparam>
7+
public interface IButtonInputHandler<T> : IInputHandler where T : struct, Enum
8+
{
9+
/// <summary>
10+
/// Called when a button's state changes (e.g. button down, button up).
11+
/// </summary>
12+
/// <param name="event">The event details.</param>
13+
void HandleButtonChanged(ButtonChangedEvent<T> @event);
14+
}

0 commit comments

Comments
 (0)