IMessageProcessor[] BuildMessageProcessors(object source)
        {
            const BindingFlags bindFlags =
                BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.InvokeMethod |
                BindingFlags.Static;

            var mpdType  = typeof(MessageProcessorHandler);
            var atbType  = typeof(MessageHandlerAttribute);
            var voidType = typeof(void);

            var tmpProcessors = new DArray <IMessageProcessor>();

            // Search through all types in the Assembly
            var assemb = Assembly.GetAssembly(source.GetType());

            foreach (var type in assemb.GetTypes())
            {
                // Search through every method in the class
                foreach (var method in type.GetMethods(bindFlags))
                {
                    // Only accept a method if it returns a void
                    if (method.ReturnType != voidType)
                    {
                        continue;
                    }

                    // Get all of the MessageAttributes for the method (should only be one)
                    var atbs = (MessageHandlerAttribute[])method.GetCustomAttributes(atbType, true);
                    if (atbs.Length > 1)
                    {
                        const string errmsg = "Multiple MessageHandlerAttributes found for method `{0}`.";
                        Debug.Fail(string.Format(errmsg, method.Name));
                        throw new ArgumentException(string.Format(errmsg, method.Name), "source");
                    }

                    // Create the message processor for the method
                    foreach (var atb in atbs)
                    {
                        if (tmpProcessors.CanGet(atb.MsgID) && tmpProcessors[atb.MsgID] != null)
                        {
                            const string errmsg =
                                "A MessageHandlerAttribute with ID `{0}` already exists. Methods in question: {1} and {2}";
                            Debug.Fail(string.Format(errmsg, atb.MsgID, tmpProcessors[atb.MsgID].Call.Method, method));
                            throw new DuplicateKeyException(string.Format(errmsg, atb.MsgID, tmpProcessors[atb.MsgID].Call.Method,
                                                                          method));
                        }

                        var del = (MessageProcessorHandler)Delegate.CreateDelegate(mpdType, source, method);
                        Debug.Assert(del != null);
                        var msgProcessor = CreateMessageProcessor(atb, del);
                        tmpProcessors.Insert(atb.MsgID, msgProcessor);
                    }
                }
            }

            return(tmpProcessors.ToArray());
        }
예제 #2
0
        /// <summary>
        /// Reorganizes the internal buffer to ensure the indices all match up. Only needed if IsReadonly is false
        /// and you don't manually update the indices.
        /// </summary>
        public void Reorganize()
        {
            var dialogs = _npcChatDialogs.ToArray();

            _npcChatDialogs.Clear();

            foreach (var dialog in dialogs.Where(x => x != null))
            {
                _npcChatDialogs[(int)dialog.ID] = dialog;
            }
        }
예제 #3
0
        IMessageProcessor[] BuildMessageProcessors(object source)
        {
            const BindingFlags bindFlags =
                BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.InvokeMethod |
                BindingFlags.Static;

            var mpdType = typeof(MessageProcessorHandler);
            var atbType = typeof(MessageHandlerAttribute);
            var voidType = typeof(void);

            var tmpProcessors = new DArray<IMessageProcessor>();

            // Search through all types in the Assembly
            var assemb = Assembly.GetAssembly(source.GetType());
            foreach (var type in assemb.GetTypes())
            {
                // Search through every method in the class
                foreach (var method in type.GetMethods(bindFlags))
                {
                    // Only accept a method if it returns a void
                    if (method.ReturnType != voidType)
                        continue;

                    // Get all of the MessageAttributes for the method (should only be one)
                    var atbs = (MessageHandlerAttribute[])method.GetCustomAttributes(atbType, true);
                    if (atbs.Length > 1)
                    {
                        const string errmsg = "Multiple MessageHandlerAttributes found for method `{0}`.";
                        Debug.Fail(string.Format(errmsg, method.Name));
                        throw new ArgumentException(string.Format(errmsg, method.Name), "source");
                    }

                    // Create the message processor for the method
                    foreach (var atb in atbs)
                    {
                        if (tmpProcessors.CanGet(atb.MsgID) && tmpProcessors[atb.MsgID] != null)
                        {
                            const string errmsg =
                                "A MessageHandlerAttribute with ID `{0}` already exists. Methods in question: {1} and {2}";
                            Debug.Fail(string.Format(errmsg, atb.MsgID, tmpProcessors[atb.MsgID].Call.Method, method));
                            throw new DuplicateKeyException(string.Format(errmsg, atb.MsgID, tmpProcessors[atb.MsgID].Call.Method,
                                method));
                        }

                        var del = (MessageProcessorHandler)Delegate.CreateDelegate(mpdType, source, method);
                        Debug.Assert(del != null);
                        var msgProcessor = CreateMessageProcessor(atb, del);
                        tmpProcessors.Insert(atb.MsgID, msgProcessor);
                    }
                }
            }

            return tmpProcessors.ToArray();
        }