Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[3.0] Input Rewrite #2427

Draft
wants to merge 3 commits into
base: develop/3.0
Choose a base branch
from
Draft
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
5 changes: 3 additions & 2 deletions .config/dotnet-tools.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,11 @@
"isRoot": true,
"tools": {
"csharpier": {
"version": "0.29.2",
"version": "0.30.6",
"commands": [
"dotnet-csharpier"
]
],
"rollForward": false
}
}
}
20 changes: 20 additions & 0 deletions Silk.NET.sln
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,14 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Windowing", "Windowing", "{
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Silk.NET.Windowing", "sources\Windowing\Windowing\Silk.NET.Windowing.csproj", "{EF07CBB5-D253-4CA9-A5DA-8B3DF2B0DF8E}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Input", "Input", "{33ED9765-8C36-4A9D-95E8-AF037FE104B3}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Silk.NET.Input", "sources\Input\Input\Silk.NET.Input.csproj", "{49A42CE3-94C5-4239-B0FC-F1FF8D7AAADA}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Input", "Input", "{4E0EF53A-76BC-4729-8E3B-4768E86E357E}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Silk.NET.Input.UnitTests", "tests\Input\Input\Silk.NET.Input.UnitTests.csproj", "{00B9B6E6-776E-480C-B3ED-D6420C5B4E8E}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -168,6 +176,14 @@ Global
{EF07CBB5-D253-4CA9-A5DA-8B3DF2B0DF8E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{EF07CBB5-D253-4CA9-A5DA-8B3DF2B0DF8E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{EF07CBB5-D253-4CA9-A5DA-8B3DF2B0DF8E}.Release|Any CPU.Build.0 = Release|Any CPU
{49A42CE3-94C5-4239-B0FC-F1FF8D7AAADA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{49A42CE3-94C5-4239-B0FC-F1FF8D7AAADA}.Debug|Any CPU.Build.0 = Debug|Any CPU
{49A42CE3-94C5-4239-B0FC-F1FF8D7AAADA}.Release|Any CPU.ActiveCfg = Release|Any CPU
{49A42CE3-94C5-4239-B0FC-F1FF8D7AAADA}.Release|Any CPU.Build.0 = Release|Any CPU
{00B9B6E6-776E-480C-B3ED-D6420C5B4E8E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{00B9B6E6-776E-480C-B3ED-D6420C5B4E8E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{00B9B6E6-776E-480C-B3ED-D6420C5B4E8E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{00B9B6E6-776E-480C-B3ED-D6420C5B4E8E}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down Expand Up @@ -200,6 +216,10 @@ Global
{F16C0AB9-DE7E-4C09-9EE9-DAA8B8E935A6} = {EC4D7B06-D277-4411-BD7B-71A6D37683F0}
{FE4414F8-5370-445D-9F24-C3AD3223F299} = {DD29EA8F-B1A6-45AA-8D2E-B38DA56D9EF6}
{EF07CBB5-D253-4CA9-A5DA-8B3DF2B0DF8E} = {FE4414F8-5370-445D-9F24-C3AD3223F299}
{33ED9765-8C36-4A9D-95E8-AF037FE104B3} = {DD29EA8F-B1A6-45AA-8D2E-B38DA56D9EF6}
{49A42CE3-94C5-4239-B0FC-F1FF8D7AAADA} = {33ED9765-8C36-4A9D-95E8-AF037FE104B3}
{4E0EF53A-76BC-4729-8E3B-4768E86E357E} = {A5578D12-9E77-4647-8C22-0DBD17760BFF}
{00B9B6E6-776E-480C-B3ED-D6420C5B4E8E} = {4E0EF53A-76BC-4729-8E3B-4768E86E357E}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {78D2CF6A-60A1-43E3-837B-00B73C9DA384}
Expand Down
21 changes: 21 additions & 0 deletions docs/silk.net/diagnostics/ST0001.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# ST0001 - ProcessClass failure

## Overview

This internal error was raised by SilkTouch when failing to generate an implementation for a binding at source
generation time. It provided details regarding the exception that led to the entire native API class failing to have its
implementation generated.

| Attribute | Value |
|--------------------|----------------------|
| Diagnostic ID | ST0001 |
| Title | ProcessClass failure |
| Category | SilkTouch.Internal |
| Default Severity | Error |
| Enabled by Default | Yes |

Example message: `ProcessClass failed. Exception: '...'`

## Explanation & Solutions

This functionality is no longer supported in 3.0, where this diagnostic is never raised.
21 changes: 21 additions & 0 deletions docs/silk.net/diagnostics/ST0002.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# ST0002 - MethodClass failure

## Overview

This internal error was raised by SilkTouch when failing to generate an implementation for a binding at source
generation time. It provided details regarding the exception that led to a specific native API method failing to have
its implementation generated.

| Attribute | Value |
|--------------------|---------------------|
| Diagnostic ID | ST0002 |
| Title | MethodClass failure |
| Category | SilkTouch.Internal |
| Default Severity | Error |
| Enabled by Default | Yes |

Example message: `MethodClass failed. Exception: '...'`

## Explanation & Solutions

This functionality is no longer supported in 3.0, where this diagnostic is never raised.
20 changes: 20 additions & 0 deletions docs/silk.net/diagnostics/ST0003.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# ST0003 - Silk.NET.Core is Missing

## Overview

This internal diagnostic was raised by SilkTouch when failing to generate an implementation for bindings at source
generation time due to the binding project missing a reference to Silk.NET.Core.

| Attribute | Value |
|--------------------|---------------------|
| Diagnostic ID | ST0003 |
| Title | MethodClass failure |
| Category | SilkTouch.Internal |
| Default Severity | Info |
| Enabled by Default | Yes |

Example message: `Silk.NET.Core is missing from references. You should use SilkTouch with Silk.NET.Core`

## Explanation & Solutions

This functionality is no longer supported in 3.0, where this diagnostic is never raised.
20 changes: 20 additions & 0 deletions docs/silk.net/diagnostics/ST0004.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# ST0004 - Build Info

## Overview

This internal diagnostic was raised by SilkTouch when configured to do so. It provided diagnostic information relating
to the performance and characteristics of SilkTouch's internals.

| Attribute | Value |
|--------------------|--------------------|
| Diagnostic ID | ST0004 |
| Title | Build Info |
| Category | SilkTouch.Internal |
| Default Severity | Warning |
| Enabled by Default | Yes |

Example message: `GCSlotCount: '127'. Time: '6437ms'`

## Explanation & Solutions

This functionality is no longer supported in 3.0, where this diagnostic is never raised.
15 changes: 15 additions & 0 deletions docs/silk.net/diagnostics/ST0005.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# ST0005 - Intentionally Unstable API

## Overview

This diagnostic is raised when trying to use a Silk.NET API that has been marked with the `Experimental` attribute due
to its API and/or ABI being unstable. When this diagnostic ID is used, it indicates that it is intentional that this is
the case and that this API is extremely unlikely to ever graduate to a stable, versioned API.

## Explanation & Solutions

Typically, APIs meeting this description are internal APIs and are not intended for use outside of the assembly they're
defined in. As a result, where this diagnostic is raised, you should cease use of this API or at least only continue if
you can guarantee that you will never update Silk.NET ever again and that your downstream consumers, if applicable, will
lock their version to the same version referenced by your project. However, please reconsider use of the API if this is
the case.
6 changes: 6 additions & 0 deletions eng/build/Silk.NET.NUKE.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,10 @@
<PackageReference Include="Octokit" Version="13.0.1" />
<PackageReference Include="System.Linq.Async" Version="6.0.1" />
</ItemGroup>

<ItemGroup>
<Content Include="..\..\tests\Input\Input\Silk.NET.Input.UnitTests.csproj">
<Link>Directory.Build\tests\Input\Input\Silk.NET.Input.UnitTests.csproj</Link>
</Content>
</ItemGroup>
</Project>
24 changes: 24 additions & 0 deletions sources/Input/Input/Button.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
namespace Silk.NET.Input;

/// <summary>
/// Represents a button the user can push.
/// </summary>
/// <param name="Name">The name of the button.</param>
/// <param name="IsDown">Whether the user is pushing the button.</param>
/// <param name="Pressure">
/// The pressure with which the user is pushing the button, where <c>0.0</c> is the smallest measurable pressure and
/// <c>1.0</c> is the largest measurable pressure.
/// </param>
/// <typeparam name="T">
/// The button type (e.g. <see cref="JoystickButton"/>, <see cref="PointerButton"/>, etc).
/// </typeparam>
public readonly record struct Button<T>(T Name, bool IsDown, float Pressure)
where T : unmanaged, Enum
{
/// <summary>
/// Collapses this <see cref="Button{T}"/> struct into just its <see cref="IsDown"/> value.
/// </summary>
/// <param name="state">The button state.</param>
/// <returns>The <see cref="IsDown"/> value.</returns>
public static implicit operator bool(Button<T> state) => state.IsDown;
}
21 changes: 21 additions & 0 deletions sources/Input/Input/ButtonChangedEvent.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
using System.Diagnostics;

namespace Silk.NET.Input;

/// <summary>
/// Contains information pertaining to a button state change (e.g. press, depress, etc).
/// </summary>
/// <param name="Device">The device on which the button being pressed or depressed resides.</param>
/// <param name="Timestamp">
/// The timestamp (as retrieved from <see cref="Stopwatch.GetTimestamp"/>) at which the event occurred.
/// </param>
/// <param name="Button">The new state of the button being pressed or depressed.</param>
/// <param name="Previous">The previous state of the button.</param>
/// <typeparam name="T">The button type e.g. <see cref="JoystickButton"/>, <see cref="PointerButton"/>, etc.</typeparam>
public readonly record struct ButtonChangedEvent<T>(
IButtonDevice<T> Device,
long Timestamp,
Button<T> Button,
Button<T> Previous
)
where T : unmanaged, Enum;
43 changes: 43 additions & 0 deletions sources/Input/Input/ButtonReadOnlyList.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
using System.Collections;

namespace Silk.NET.Input;

/// <summary>
/// An implementation of <see cref="IReadOnlyList{T}"/> providing utility APIs for getting a <see cref="Button{T}"/>
/// given a button name <typeparamref name="T"/>, that is optimised for storing <see cref="Button{T}"/>s with the
/// given button name type <typeparamref name="T"/> using the most memory-efficient mechanism available.
/// </summary>
/// <typeparam name="T">
/// The button type (e.g. <see cref="JoystickButton"/>, <see cref="PointerButton"/>, etc).
/// </typeparam>
public struct ButtonReadOnlyList<T> : IReadOnlyList<Button<T>>
where T : unmanaged, Enum
{
private InputReadOnlyList<Button<T>> _list;

internal ButtonReadOnlyList(InputReadOnlyList<Button<T>> list) => _list = list;

/// <summary>
/// Creates an <see cref="ButtonReadOnlyList{T}"/> from a <see cref="IReadOnlyList{T}"/>.
/// </summary>
/// <param name="other">The list to copy.</param>
public ButtonReadOnlyList(IReadOnlyList<Button<T>> other) =>
InputMarshal.Clone(other).List.AsButtonList();

/// <summary>
/// Gets the state for the button with the given name.
/// </summary>
/// <param name="name">The button name.</param>
public Button<T> this[T name] => InputMarshal.GetButtonState(_list, name);

/// <inheritdoc />
public IEnumerator<Button<T>> GetEnumerator() => _list.GetEnumerator();

IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();

/// <inheritdoc />
public int Count => _list.Count;

/// <inheritdoc />
public Button<T> this[int index] => _list[index];
}
13 changes: 13 additions & 0 deletions sources/Input/Input/ConnectionEvent.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
using System.Diagnostics;

namespace Silk.NET.Input;

/// <summary>
/// Contains information pertaining to a device connection or disconnection event.
/// </summary>
/// <param name="Device">The device that has disconnected or connected.</param>
/// <param name="Timestamp">
/// The timestamp (as retrieved from <see cref="Stopwatch.GetTimestamp"/>) at which the event occurred.
/// </param>
/// <param name="IsConnected">Whether the device has connected (<c>true</c>) or disconnected (<c>false</c>).</param>
public readonly record struct ConnectionEvent(IInputDevice Device, long Timestamp, bool IsConnected);
57 changes: 57 additions & 0 deletions sources/Input/Input/CursorModes.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
namespace Silk.NET.Input;

/// <summary>
/// Enumerates the modes in which a mouse cursor can operate.
/// </summary>
/// <remarks>
/// <see cref="IPointerDevice"/> implementations for <see cref="IMouse"/> implementations typically have two
/// <see cref="IPointerDevice.Targets"/>:
/// <list type="bullet">
/// <item>
/// <term>Bounded <see cref="IPointerTarget"/></term>
/// <description>
/// An <see cref="IPointerTarget"/> that is bounded to the desktop environment i.e. the
/// <see cref="IPointerTarget.Bounds"/> are not infinite and reflect the total screen space that is available to the
/// running application in window coordinates. This is typically the sum of all monitor resolutions, with the positions
/// being defined using an implementation-defined mechanism. The window bounds operate in this same coordinate space.
/// It is highly unlikely that you will be unable to determine the individual points for multiple mice on this target,
/// as desktop environments typically aggregate all movement from all mice into a single <see cref="TargetPoint"/>.
/// This target is used for every cursor mode except <see cref="Unbounded"/>.
/// </description>
/// </item>
/// <item>
/// <term>Unbounded <see cref="IPointerTarget"/></term>
/// <description>
/// An <see cref="IPointerTarget"/> that is unbounded and operates in an arbitrary coordinate space. This target is used
/// for <b>raw mouse mode</b> and points on this target represent the net mouse movement from a mouse. Implementations
/// are more likely to be able to give multiple <see cref="TargetPoint"/>s for each mouse when this target is used. This
/// target is used when the <see cref="Unbounded"/> cursor mode is enabled. <see cref="IPointerTarget.Bounds"/> will
/// represent an infinitely large unbounded target.
/// </description>
/// </item>
/// </list>
/// </remarks>
[Flags]
public enum CursorModes
{
/// <summary>
/// The cursor is visible to the user and operating within the bounds of the <b>desktop environment</b>. The
/// coordinates received are in desktop coordinates, operating in the same coordinate space as the window
/// position/size.
/// </summary>
Normal = 1 << 0,

/// <summary>
/// The cursor is visible to the user but is constrained to the <b>window's client area</b>. The coordinates
/// received are in desktop coordinates, operating in the same coordinate space as the window position/size.
/// The <see cref="IPointerTarget"/> bounded to the desktop environment is used.
/// </summary>
Confined = 1 << 1,

/// <summary>
/// The cursor is invisible to the user and is <b>unconstrained/unbounded</b>. The coordinates received are
/// arbitrary values that have no bounds representing the net mouse movement since entering into this cursor mode.
/// The unbounded <see cref="IPointerTarget"/> is used. This is the equivalent of <b>raw mouse mode</b>.
/// </summary>
Unbounded = 1 << 2,
}
61 changes: 61 additions & 0 deletions sources/Input/Input/CursorStyles.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
namespace Silk.NET.Input;

/// <summary>
/// Enumerates the cursor styles with which the desktop environment should render the cursor.
/// </summary>
[Flags]
public enum CursorStyles
{
/// <summary>
/// The cursor should be rendered using its default image.
/// </summary>
Default,

/// <summary>
/// The cursor should be rendered using an arrow cursor image.
/// </summary>
Arrow = 1 << 0,

/// <summary>
/// The cursor should be rendered using an I-beam cursor image, which is used to show where the text cursor appears
/// when the mouse is clicked.
/// </summary>
IBeam = 1 << 1,

/// <summary>
/// The cursor should be rendered using a crosshair cursor image.
/// </summary>
Crosshair = 1 << 2,

/// <summary>
/// The cursor should be rendered using a hand cursor image, typically used when hovering over a web link.
/// </summary>
Hand = 1 << 3,

/// <summary>
/// The cursor should be rendered using a two-headed horizontal sizing cursor image.
/// </summary>
HResize = 1 << 4,

/// <summary>
/// The cursor should be rendered using a two-headed vertical sizing cursor image.
/// </summary>
VResize = 1 << 5,

/// <summary>
/// The cursor should not be rendered.
/// </summary>
/// <remarks>
/// When <see cref="CursorModes.Unbounded"/> is used, the cursor ceases to exist anyway. As such, while the
/// <see cref="ICursorConfiguration.Style"/> property may not reflect this (as it is retained across changes to
/// <see cref="ICursorConfiguration.Mode"/> and just ignored when <see cref="CursorModes.Unbounded"/> is used),
/// <see cref="ICursorConfiguration.Style"/> can be implied as being <see cref="CursorStyles.Hidden"/> when
/// <see cref="CursorModes.Unbounded"/> is used.
/// </remarks>
Hidden = 1 << 6,

/// <summary>
/// The cursor should be rendered using a custom application-provided image.
/// </summary>
Custom = 1 << 7,
}
Loading
Loading