Split the platform out of Core: new Host library + HeadlessHost
CI / build-test (push) Successful in 1m24s
CI / build-test (push) Successful in 1m24s
Core now depends only on Friflo.Engine.ECS — no MonoGame, no platform. The windowed MonoGame host moves to the new MrGameEng.Host library: GameHost, GameHostOptions, visual scene transitions (OverlayTransition, Transitions.Fade/Wipe, TransitionRenderer) and the Input feature (namespace MrGameEng.Input is unchanged). Transition timing stays in Core (SceneManager exposes ActiveTransition/TransitionCoverage/ TransitionPhase; the host draws the overlay). EngineContext loses its GraphicsDevice property: hosts publish the device as a service and graphics code reads it via context.GetGraphicsDevice() in Graphics. Core gains HeadlessHost: a fixed-timestep loop without a window or GPU (Tick/RunTicks, Run with wall-clock pacing and lag resync) for dedicated servers, batch simulation and tests. Graphics and Audio now carry their own MonoGame.Framework.DesktopGL reference instead of inheriting it from Core. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
79d406a9f4
commit
2ac074004a
@@ -0,0 +1,135 @@
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Input;
|
||||
|
||||
namespace MrGameEng.Input;
|
||||
|
||||
/// <summary>Mouse buttons addressable through <see cref="InputManager"/>.</summary>
|
||||
public enum MouseButton
|
||||
{
|
||||
/// <summary>Left button.</summary>
|
||||
Left,
|
||||
|
||||
/// <summary>Right button.</summary>
|
||||
Right,
|
||||
|
||||
/// <summary>Middle button (wheel click).</summary>
|
||||
Middle,
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Polls keyboard, mouse and gamepad once per frame and keeps the previous frame's state,
|
||||
/// enabling edge queries (<c>Pressed</c> = went down this frame, <c>Released</c> = went up).
|
||||
/// Registered as a service by <c>scene.UseInput()</c>; polled by <see cref="InputSystem"/>
|
||||
/// at the start of the update phase. While <see cref="MrGameEng.Core.InputCapture.Captured"/>
|
||||
/// is set (e.g. the developer console is open), game-facing input reads as released.
|
||||
/// </summary>
|
||||
public sealed class InputManager
|
||||
{
|
||||
private readonly MrGameEng.Core.InputCapture? _capture;
|
||||
|
||||
private KeyboardState _keyboard;
|
||||
private KeyboardState _previousKeyboard;
|
||||
private MouseState _mouse;
|
||||
private MouseState _previousMouse;
|
||||
private GamePadState _gamePad;
|
||||
private GamePadState _previousGamePad;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a manager. With a <paramref name="capture"/>, input is suppressed while a UI
|
||||
/// overlay holds it (keys/buttons read as released, mouse position and wheel freeze).
|
||||
/// </summary>
|
||||
public InputManager(MrGameEng.Core.InputCapture? capture = null) => _capture = capture;
|
||||
|
||||
/// <summary>Polls all devices. Called once per frame by <see cref="InputSystem"/>.</summary>
|
||||
public void Update()
|
||||
{
|
||||
if (_capture?.Captured == true)
|
||||
{
|
||||
// Оверлей (консоль) захватил ввод: клавиши и кнопки считаются отпущенными,
|
||||
// позиция мыши и счётчик колеса замораживаются — все дельты нулевые.
|
||||
Apply(
|
||||
default,
|
||||
new MouseState(
|
||||
_mouse.X,
|
||||
_mouse.Y,
|
||||
_mouse.ScrollWheelValue,
|
||||
ButtonState.Released,
|
||||
ButtonState.Released,
|
||||
ButtonState.Released,
|
||||
ButtonState.Released,
|
||||
ButtonState.Released
|
||||
),
|
||||
default
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
Apply(Keyboard.GetState(), Mouse.GetState(), GamePad.GetState(PlayerIndex.One));
|
||||
}
|
||||
|
||||
internal void Apply(KeyboardState keyboard, MouseState mouse, GamePadState gamePad)
|
||||
{
|
||||
_previousKeyboard = _keyboard;
|
||||
_previousMouse = _mouse;
|
||||
_previousGamePad = _gamePad;
|
||||
_keyboard = keyboard;
|
||||
_mouse = mouse;
|
||||
_gamePad = gamePad;
|
||||
}
|
||||
|
||||
/// <summary>True while the key is held down.</summary>
|
||||
public bool IsKeyDown(Keys key) => _keyboard.IsKeyDown(key);
|
||||
|
||||
/// <summary>True only on the frame the key went down.</summary>
|
||||
public bool IsKeyPressed(Keys key) =>
|
||||
_keyboard.IsKeyDown(key) && _previousKeyboard.IsKeyUp(key);
|
||||
|
||||
/// <summary>True only on the frame the key went up.</summary>
|
||||
public bool IsKeyReleased(Keys key) =>
|
||||
_keyboard.IsKeyUp(key) && _previousKeyboard.IsKeyDown(key);
|
||||
|
||||
/// <summary>Mouse cursor position in window pixels.</summary>
|
||||
public Point MousePosition => _mouse.Position;
|
||||
|
||||
/// <summary>Cursor movement since the previous frame.</summary>
|
||||
public Point MouseDelta => _mouse.Position - _previousMouse.Position;
|
||||
|
||||
/// <summary>Scroll wheel change since the previous frame (positive = up).</summary>
|
||||
public int WheelDelta => _mouse.ScrollWheelValue - _previousMouse.ScrollWheelValue;
|
||||
|
||||
/// <summary>True while the mouse button is held down.</summary>
|
||||
public bool IsMouseDown(MouseButton button) => GetButton(_mouse, button) == ButtonState.Pressed;
|
||||
|
||||
/// <summary>True only on the frame the mouse button went down.</summary>
|
||||
public bool IsMousePressed(MouseButton button) =>
|
||||
GetButton(_mouse, button) == ButtonState.Pressed
|
||||
&& GetButton(_previousMouse, button) == ButtonState.Released;
|
||||
|
||||
/// <summary>True only on the frame the mouse button went up.</summary>
|
||||
public bool IsMouseReleased(MouseButton button) =>
|
||||
GetButton(_mouse, button) == ButtonState.Released
|
||||
&& GetButton(_previousMouse, button) == ButtonState.Pressed;
|
||||
|
||||
/// <summary>True while the gamepad button is held down.</summary>
|
||||
public bool IsButtonDown(Buttons button) => _gamePad.IsButtonDown(button);
|
||||
|
||||
/// <summary>True only on the frame the gamepad button went down.</summary>
|
||||
public bool IsButtonPressed(Buttons button) =>
|
||||
_gamePad.IsButtonDown(button) && _previousGamePad.IsButtonUp(button);
|
||||
|
||||
/// <summary>True only on the frame the gamepad button went up.</summary>
|
||||
public bool IsButtonReleased(Buttons button) =>
|
||||
_gamePad.IsButtonUp(button) && _previousGamePad.IsButtonDown(button);
|
||||
|
||||
/// <summary>Left thumbstick, x/y in [-1, 1]. Y is inverted to match the engine's y-down world.</summary>
|
||||
public Vector2 LeftStick => new(_gamePad.ThumbSticks.Left.X, -_gamePad.ThumbSticks.Left.Y);
|
||||
|
||||
private static ButtonState GetButton(in MouseState state, MouseButton button) =>
|
||||
button switch
|
||||
{
|
||||
MouseButton.Left => state.LeftButton,
|
||||
MouseButton.Right => state.RightButton,
|
||||
MouseButton.Middle => state.MiddleButton,
|
||||
_ => ButtonState.Released,
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user