I'm programming an event system, where every listener listens to one, multiple or all channels (GameEventChannel enum) and and event can be raised only for one, multiple or all channels (GameEventChannels). What i have right now is.
[System.Flags]
public enum GameEventChannel {
One = 1,
Two = 2,
Three = 4,
Four = 8,
Five = 16,
Six = 32,
Seven = 64,
Eight = 128,
Nine = 256,
Ten = 512
}
The event gets invoked by another class, which calls Invoke(GameEventChannel channel) on it. Inside the Invoke function, i iterate over all listening listeners for this event, and want to determine which listeners it should invoke
public void Invoke(GameEventChannel channels)
{
Debug.Log("Invoke with channales: " + channels.ToString());
for (var i = 0; i < _Listeners.Count; i++)
{
var listener = _Listeners[i];
if (listener != null && IsListeningToChannel())
{
_Listeners[i]?.OnEventInvoked();
}
}
}
I need to code out the function IsListeningToChannel() which needs to decide if the listeners is listening on this GameEventChannel the event wants to invoke.
e.g.
Event.Invoke(GameEventChannel.One | GameEventChannel.Two | GameEventChannel.Three)
Listener1 is listening to "GameEventChannel.Two | GameEventChannel.Eight"
How can i check if Listener1 should be invoked, because he listens on GameEventChannel.Two which Event wants to call.
All Code
public enum GameEventChannel {
One = 1,
Two = 2,
Three = 4,
Four = 8,
Five = 16,
Six = 32,
Seven = 64,
Eight = 128,
Nine = 256,
Ten = 512
}
public void Invoke(GameEventChannel channels)
{
for (var i = 0; i < _Listeners.Count; i++)
{
var listener = _Listeners[i];
if (listener != null && IsListeningToChannel())
{
_Listeners[i]?.OnEventInvoked();
}
}
}
public bool IsListeningToChannel(GameEventChannel listenerChannel, GameEventChannel eventChannels)
{
return AnyOfListenerChanelFlagInsideEventChannelFlags;
}
Edit 1: Changed every occurance of the enum to the right name Edit 2: Added complete code for enum (includes attribute now)
Though Steve's answer -- now mysteriously deleted -- is correct, it could be improved.
First, build your enumeration correctly. Flag enums should be marked as such and should have a None
value. You might also consider using binary literals to make it more clear.
[Flags] public enum Channel
{
None = 0b0000_0000_0000,
One = 0b0000_0000_0001,
Two = 0b0000_0000_0010,
...
My recommendation is that you implement an extension method that computes what you want, and is named appropriately. For example, if what you want is "has any of the given channels":
static class Extensions
{
public static bool HasAnyChannel(
this Channel x,
Channel y) =>
x & y != Channel.None;
}
And now you can use the expression
listenerChannels.HasAnyChannel(eventChannels)
which is easy to read and understand.