Reputation: 21
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?
Upvotes: 1
Views: 601
Reputation: 5422
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.
Upvotes: 5