class Publisher { private Dictionary> subscribers = new Dictionary>(); private InteractorKind kind; public Publisher(InteractorKind kind) { this.kind = kind; this.scan(); } private void scan() { var assembly = this.GetType().Assembly; var types = assembly.GetTypes(); foreach (var type in types) { var attrs = type.GetCustomAttributes(typeof(Interactor), false); if (attrs.Length == 0) { continue; } var methods = type.GetMethods(); foreach (var method in methods) { var attrs2 = method.GetCustomAttributes(typeof(Interaction), false); if (attrs2.Length == 0) { continue; } var attr = (Interaction)attrs2[0]; if (attr.Kind == InteractorKind.Server && this.kind == InteractorKind.Client) { continue; } var del = Delegate.CreateDelegate( typeof(Action<>).MakeGenericType(method.GetParameters()[0].ParameterType), method ); this.subscribe(attr.Type, del); } } } private void subscribe(string type, Delegate callback) { if (!subscribers.ContainsKey(type)) { subscribers[type] = new HashSet(); } subscribers[type].Add(callback); } public void Dump() { foreach (var pair in subscribers) { Console.WriteLine(pair.Key); foreach (var del in pair.Value) { Console.WriteLine(del); } } } public void Publish(ValueType packet) { var type = PacketUtils.GetType(packet); if (type != "tick") Console.WriteLine("Publishing packet: " + type); if (subscribers.ContainsKey(type)) { if (type != "tick") Console.WriteLine("Found " + subscribers[type].Count + " subscribers"); foreach (var del in subscribers[type]) { del.DynamicInvoke(packet); } } } }