2011-10-22 93 views
1

我正在用C#设计一款游戏,我相信你会得到很多 - 但我的问题有点不同,因为我想根据我的理解设计一些围绕观察者模式的东西 - 而且我可以'找到很多信息吧。网络流程

我的所有数据包都实现了一个基本的接口,叫做IPacket ......我希望在接收到某种类型的数据包时触发一个事件;无需使用大量开关。

我或许是希望这样的事情:

networkEvents.PacketRecieved + = [...]

任何人都可以点我的方向来做到这一点?

回答

5

什么是这样的:

public interface IPacket 
{ 

} 

public class FooPacket: IPacket {} 

public class PacketService 
{ 
    private static readonly ConcurrentDictionary<Type, Action<IPacket>> _Handlers = new ConcurrentDictionary<Type, Action<IPacket>>(new Dictionary<Type, Action<IPacket>>()); 

    public static void RegisterPacket<T>(Action<T> handler) 
     where T: IPacket 
    { 
     _Handlers[typeof (T)] = packet => handler((T) packet); 
    } 

    private void ProcessReceivedPacket(IPacket packet) 
    { 
     Action<IPacket> handler; 
     if (!_Handlers.TryGetValue(packet.GetType(), out handler)) 
     { 
      // Error handling here. No packet handler exists for this type of packet. 
      return; 
     } 
     handler(packet); 
    } 
} 

class Program 
{ 
    private static PacketService _PacketService = new PacketService(); 
    static void Main(string[] args) 
    { 
     PacketService.RegisterPacket<FooPacket>(HandleFooPacket); 
    } 

    public static void HandleFooPacket(FooPacket packet) 
    { 
     // Do something with the packet 
    } 
} 

每次创建注册它可以处理特定于该类型的数据包封装类型。使用ConcurrentDictionary会使锁定变得多余。

+0

那么,我的头稍微有些......我可以看到你正在创建所有不同数据包的映射,并且大概我正在客户端重构我的数据包对象 - 并将它提供给处理器。通过调用processRecievedPacket呢?那么,外部监听器触发的方式到底是什么?听着吗? –

+0

那么,你正在通过网络连接接收二进制数据。在某些时候,您将它们重建为.NET对象。您现在可以将此数据包交给PacketService ProcessReceivedPacket方法,该方法选择数据包的最终处理程序。这不是你想要的吗? –

+0

这就是我的意图 - 我只是对我的听众如何'听到'这个事件被触发感到困惑。我仍然是这个主题的新手,我习惯于订阅一个活动......并且没有任何活动可以在这里订阅。 –