0

我正在编写一个事件系统,其中每个侦听器都侦听一个、多个或所有通道(GameEventChannel 枚举),并且只能为一个、多个或所有通道(GameEventChannels)引发事件。我现在拥有的是。

[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
}

该事件被另一个类调用,该类在其上调用Invoke(GameEventChannel channel)。在 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();
            }
        }
    }

我需要编写函数IsListeningToChannel() ,该函数需要确定侦听器是否正在侦听事件要调用的 GameEventChannel。

例如

Event.Invoke(GameEventChannel.One | GameEventChannel.Two | GameEventChannel.Three)

Listener1 正在收听"GameEventChannel.Two | GameEventChannel.Eight"

我如何检查是否应该调用 Listener1,因为他在 GameEventChannel.Two 上侦听 Event 想要调用的。

所有代码

  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;
    }

编辑 1:将枚举的每次出现都更改为正确的名称编辑 2:添加了枚举的完整代码(现在包括属性)

4

1 回答 1

4

虽然史蒂夫的回答——现在被神秘地删除了——是正确的,但可以改进。

首先,正确构建您的枚举。标志枚举应该这样标记并且应该有一个None值。您也可以考虑使用二进制文字使其更清晰。

[Flags] public enum Channel 
{
  None = 0b0000_0000_0000,
  One  = 0b0000_0000_0001,
  Two  = 0b0000_0000_0010,
  ...

我的建议是你实现一个扩展方法来计算你想要的,并适当地命名。例如,如果您想要的是“具有任何给定的频道”:

static class Extensions 
{
  public static bool HasAnyChannel(
      this Channel x,
      Channel y) =>
    x & y != Channel.None;
}

现在你可以使用表达式

listenerChannels.HasAnyChannel(eventChannels)

这很容易阅读和理解。

于 2019-08-15T20:38:20.563 回答