I have two classes, Input, and “EventSystem”. EventSystem is an internal (non-system dependent) class that handles ‘internal application events’. Input is a dependent class (system dependent) and handles key/button events and maps them both to key events and “EventSystem”. I will show you how I’m currently passing data through, it looks very clean on the inside, but very dirty on the outside. Does anyone know of a better way–or easier method–to passing down custom values?
EventSystem:
// Raisable Events
public enum EventType { Action, Cancel };
// Base for custom arguments
public class EventArguments
{
public double time;
public EventArguments(double _time)
{
time = _time;
}
}
// Event Delegate (invoked on raise)
public delegate void Event(EventArguments eventArgs);
// full class
static class EventSystem
{
private static Dictionary<EventType, Event> eventMapping = new Dictionary<EventType, Event>();
public static void HookEvent(EventType eventType, Event _event)
{
if (eventMapping.ContainsKey(eventType))
{
eventMapping[eventType] += _event;
}
else
{
eventMapping.Add(eventType, _event);
}
}
public static void RaiseEvent(EventType eventType, EventArguments args)
{
if (eventMapping.ContainsKey(eventType))
{
eventMapping[eventType].Invoke(args);
}
else
{
// do nothing
}
}
}
My input args simply inherit EventArguments.
// Inherits EventArguments (double time) and adds it's own, "bool pressed"
class KeyInputArguments : EventArguments
{
public bool pressed;
public KeyInputArguments(double time, bool _pressed) :
base(time)
{
pressed = _pressed;
}
}
When a key is pressed it fires key (input) events, then it checks to see if the key is mapped to an internal event and raises it. A separate class (Config) handles all the configuration of mapping/binding Keys to events.
// Raise on press
EventSystem.RaiseEvent(eventType, new KeyInputArguments(time, true));
// [...]
// Raise on release
EventSystem.RaiseEvent(eventType, new KeyInputArguments(time, false));
Finally, in order to fire the event, we have to register the key to the event (this is the ‘external‘ code)
// Hook our "Enter" function into the Action event
EventSystem.HookEvent(EventType.Action, Enter);
// [...]
public void Enter(EventArguments eventArg)
{
if (((KeyInputArguments)eventArg).pressed == false)
{
Error.Break();
}
}
Everything is great until I see ‘(((‘. This is an ugly result of my limited knowledge of C# and OOP programming in general.
I cannot change the Enter method argument because Event delegate explicitly requires EventArguments. (Even though KeyInputArguments inherits it ?). I also don’t understand why it takes so much to cast eventArg to KeyInputArguments.
Finally, I also tried this (though I don’t like it that much)
KeyInputArguments keyInputArguments = (KeyInputArguments)eventArg;
if (keyInputArguments.pressed == false)
The reason I require custom data is that I plan on receiving input from multiple forms of input, such as gamepads. This means I can then process system dependent data (gamepad device information) into independent arguments. This limits system dependent data to my Input class, while leveraging my event system internally as independent. Is there a better method for what I’m doing?
Put this code in your project somewhere:
This enables you to write
I really like this because it conserves the left to right order of the things. This is especially good when writing linq.
In answer to your question “Even though KeyInputArguments inherits it ?”. The problem here is that you have defined a general purpose method that uses a base class, it can’t know about inherited classes. You would need to use generics on that method to fix that issue, eg passing in the event type as a generic parameter