检查一组位标志是否至少包含其他位标志的一个标志
Check if set of bitflags include atleast one flag of other bitflags
我正在编写一个事件系统,其中每个侦听器都会侦听一个、多个或所有通道(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
}
事件被另一个 class 调用,后者调用 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 哪个事件想要调用。
所有代码
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:
为枚举添加了完整代码(现在包括属性)
虽然史蒂夫的回答——现在被神秘地删除了——是正确的,但它可以改进。
首先,正确构建枚举。 Flag 枚举应该这样标记,并且应该有一个 None
值。您也可以考虑使用二进制文字来使其更清晰。
[Flags] public enum Channel
{
None = 0b0000_0000_0000,
One = 0b0000_0000_0001,
Two = 0b0000_0000_0010,
...
我的建议是您实现一个扩展方法来计算您想要的内容,并适当命名。例如,如果您想要的是 "has any of the given channels":
static class Extensions
{
public static bool HasAnyChannel(
this Channel x,
Channel y) =>
x & y != Channel.None;
}
现在您可以使用表达式
listenerChannels.HasAnyChannel(eventChannels)
易于阅读和理解。
我正在编写一个事件系统,其中每个侦听器都会侦听一个、多个或所有通道(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
}
事件被另一个 class 调用,后者调用 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 哪个事件想要调用。
所有代码
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: 为枚举添加了完整代码(现在包括属性)
虽然史蒂夫的回答——现在被神秘地删除了——是正确的,但它可以改进。
首先,正确构建枚举。 Flag 枚举应该这样标记,并且应该有一个 None
值。您也可以考虑使用二进制文字来使其更清晰。
[Flags] public enum Channel
{
None = 0b0000_0000_0000,
One = 0b0000_0000_0001,
Two = 0b0000_0000_0010,
...
我的建议是您实现一个扩展方法来计算您想要的内容,并适当命名。例如,如果您想要的是 "has any of the given channels":
static class Extensions
{
public static bool HasAnyChannel(
this Channel x,
Channel y) =>
x & y != Channel.None;
}
现在您可以使用表达式
listenerChannels.HasAnyChannel(eventChannels)
易于阅读和理解。