Question

I'm designing a game in C#, I'm sure you get it a lot - but my question is a bit different in that I want to design something around an observer pattern to my understanding - and I can't find much information it.

All of my packets implement a basic interface, called IPacket... and I was hoping to fire off an event when a packet of a certain type was recieved; without using a massive switch.

I was perhaps hoping for something like:

networkEvents.PacketRecieved += [...]

Could anyone point me in the direction to do this?

Was it helpful?

Solution

What about something like this:

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

Each type of package you create registers a handler specific to that type of packet. Using a ConcurrentDictionary makes locking superfluous.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top