Im trying to implement an Event System for a game, where there are classes that can fire or handle an event wheter or not they implement these interfaces:
public interface IGameEvent where T : EventArgs
{
event EventHandler OnEvent;
}
public interface IGameHandler where T : EventArgs
{
void OnEvent(object sender, T e);
}
everything looked great until i realized that no class can implement more than 1 IGameEvent because it would cause duplicate declaration,
Here is an example:
public class Event
{
public KeyPressEvent OnKeyPress;
public UpdateEvent OnUpdate;
public void AddHadler(IGameEvent eEvent , IGameHandler eHandler) where T : EventArgs
{
eEvent.OnEvent += eHandler.OnEvent;
}
public void RemoveHandler(IGameEvent eEvent, IGameHandler eHandler) where T : EventArgs
{
eEvent.OnEvent -= eHandler.OnEvent;
}
}
KeyPressEvent:
public class KeyPressEvent : IGameEvent
{
public class KeyPressedEventArgs : EventArgs
{
public KeyPressedEventArgs(Keys key)
{
Key = key;
}
public Keys Key { get; private set; }
}
public event EventHandler OnEvent;
private void OnCheckForKeyPressed() //Example
{
if (OnEvent != null)
OnEvent(this, new KeyPressedEventArgs(Keys.Space));
}
}
Would be better to manually store the suscribers in a list in the EventSystem ?
How slower or faster than this approach that would be?
Thanks!
Answer
Although you can use the existing event model in C#, it might not always give you the flexibility that you require.
You can for instance not sort events based on their priority, clear events of a specific type or add a queued/delayed event.
Example)
To signup for an event the object needs a method with the same signature as the CallbackMethod delegate. The call might look like this:
class SomeObject
{
private void OnDamageTaken(object sender, IGameEvent e)
{
...
}
... void Initialize()
{
...
EventManager.Subscribe("EVENT_PLAYERINJURED", this.OnDamageTaken);
...
}
}
//Somewhere in the application
EventManager.Notify("EVENT_PLAYERINJURED", new PlayerInjuredEvent(...));
If you don't like using hardcoded eventIds everywhere you could introduce a property on your game event classes.
public PlayerInjuredEvent : IGameEvent
{
public static string EventType
{
get
{
return "EVENT_PLAYERINJURED";
}
}
}
Now you can write:
EventManager.Notify(PlayerInjuredEvent.EventType, ...
I hope this gives you some ideas on how to solve your problem.
No comments:
Post a Comment