Every time an object says "Call the Start event" I have to iterate through every single entity in the game, and find out if they are "listening" for that event.
You're doing it wrong! Iterating over every single object and checking if they're registered for an event is very inefficient! This is the typical Observer design pattern and there are several ways to go about this, here are a couple:
- Have a single event which gets raised and has an enum parameter for event type (every subscriber gets it).
- Have a dictionary of enums and corresponding events.
Here is what option 1 might look like:
delegate void OnEventDelegate(kEvents anEvent);
public class MyEventObservable
{
public event OnEventDelegate OnEvent;
}
public class MyEventObserver
{
// Constructors and all
// ...
public void OnEventReceived(kEvents anEvent)
{
switch(anEvent)
{
// switch through all the events and handle the ones that you need
}
}
}
MyEventObserver observer = new MyEventObserver();
MyEventObservable observable = new MyEventObservable();
observable.OnEvent += new OnEventDelegate(observer.OnEventReceived);
Here is option 2:
public class MyEventObservable
{
private Dictionary<kEvents, List<IObserver>> _observers;
MyEventObservable()
{
// Initialize the dictionary with all the events
}
public void RegisterObserver(kEvents event, IObserver observer)
{
_observers[event].Add(observer);
}
}
interface class IObserver
{
void Notify(kEvents anEvent);
}
public MyEventObserver: IObserver
{
// Constructors and all
// ...
// Override the IObserver
public void Notify(kEvents anEvent)
{
switch(anEvent)
{
// switch through all the events and handle the ones that you need
}
}
}
MyEventObserver observer = new MyEventObserver();
MyEventObservable observable = new MyEventObservable();
observable.RegisterObserver(kEvents.Start, observer);
Option two will reduce the number of events each observer has to handle, but it comes at the cost of having to register for every event separately (which adds coding complexity). This means that option 2 will work faster because there are fewer function calls to make. Depending on how "crazy" you want to get with the performance, there might be other options that can help you to speed it up but this should set you on the right track.
P.S. I have not compiled any of the code, but it should give you a general idea of how things ought to work.