|
|
|
@ -15,28 +15,28 @@ namespace gaemstone.Client.Systems; |
|
|
|
|
[DependsOn<gaemstone.Client.Systems.Windowing>] |
|
|
|
|
public class InputManager |
|
|
|
|
{ |
|
|
|
|
[Component, Path("InputContext"), Proxy<IInputContext>] public struct ContextProxy { } |
|
|
|
|
[Component] public record class InputContext(IInputContext Value) { } |
|
|
|
|
|
|
|
|
|
[Component, Path("MouseImpl" ), Proxy<IMouse >] public struct MouseProxy { } |
|
|
|
|
[Component, Path("KeyboardImpl"), Proxy<IKeyboard>] public struct KeyboardProxy { } |
|
|
|
|
[Component, Path("GamepadImpl" ), Proxy<IGamepad >] public struct GamepadProxy { } |
|
|
|
|
[Component] public record class MouseImpl(IMouse Value) { } |
|
|
|
|
[Component] public record class KeyboardImpl(IKeyboard Value) { } |
|
|
|
|
[Component] public record class GamepadImpl(IGamepad Value) { } |
|
|
|
|
|
|
|
|
|
[System<SystemPhase.OnLoad>] |
|
|
|
|
public static void Initialize(Universe universe, |
|
|
|
|
[Game] GameWindow window, [Source<Input>, Not] IInputContext _) |
|
|
|
|
[Game] GameWindow window, [Source<Input>, Not] InputContext _) |
|
|
|
|
{ |
|
|
|
|
var input = universe.LookupByTypeOrThrow<Input>(); |
|
|
|
|
var context = window.Handle.CreateInput(); |
|
|
|
|
input.Set(context); |
|
|
|
|
input.Set(new InputContext(context)); |
|
|
|
|
|
|
|
|
|
// TODO: Add device names as documentation names to these entities. |
|
|
|
|
|
|
|
|
|
foreach (var impl in context.Mice.Take(1)) |
|
|
|
|
input.LookupChildOrThrow("Mouse").Set(impl); |
|
|
|
|
foreach (var impl in context.Keyboards.Take(1)) |
|
|
|
|
input.LookupChildOrThrow("Keyboard").Set(impl); |
|
|
|
|
foreach (var impl in context.Gamepads) |
|
|
|
|
input.NewChild("Gamepad" + impl.Index).Add<Gamepad>().Set(impl).Build(); |
|
|
|
|
foreach (var mouse in context.Mice.Take(1)) |
|
|
|
|
input.LookupChildOrThrow("Mouse").Set(new MouseImpl(mouse)); |
|
|
|
|
foreach (var keyboard in context.Keyboards.Take(1)) |
|
|
|
|
input.LookupChildOrThrow("Keyboard").Set(new KeyboardImpl(keyboard)); |
|
|
|
|
foreach (var gamepad in context.Gamepads) |
|
|
|
|
input.NewChild("Gamepad" + gamepad.Index).Add<Gamepad>().Set(new GamepadImpl(gamepad)).Build(); |
|
|
|
|
|
|
|
|
|
// TODO: Should we even support joysticks? |
|
|
|
|
} |
|
|
|
@ -45,53 +45,56 @@ public class InputManager |
|
|
|
|
[Observer<ObserverEvent.OnAdd>] |
|
|
|
|
[Expression("CursorCapturedBy(Input, *)")] |
|
|
|
|
public static void OnCursorCaptured(Universe universe) |
|
|
|
|
=> universe.LookupByTypeOrThrow<Mouse>().GetOrThrow<IMouse>() |
|
|
|
|
.Cursor.CursorMode = CursorMode.Raw; |
|
|
|
|
=> universe.LookupByTypeOrThrow<Mouse>().GetOrThrow<MouseImpl>() |
|
|
|
|
.Value.Cursor.CursorMode = CursorMode.Raw; |
|
|
|
|
|
|
|
|
|
[Observer<ObserverEvent.OnRemove>] |
|
|
|
|
[Expression("CursorCapturedBy(Input, *)")] |
|
|
|
|
public static void OnCursorReleased(Universe universe) |
|
|
|
|
=> universe.LookupByTypeOrThrow<Mouse>().GetOrThrow<IMouse>() |
|
|
|
|
.Cursor.CursorMode = CursorMode.Normal; |
|
|
|
|
=> universe.LookupByTypeOrThrow<Mouse>().GetOrThrow<MouseImpl>() |
|
|
|
|
.Value.Cursor.CursorMode = CursorMode.Normal; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
[System<SystemPhase.OnLoad>] |
|
|
|
|
public static void ProcessMouse(TimeSpan delta, EntityRef mouse, IMouse impl) |
|
|
|
|
public static void ProcessMouse(TimeSpan delta, EntityRef entity, MouseImpl impl) |
|
|
|
|
{ |
|
|
|
|
var isCaptured = mouse.Parent!.Has<CursorCapturedBy, Core.Any>(); |
|
|
|
|
ref var position = ref mouse.NewChild("Position").Build().GetMut<RawValue2D>(); |
|
|
|
|
ref var posDelta = ref mouse.NewChild("Delta" ).Build().GetMut<RawValue2D>(); |
|
|
|
|
posDelta = impl.Position - position; |
|
|
|
|
if (isCaptured) impl.Position = position; |
|
|
|
|
else position = impl.Position; |
|
|
|
|
|
|
|
|
|
Update1D(delta, mouse.NewChild("Wheel").Build(), impl.ScrollWheels[0].Y); |
|
|
|
|
|
|
|
|
|
var buttons = mouse.NewChild("Buttons").Build(); |
|
|
|
|
foreach (var button in impl.SupportedButtons) |
|
|
|
|
var mouse = impl.Value; |
|
|
|
|
var isCaptured = entity.Parent!.Has<CursorCapturedBy, Core.Any>(); |
|
|
|
|
ref var position = ref entity.NewChild("Position").Build().GetMut<RawValue2D>(); |
|
|
|
|
ref var posDelta = ref entity.NewChild("Delta" ).Build().GetMut<RawValue2D>(); |
|
|
|
|
posDelta = mouse.Position - position; |
|
|
|
|
if (isCaptured) mouse.Position = position; |
|
|
|
|
else position = mouse.Position; |
|
|
|
|
|
|
|
|
|
Update1D(delta, entity.NewChild("Wheel").Build(), mouse.ScrollWheels[0].Y); |
|
|
|
|
|
|
|
|
|
var buttons = entity.NewChild("Buttons").Build(); |
|
|
|
|
foreach (var button in mouse.SupportedButtons) |
|
|
|
|
Update1D(delta, buttons.NewChild(button.ToString()).Build(), |
|
|
|
|
impl.IsButtonPressed(button) ? 1 : 0); |
|
|
|
|
mouse.IsButtonPressed(button) ? 1 : 0); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
[System<SystemPhase.OnLoad>] |
|
|
|
|
public static void ProcessKeyboard(TimeSpan delta, EntityRef keyboard, IKeyboard impl) |
|
|
|
|
public static void ProcessKeyboard(TimeSpan delta, EntityRef entity, KeyboardImpl impl) |
|
|
|
|
{ |
|
|
|
|
foreach (var key in impl.SupportedKeys) { |
|
|
|
|
var entity = keyboard.NewChild(key.ToString()).Build(); |
|
|
|
|
Update1D(delta, entity, impl.IsKeyPressed(key) ? 1 : 0); |
|
|
|
|
var keyboard = impl.Value; |
|
|
|
|
foreach (var key in keyboard.SupportedKeys) { |
|
|
|
|
var keyEntity = entity.NewChild(key.ToString()).Build(); |
|
|
|
|
Update1D(delta, keyEntity, keyboard.IsKeyPressed(key) ? 1 : 0); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
[System<SystemPhase.OnLoad>] |
|
|
|
|
public static void ProcessGamepad(TimeSpan delta, EntityRef gamepad, IGamepad impl) |
|
|
|
|
public static void ProcessGamepad(TimeSpan delta, EntityRef entity, GamepadImpl impl) |
|
|
|
|
{ |
|
|
|
|
var buttons = gamepad.NewChild("Buttons").Build(); |
|
|
|
|
foreach (var button in impl.Buttons) |
|
|
|
|
var gamepad = impl.Value; |
|
|
|
|
var buttons = entity.NewChild("Buttons").Build(); |
|
|
|
|
foreach (var button in gamepad.Buttons) |
|
|
|
|
Update1D(delta, buttons.NewChild(button.Name.ToString()).Build(), button.Pressed ? 1 : 0); |
|
|
|
|
foreach (var trigger in impl.Triggers) |
|
|
|
|
Update1D(delta, gamepad.NewChild("Trigger" + trigger.Index).Build(), trigger.Position); |
|
|
|
|
foreach (var thumbstick in impl.Thumbsticks) |
|
|
|
|
Update2D(delta, gamepad.NewChild("Thumbstick" + thumbstick.Index).Build(), new(thumbstick.X, thumbstick.Y)); |
|
|
|
|
foreach (var trigger in gamepad.Triggers) |
|
|
|
|
Update1D(delta, entity.NewChild("Trigger" + trigger.Index).Build(), trigger.Position); |
|
|
|
|
foreach (var thumbstick in gamepad.Thumbsticks) |
|
|
|
|
Update2D(delta, entity.NewChild("Thumbstick" + thumbstick.Index).Build(), new(thumbstick.X, thumbstick.Y)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|