예제 #1
0
        /// <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);
                        }
                    }
                }
            }
        }