/// <summary> /// This class encapsulates a packet processor. It stores packet handling methods in a red-black tree /// for faster switching between large amounts of handlers. This technique can replace a large switch /// statement for better efficiency. /// </summary> /// <param name="handlers">The class encapsulating the packet handlers to be added to the tree.</param> public PacketProcessor(object handlers) { // Error check the callback type (should be void or delegate): if (!typeof(TCallbackSignature).IsSubclassOf(typeof(Delegate))) { return; } _tree = new RedBlackTree <TIdentity, TCallbackSignature>(); var root = handlers.GetType(); // Populate the processing tree: For each method in the class, check for custom attributes and // the IPacketAttribute interface. foreach (MethodInfo method in root.GetMethods()) { foreach (var attr in method.GetCustomAttributes(true)) { // If the attribute isn't null, add the method as a callback for the handler type. IPacketAttribute attribute = attr as IPacketAttribute; if (attribute != null) { // Get the key and value for the entry in the tree: TIdentity key = (TIdentity)attribute.Type; TCallbackSignature value = Delegate.CreateDelegate(typeof(TCallbackSignature), null, method) as TCallbackSignature; // Add the callback definition: if (!_tree.TryAppend(key, value)) { // The method already exists. Combine. TCallbackSignature source = _tree.TryGetValue(key); source = Delegate.Combine(source as Delegate, value as Delegate) as TCallbackSignature; _tree.AppendOrUpdate(key, source); } } } } }