Skip to content
Open
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
27 changes: 27 additions & 0 deletions Modules/Orama.Input/Bindings/GamepadButtonBinding.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// This file is part of the Orama Game Engine.
// Licensed under the MIT license. (https://github.com/Orama-Engine/Orama/blob/main/LICENSE)

using Orama.Common;
using Orama.Input.Devices;

namespace Orama.Input.Bindings;

public class GamepadButtonBinding : IInputBinding
{
Gamepad.Button Button { get; set; }

public GamepadButtonBinding(Gamepad.Button button)
{
Button = button;
}

public float Read()
{
var input = ModuleManager.GetModule<InputModule>();

if (input == null || input.PrimaryGamepad == null)
return 0f;

return input.PrimaryGamepad.IsButtonPressed(Button) ? 1f : 0f;
}
}
13 changes: 13 additions & 0 deletions Modules/Orama.Input/Bindings/IInputBinding.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// This file is part of the Orama Game Engine.
// Licensed under the MIT license. (https://github.com/Orama-Engine/Orama/blob/main/LICENSE)

namespace Orama.Input.Bindings;

/// <summary>
/// A single physical input source that can drive an <see cref="InputAction"/>.
/// </summary>
public interface IInputBinding
{
/// <summary> Reads the current value of this binding. </summary>
public float Read();
}
27 changes: 27 additions & 0 deletions Modules/Orama.Input/Bindings/KeyBinding.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// This file is part of the Orama Game Engine.
// Licensed under the MIT license. (https://github.com/Orama-Engine/Orama/blob/main/LICENSE)

using Orama.Common;
using Orama.Input.Devices;

namespace Orama.Input.Bindings;

public class KeyBinding : IInputBinding
{
Keyboard.Key Key { get; set; }

public KeyBinding(Keyboard.Key key)
{
Key = key;
}

public float Read()
{
var input = ModuleManager.GetModule<InputModule>();

if (input == null || input.PrimaryKeyboard == null)
return 0f;

return input.PrimaryKeyboard.IsKeyDown(Key) ? 1f : 0f;
}
}
27 changes: 27 additions & 0 deletions Modules/Orama.Input/Bindings/MouseButtonBinding.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// This file is part of the Orama Game Engine.
// Licensed under the MIT license. (https://github.com/Orama-Engine/Orama/blob/main/LICENSE)

using Orama.Common;
using Orama.Input.Devices;

namespace Orama.Input.Bindings;

public class MouseButtonBinding : IInputBinding
{
Mouse.Button Button { get; set; }

public MouseButtonBinding(Mouse.Button button)
{
Button = button;
}

public float Read()
{
var input = ModuleManager.GetModule<InputModule>();

if (input == null || input.PrimaryMouse == null)
return 0f;

return input.PrimaryMouse.IsButtonDown(Button) ? 1f : 0f;
}
}
69 changes: 69 additions & 0 deletions Modules/Orama.Input/InputAction.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
// This file is part of the Orama Game Engine.
// Licensed under the MIT license. (https://github.com/Orama-Engine/Orama/blob/main/LICENSE)

using Orama.Input.Bindings;

namespace Orama.Input;

/// <summary>
/// A named input action resolved each frame from one or more <see cref="IInputBinding"/>s.
/// </summary>
public class InputAction
{
/// <summary> The unique name used to look this action up via <see cref="InputModule.GetAction"/>. </summary>
public string Name { get; }

/// <summary> All bindings that can drive this action's value. </summary>
public List<IInputBinding> Bindings { get; } = new();

/// <summary> The resolved value for this frame. </summary>
public float Value { get; private set; }

/// <summary> The resolved value from the previous frame. </summary>
public float PreviousValue { get; private set; }

/// <summary> True while this action's value is nonzero. </summary>
public bool IsPressed => Value != 0f;

/// <summary> Same as <see cref="IsPressed"/>, evaluated against last frame's value. </summary>
public bool WasPressed => PreviousValue != 0f;

/// <summary> True only on the frame this action goes from released to pressed. </summary>
public bool Triggered => IsPressed && !WasPressed;

/// <summary> True only on the frame this action goes from pressed to released. </summary>
public bool Released => !IsPressed && WasPressed;

public InputAction(string name)
{
Name = name;
}

public InputAction(string name, params IInputBinding[] bindings) : this(name)
{
Bindings.AddRange(bindings);
}

/// <summary> Adds a binding to this action. </summary>
public InputAction AddBinding(IInputBinding binding)
{
Bindings.Add(binding);
return this;
}

/// <summary> Re-reads all bindings and resolves this action's value for the current frame. </summary>
internal void Update()
{
PreviousValue = Value;

float value = 0f;
foreach (var binding in Bindings)
{
float bindingValue = binding.Read();
if (bindingValue != 0f)
value = bindingValue;
}

Value = value;
}
}
14 changes: 14 additions & 0 deletions Modules/Orama.Input/InputModule.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ public class InputModule : BaseModule
public Gamepad? PrimaryGamepad { get; private set; }

private readonly List<Devices.IInputDevice> devices = new();
private readonly Dictionary<string, InputAction> actions = new();

private IInputContext input = null!;

Expand All @@ -52,6 +53,16 @@ public override void Initialize()
PrimaryGamepad = devices.OfType<Gamepad>().FirstOrDefault();
}

/// <summary> Registers an <see cref="InputAction"/> so it's updated each frame and can be looked up by name. </summary>
public InputAction RegisterAction(InputAction action)
{
actions[action.Name] = action;
return action;
}

/// <summary> Gets a previously registered <see cref="InputAction"/> by name. </summary>
public InputAction GetAction(string name) => actions[name];

/// <inheritdoc/>
public override void Dispose()
{
Expand All @@ -66,5 +77,8 @@ public void Update()
{
foreach (var device in devices)
device.Update();

foreach (var action in actions.Values)
action.Update();
}
}
9 changes: 9 additions & 0 deletions Players/Orama.Players.Desktop/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
using Orama.Common.Utility;
using Orama.GUI;
using Orama.Input;
using Orama.Input.Bindings;
using Orama.Math;
using Orama.Physics;
using Orama.Rendering;
Expand Down Expand Up @@ -55,6 +56,10 @@ static void Main(string[] args)
for (int i = 0; i < 1000; i++)
OramaConsole.Log($"Logging {i} times.");

var testAction = new InputAction("TestAction");
testAction.AddBinding(new KeyBinding(Input.Devices.Keyboard.Key.Space));
testAction.AddBinding(new GamepadButtonBinding(Input.Devices.Gamepad.Button.ActionDown));
ModuleManager.GetModule<InputModule>()?.RegisterAction(testAction);

ModuleManager.GetModule<SceneModule>()?.CurrentScene.StartAll();
};
Expand All @@ -66,6 +71,10 @@ static void Main(string[] args)

Application.OnUpdate += () =>
{
var input = ModuleManager.GetModule<InputModule>();
if (input!.GetAction("TestAction").Triggered)
OramaConsole.Log("Test action triggered");


};

Expand Down