diff --git a/Firebird2D.EventPipelines/EventArguments/FirebirdJoystickButtonEventArgs.cs b/Firebird2D.EventPipelines/EventArguments/FirebirdJoystickButtonEventArgs.cs new file mode 100644 index 0000000..e3cfce9 --- /dev/null +++ b/Firebird2D.EventPipelines/EventArguments/FirebirdJoystickButtonEventArgs.cs @@ -0,0 +1,19 @@ +using SFML.Window; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Firebird2D.EventPipelines.EventArguments +{ + public class FirebirdJoystickButtonEventArgs : JoystickButtonEventArgs + { + public InputEventType InputEventType { get; private set; } + + public FirebirdJoystickButtonEventArgs(JoystickButtonEvent e, InputEventType t) : base(e) + { + InputEventType = t; + } + } +} diff --git a/Firebird2D.EventPipelines/EventArguments/FirebirdKeyEventArgs.cs b/Firebird2D.EventPipelines/EventArguments/FirebirdKeyEventArgs.cs new file mode 100644 index 0000000..4fb0fb9 --- /dev/null +++ b/Firebird2D.EventPipelines/EventArguments/FirebirdKeyEventArgs.cs @@ -0,0 +1,19 @@ +using SFML.Window; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Firebird2D.EventPipelines.EventArguments +{ + public class FirebirdKeyEventArgs : KeyEventArgs + { + public InputEventType InputEventType { get; private set; } + + public FirebirdKeyEventArgs(KeyEvent e, InputEventType t) : base(e) + { + InputEventType = t; + } + } +} diff --git a/Firebird2D.EventPipelines/EventArguments/FirebirdMouseButtonEventArgs.cs b/Firebird2D.EventPipelines/EventArguments/FirebirdMouseButtonEventArgs.cs new file mode 100644 index 0000000..aa0fce1 --- /dev/null +++ b/Firebird2D.EventPipelines/EventArguments/FirebirdMouseButtonEventArgs.cs @@ -0,0 +1,19 @@ +using SFML.Window; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Firebird2D.EventPipelines.EventArguments +{ + public class FirebirdMouseButtonEventArgs : MouseButtonEventArgs + { + public InputEventType InputEventType { get; private set; } + + public FirebirdMouseButtonEventArgs(MouseButtonEvent e,InputEventType t) : base(e) + { + InputEventType = t; + } + } +} diff --git a/Firebird2D.EventPipelines/EventArguments/InputEventType.cs b/Firebird2D.EventPipelines/EventArguments/InputEventType.cs new file mode 100644 index 0000000..18f7e20 --- /dev/null +++ b/Firebird2D.EventPipelines/EventArguments/InputEventType.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Firebird2D.EventPipelines.EventArguments +{ + public enum InputEventType + { + Pressed = 0, + Released = 1 + } +} diff --git a/Firebird2D.EventPipelines/EventBus.cs b/Firebird2D.EventPipelines/EventBus.cs index b97210e..7838325 100644 --- a/Firebird2D.EventPipelines/EventBus.cs +++ b/Firebird2D.EventPipelines/EventBus.cs @@ -6,13 +6,26 @@ using System.Threading.Tasks; namespace Firebird2D.EventPipelines { + /// + /// EventBus manages event pipelines and allows registering callbacks (hooks) if a pipeline is not Build Yet, as well as creating, retrieving, and destroying pipelines. + /// public class EventBus { + // Dictionary that stores various pipelines for specific FirebirdEvents. + // The key is the event, and the value is the corresponding pipeline. private Dictionary pipelines = new(); + // Dictionary that stores a list of callbacks for each FirebirdEvent. + // These callbacks will be invoked when the event's pipeline is build. private Dictionary>> pendingHooks = new(); - public void OnPipelineExists(Action callback, FirebirdEvent type) + /// + /// Registers a callback (hook) for a specific event. The callback will be invoked when the pipeline for this event is built. + /// + /// The function to be called when the pipeline for the event is built. + /// The event for which the callback should be registered. + /// Thrown when the callback is null. + public void OnPipelineIsBuild(Action callback, FirebirdEvent type) { if (callback == null) throw new ArgumentNullException(nameof(callback)); @@ -25,6 +38,15 @@ namespace Firebird2D.EventPipelines hookList.Add(callback); } + /// + /// Attempts to create or retrieve a pipeline for the given event. + /// If the pipeline already exists, it is returned. + /// Otherwise, a new pipeline is created and stored. + /// + /// The event for which the pipeline should be created or retrieved. + /// The type of the arguments to be passed to the pipeline. + /// The master object used when creating the pipeline. + /// The pipeline for the given event. public I_Pipeline GetOrBuildPipeline(FirebirdEvent type, Type argsType, object master) { if (pipelines.TryGetValue(type, out var pipeline)) return pipeline; @@ -35,12 +57,24 @@ namespace Firebird2D.EventPipelines return pipelineInstance; } + /// + /// Retrieves the pipeline for an event if it exists; otherwise, returns null. + /// + /// The event for which the pipeline should be retrieved. + /// The type of the arguments for the pipeline. + /// The pipeline for the event, or null if it does not exist. public I_Pipeline? GetPipeline(FirebirdEvent type, Type argsType) { if (!pipelines.TryGetValue(type, out var pipeline)) return null; return pipeline; } + /// + /// Destroys the pipeline for an event. Only the "master" of the pipeline is allowed to destroy it. + /// + /// The event for which the pipeline should be destroyed. + /// The master object that has permission to destroy the pipeline. + /// Thrown when a non-authorized user attempts to destroy the pipeline. public void DestroyPipeline(FirebirdEvent type, object master) { if (!pipelines.ContainsKey(type)) return; diff --git a/Firebird2D.EventPipelines/Firebird2D.EventPipelines.csproj b/Firebird2D.EventPipelines/Firebird2D.EventPipelines.csproj index 1a5b4a4..fc8481e 100644 --- a/Firebird2D.EventPipelines/Firebird2D.EventPipelines.csproj +++ b/Firebird2D.EventPipelines/Firebird2D.EventPipelines.csproj @@ -10,8 +10,4 @@ - - - - diff --git a/Firebird2D.EventPipelines/I_Pipeline.cs b/Firebird2D.EventPipelines/I_Pipeline.cs index 3fda8b0..05b41e1 100644 --- a/Firebird2D.EventPipelines/I_Pipeline.cs +++ b/Firebird2D.EventPipelines/I_Pipeline.cs @@ -6,11 +6,29 @@ using System.Threading.Tasks; namespace Firebird2D.EventPipelines { + /// + /// Interface for the Firebird event Pipeline + /// public interface I_Pipeline { + /// + /// Class witch owns the Pipeline and has the right to send events or delete the pipeline + /// object PipelineMaster { get; } + /// + /// Check if no one subscribed to the event + /// bool IsEventEmpty { get; } + /// + /// Subscribe to this event Pipeline + /// + /// Handler witch should be Invoked when the event is send void Subscribe(Delegate handler); + + /// + /// Unsubscribe from this event Pipeline + /// + /// Handler witch should be removed from the Pipeline void Unsubscribe(Delegate handler); } diff --git a/Firebird2D.EventPipelines/Pipeline.cs b/Firebird2D.EventPipelines/Pipeline.cs index 244dd46..2d6156f 100644 --- a/Firebird2D.EventPipelines/Pipeline.cs +++ b/Firebird2D.EventPipelines/Pipeline.cs @@ -8,29 +8,60 @@ using System.Threading.Tasks; namespace Firebird2D.EventPipelines { + /// + /// Eventpypeline which transports an event to every Subscyber + /// + /// Event Arguments for the Pipeline event public class Pipeline : I_Pipeline where T : EventArgs { + /// + /// Class witch owns the Pipeline and has the right to send events or delete the pipeline + /// public object PipelineMaster { get; } + //EventHandler to which the subscribers subribe. private event EventHandler? OnEvent; + /// + /// Pipeline Constructor + /// + /// Every pipeline needs a Master which is able to send events or Destroy the pipeline public Pipeline(object pipelineMaster) { PipelineMaster = pipelineMaster; } + /// + /// Check if no one subscribed to the event + /// public bool IsEventEmpty { get { return OnEvent != null; } } + /// + /// Subscribe to this event Pipeline + /// + /// Handler witch should be Invoked when the event is send public void Subscribe(Delegate handler) { OnEvent += (EventHandler)handler; } + /// + /// Unsubscribe from this event Pipeline + /// + /// Handler witch should be removed from the Pipeline public void Unsubscribe(Delegate handler) { OnEvent -= (EventHandler)handler; } + /// + /// Method to send an event through the pipeline + /// + /// Sneder object must be Pipelinemaster or the Pipeline throws an exception + /// Arguments that should be sent + /// Exception when sender or arguments ar null + /// Exception wehn Arguments are not equal the Pipeline type + /// Exception when sender is not Pipeline master public void SendEvent(object sender, T args) { if (sender == null || args == null) throw new ArgumentNullException(nameof(sender)); diff --git a/Firebird2D.KeyMapper/KeyMapper.cs b/Firebird2D.KeyMapper/KeyMapper.cs index b9d9c84..f0ae915 100644 --- a/Firebird2D.KeyMapper/KeyMapper.cs +++ b/Firebird2D.KeyMapper/KeyMapper.cs @@ -1,22 +1,28 @@ -using Firebird2D.EventPipelines; -using SFML.System; +using Firebird2D.EventPipelines.EventArguments; +using Firebird2D.EventPipelines; using SFML.Window; using System.Runtime.CompilerServices; using System.Text.Json; - namespace Firebird2D.KeyMapping { + /// + /// Maps input events (keyboard, mouse, joystick) to custom Firebird events and manages their pipelines. + /// public class KeyMapper { private EventBus eventBus; + // Stores registered input events by name. private Dictionary inputEvents = []; + // Stores the expected argument type for each input event. private Dictionary eventTypes = []; + // Maps event names to FirebirdEvent identifiers. private Dictionary inputMapping = []; + // Caches active pipelines for performance. private Dictionary cachedPipelines = []; public KeyMapper(EventBus eventBus) @@ -25,31 +31,40 @@ namespace Firebird2D.KeyMapping this.eventBus = eventBus; } + /// + /// Registers an input event with its handler and links it to a FirebirdEvent. + /// public void RegisterEvent(string EventName, EventHandler handler, FirebirdEvent eventNumber) where T : EventArgs { - if (inputEvents.ContainsKey(EventName)) throw new ArgumentException($"Event {EventName} exist Already."); + if (inputEvents.ContainsKey(EventName)) + throw new ArgumentException($"Event {EventName} already exists."); + inputEvents.Add(EventName, handler); - eventTypes.Add(EventName, typeof(T)); - Map(EventName, eventNumber); } + /// + /// Maps an existing input event to a new FirebirdEvent. + /// public void Map(string EventName, FirebirdEvent eventNumber) { if (inputMapping.ContainsKey(EventName)) { RemoveMapping(EventName); inputMapping[EventName] = eventNumber; - AjustPipeline(EventName, eventNumber); } else { inputMapping.Add(EventName, eventNumber); - AjustPipeline(EventName, eventNumber); } + + AjustPipeline(EventName, eventNumber); } + /// + /// Removes the current mapping and unsubscribes from the pipeline. + /// private void RemoveMapping(string EventName) { if (!inputMapping.TryGetValue(EventName, out var firebirdEvent)) return; @@ -66,9 +81,13 @@ namespace Firebird2D.KeyMapping cachedPipelines.Remove(firebirdEvent); } } + inputMapping.Remove(EventName); } + /// + /// Creates or adjusts a pipeline to reflect current mappings. + /// private void AjustPipeline(string EventName, FirebirdEvent eventNumber) { if (!eventTypes.TryGetValue(EventName, out var type)) return; @@ -77,17 +96,23 @@ namespace Firebird2D.KeyMapping pipeline.Subscribe(inputEvents[EventName]); } + /// + /// Serializes and saves the current mapping to a file. + /// public void SaveMapping(string Path) { string json = JsonSerializer.Serialize(inputMapping); File.WriteAllText(Path, json); } + /// + /// Loads and applies an input mapping from a JSON file. + /// public void LoadMapping(string Path) { string json = File.ReadAllText(Path); Dictionary? keyValuePairs = JsonSerializer.Deserialize>(json); - if (keyValuePairs == null) throw new FileLoadException("Unable to deserialize Inputmapping"); + if (keyValuePairs == null) throw new FileLoadException("Unable to deserialize input mapping."); cachedPipelines.Clear(); @@ -95,7 +120,7 @@ namespace Firebird2D.KeyMapping { RemoveMapping(kvp.Key); } - + inputMapping = keyValuePairs; foreach (var kvp in inputMapping) @@ -107,12 +132,17 @@ namespace Firebird2D.KeyMapping } } + /// + /// Removes a pipeline from the internal cache. + /// public void InvalidatePipelineCache(FirebirdEvent fbEvent) { cachedPipelines.Remove(fbEvent); } - + /// + /// Retrieves a cached pipeline or fetches and caches it. + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] private Pipeline? GetOrCachePipeline(FirebirdEvent fbEvent) where T : EventArgs { @@ -127,31 +157,45 @@ namespace Firebird2D.KeyMapping return pipeline; } - - public void HandleKeyboardInput(KeyEvent key) + /// + /// Handles a keyboard input and dispatches the event. + /// + public void HandleKeyboardInput(KeyEvent key, InputEventType type) { - var pipeline = GetOrCachePipeline((FirebirdEvent)key.Code); - pipeline?.SendEvent(this, new KeyEventArgs(key)); + var pipeline = GetOrCachePipeline((FirebirdEvent)key.Code); + pipeline?.SendEvent(this, new FirebirdKeyEventArgs(key, type)); } - public void HandleMouseInput(MouseButtonEvent button) + /// + /// Handles a mouse button input and dispatches the event. + /// + public void HandleMouseInput(MouseButtonEvent button, InputEventType type) { - var pipeline = GetOrCachePipeline((FirebirdEvent)(button.Button + 101)); - pipeline?.SendEvent(this, new MouseButtonEventArgs(button)); + var pipeline = GetOrCachePipeline((FirebirdEvent)(button.Button + 101)); + pipeline?.SendEvent(this, new FirebirdMouseButtonEventArgs(button, type)); } - public void HandleJoystickButtonInput(JoystickButtonEvent joystickButton) + /// + /// Handles a joystick button press and dispatches the event. + /// + public void HandleJoystickButtonInput(JoystickButtonEvent joystickButton, InputEventType type) { - var pipeline = GetOrCachePipeline(FirebirdEvent.JoystickButton); - pipeline?.SendEvent(this, new JoystickButtonEventArgs(joystickButton)); + var pipeline = GetOrCachePipeline(FirebirdEvent.JoystickButton); + pipeline?.SendEvent(this, new FirebirdJoystickButtonEventArgs(joystickButton, type)); } + /// + /// Handles mouse movement and dispatches the event. + /// public void HandleMouseMovement(MouseMoveEvent mouseMove) { var pipeline = GetOrCachePipeline(FirebirdEvent.MouseMove); pipeline?.SendEvent(this, new MouseMoveEventArgs(mouseMove)); } + /// + /// Handles joystick movement and dispatches the event. + /// public void HandleJoytickMove(JoystickMoveEvent joystickMove) { var pipeline = GetOrCachePipeline(FirebirdEvent.JoystickMove);