From 13f69a08564327c988229a81fecfd1ad1d143df8 Mon Sep 17 00:00:00 2001 From: copygirl Date: Tue, 3 Jan 2023 11:38:49 +0100 Subject: [PATCH] Remove ProxyAttribute --- src/gaemstone.Client/Systems/ImGuiManager.cs | 14 ++-- src/gaemstone.Client/Systems/InputManager.cs | 83 ++++++++++---------- src/gaemstone/ECS/Attributes.cs | 15 ---- src/gaemstone/Universe+Modules.cs | 16 ++-- 4 files changed, 56 insertions(+), 72 deletions(-) diff --git a/src/gaemstone.Client/Systems/ImGuiManager.cs b/src/gaemstone.Client/Systems/ImGuiManager.cs index f423405..7d45a8c 100644 --- a/src/gaemstone.Client/Systems/ImGuiManager.cs +++ b/src/gaemstone.Client/Systems/ImGuiManager.cs @@ -10,6 +10,7 @@ using ImGuiNET; using Silk.NET.Input; using Silk.NET.OpenGL.Extensions.ImGui; using static gaemstone.Client.Components.InputComponents; +using static gaemstone.Client.Systems.InputManager; using static gaemstone.Client.Systems.Windowing; namespace gaemstone.Client.Systems; @@ -85,9 +86,9 @@ public class ImGuiManager [System] public unsafe void Initialize(Universe universe, GameWindow window, Canvas canvas, - [Source] IInputContext inputContext, [Not] ImGuiData _) + [Source] InputContext inputContext, [Not] ImGuiData _) => universe.LookupByTypeOrThrow().Set(new ImGuiData( - new(canvas.GL, window.Handle, inputContext, () => { + new(canvas.GL, window.Handle, inputContext.Value, () => { var io = ImGui.GetIO(); var style = ImGui.GetStyle(); @@ -140,8 +141,9 @@ public class ImGuiManager [System] public static void UpdateMouse(Universe universe, - [Source] IMouse impl, ImGuiData _) + [Source] MouseImpl impl, ImGuiData _) { + var mouse = impl.Value; var input = universe.LookupByTypeOrThrow(); var module = universe.LookupByTypeOrThrow(); var capturedBy = input.GetTargets().FirstOrDefault();; @@ -152,7 +154,7 @@ public class ImGuiManager var IO = ImGui.GetIO(); // Set the mouse position if ImGui wants to move it. - if (IO.WantSetMousePos) impl.Position = IO.MousePos; + if (IO.WantSetMousePos) mouse.Position = IO.MousePos; // Capture the mouse input it is above GUI elements. if (IO.WantCaptureMouse != isCaptured) { @@ -161,10 +163,10 @@ public class ImGuiManager } var cursor = ImGui.GetMouseCursor(); - impl.Cursor.CursorMode = (cursor == ImGuiMouseCursor.None) + mouse.Cursor.CursorMode = (cursor == ImGuiMouseCursor.None) ? CursorMode.Hidden : CursorMode.Normal; // TODO: Use additional cursors once Silk.NET supports GLFW 3.4. - impl.Cursor.StandardCursor = cursor switch { + mouse.Cursor.StandardCursor = cursor switch { ImGuiMouseCursor.Arrow => StandardCursor.Arrow, ImGuiMouseCursor.TextInput => StandardCursor.IBeam, // ImGuiMouseCursor.ResizeAll => StandardCursor., diff --git a/src/gaemstone.Client/Systems/InputManager.cs b/src/gaemstone.Client/Systems/InputManager.cs index 904c104..edce533 100644 --- a/src/gaemstone.Client/Systems/InputManager.cs +++ b/src/gaemstone.Client/Systems/InputManager.cs @@ -15,28 +15,28 @@ namespace gaemstone.Client.Systems; [DependsOn] public class InputManager { - [Component, Path("InputContext"), Proxy] public struct ContextProxy { } + [Component] public record class InputContext(IInputContext Value) { } - [Component, Path("MouseImpl" ), Proxy] public struct MouseProxy { } - [Component, Path("KeyboardImpl"), Proxy] public struct KeyboardProxy { } - [Component, Path("GamepadImpl" ), Proxy] 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] public static void Initialize(Universe universe, - [Game] GameWindow window, [Source, Not] IInputContext _) + [Game] GameWindow window, [Source, Not] InputContext _) { var input = universe.LookupByTypeOrThrow(); 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().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().Set(new GamepadImpl(gamepad)).Build(); // TODO: Should we even support joysticks? } @@ -45,53 +45,56 @@ public class InputManager [Observer] [Expression("CursorCapturedBy(Input, *)")] public static void OnCursorCaptured(Universe universe) - => universe.LookupByTypeOrThrow().GetOrThrow() - .Cursor.CursorMode = CursorMode.Raw; + => universe.LookupByTypeOrThrow().GetOrThrow() + .Value.Cursor.CursorMode = CursorMode.Raw; [Observer] [Expression("CursorCapturedBy(Input, *)")] public static void OnCursorReleased(Universe universe) - => universe.LookupByTypeOrThrow().GetOrThrow() - .Cursor.CursorMode = CursorMode.Normal; + => universe.LookupByTypeOrThrow().GetOrThrow() + .Value.Cursor.CursorMode = CursorMode.Normal; [System] - 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(); - ref var position = ref mouse.NewChild("Position").Build().GetMut(); - ref var posDelta = ref mouse.NewChild("Delta" ).Build().GetMut(); - 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(); + ref var position = ref entity.NewChild("Position").Build().GetMut(); + ref var posDelta = ref entity.NewChild("Delta" ).Build().GetMut(); + 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] - 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] - 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)); } diff --git a/src/gaemstone/ECS/Attributes.cs b/src/gaemstone/ECS/Attributes.cs index 3ccf709..abeb0fa 100644 --- a/src/gaemstone/ECS/Attributes.cs +++ b/src/gaemstone/ECS/Attributes.cs @@ -45,14 +45,6 @@ public class SymbolAttribute : Attribute, ICreateEntityAttribute public class SingletonAttribute : Attribute, ICreateEntityAttribute { public bool AutoAdd { get; init; } = true; } -/// -/// Register the proxied type instead of the one marked with this attribute. -/// This can be used to make types not registered in a module available, -/// including types registered in other assemblies. -/// -public class ProxyAttribute : ProxyAttribute - { public ProxyAttribute() : base(typeof(T)) { } } - /// /// Marked entity automatically has the specified entity added to it when @@ -112,13 +104,6 @@ public class WithAttribute : AddAttribute { } // Base attributes for other attributes. -[AttributeUsage(AttributeTargets.Struct)] -public class ProxyAttribute : Attribute -{ - public Type Type { get; } - internal ProxyAttribute(Type type) => Type = type; -} - [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum, AllowMultiple = true)] public class AddEntityAttribute : Attribute { diff --git a/src/gaemstone/Universe+Modules.cs b/src/gaemstone/Universe+Modules.cs index 641108d..bb64a1b 100644 --- a/src/gaemstone/Universe+Modules.cs +++ b/src/gaemstone/Universe+Modules.cs @@ -183,16 +183,10 @@ public class ModuleManager { if (!type.GetCustomAttributes(true).OfType().Any()) return; - // If proxied type is specified, use it instead of the marked type. - // Attributes are still read from the original type. - var proxyType = type.Get()?.Type ?? type; + if (!type.Has() && (!type.IsValueType || (type.GetFields().Length > 0))) + throw new Exception($"Type {type} must be an empty, used-defined struct."); - if (!type.Has() && (!proxyType.IsValueType || (proxyType.GetFields().Length > 0))) { - var typeHint = (proxyType != type) ? $"{proxyType.Name} (proxied by {type})" : type.ToString(); - throw new Exception($"Type {typeHint} must be an empty, used-defined struct."); - } - - var path = EntityPath.Parse(type.Get()?.Value ?? proxyType.Name); + var path = EntityPath.Parse(type.Get()?.Value ?? type.Name); var builder = path.IsAbsolute ? Universe.New(path) : Entity.NewChild(path); if (type.Get() is SymbolAttribute symbolAttr) @@ -208,8 +202,8 @@ public class ModuleManager entity.Add(Lookup(attr.Relation), Lookup(attr.Target)); if (type.Get()?.AutoAdd == true) entity.Add(entity); - if (type.Has()) entity.InitComponent(proxyType); - else entity.CreateLookup(proxyType); + if (type.Has()) entity.InitComponent(type); + else entity.CreateLookup(type); if (type.Has()) entity.Add(); if (type.Has()) entity.Add(); }