Пример #1
0
        public MessageWrapper(MessageWrapper inBase, MessengerImpl inTarget)
        {
            Target         = inTarget;
            Message        = inBase.Message;
            Metadata       = inBase.Metadata;
            m_RequeuesLeft = inBase.m_RequeuesLeft;

            m_ID = s_GlobalID++;
        }
Пример #2
0
        public Manager()
        {
            s_Instance = this;

            m_MessengerRegistry = new Dictionary <int, MessengerImpl>();
            m_MessageQueue      = new List <MessageWrapper>();

            Root = new MessengerImpl(this);

#if DEVELOPMENT
            DebugMode = true;
#endif
        }
Пример #3
0
        public DelegateBlock(MessengerImpl inOwner, Manager inManager, MsgType inType)
        {
            m_Manager   = inManager;
            m_Owner     = inOwner;
            m_DebugMode = inManager.DebugMode;

            m_Metadata       = inManager.Database.Find(inType);
            m_AllowedArgType = m_Metadata.ArgType;
            if (m_AllowedArgType != null)
            {
                m_AllowedArgTypePtr = m_AllowedArgType.TypeHandle.Value;
            }
        }
Пример #4
0
        /// <summary>
        /// Sends a message to the messenger on the given GameObject.
        /// </summary>
        public void Send(GameObject inTarget, Message inMessage)
        {
            if (m_Manager.DebugMode)
            {
                if (m_Destroyed)
                {
                    throw new InvalidOperationException("Messenger has already been destroyed");
                }
                if (!inMessage.Type)
                {
                    throw new ArgumentException("Provided MsgType is null.");
                }
                if (inTarget == null)
                {
                    throw new ArgumentNullException();
                }
            }

            MessengerImpl messenger = m_Manager.Find(inTarget);

            if (messenger == null)
            {
                if (m_Manager.DebugMode)
                {
                    if (m_Manager.Database.Find(inMessage.Type).HasFlags(MsgFlags.RequireHandler))
                    {
                        throw new Exception("MsgType " + inMessage.Type.ToString() + " requires a handler");
                    }
                }
                return;
            }

            MessageWrapper wrapper = new MessageWrapper(messenger, inMessage);

            if (m_Manager.DebugMode)
            {
                if (wrapper.Metadata.CanLog(LogFlags.Dispatch))
                {
                    m_Manager.Log(Owner.name + " sending message " + inMessage.ToString() + " to " + inTarget.name);
                }
            }

            if ((wrapper.Metadata.Dispatch & MsgDispatch.Immediate) != 0)
            {
                messenger.TryDispatch(ref wrapper);
            }
            else
            {
                m_Manager.QueueMessage(ref wrapper);
            }
        }
Пример #5
0
        public void Invoke(ref MessageWrapper inMessage)
        {
            if (m_Handlers != null)
            {
                m_Handlers(inMessage.Message);
            }
            if (m_Actions != null)
            {
                m_Actions();
            }

            if (m_Typed != null)
            {
                m_Typed.Invoke(ref inMessage);
            }

            if (m_Children != null)
            {
                int prevDispatchChildren = ++m_DispatchChildrenDepthAndVersion;

                int childLength = m_Children.Count;
                for (int i = 0; i < childLength; ++i)
                {
                    MessengerImpl impl = m_Children[i];
                    if (impl != null)
                    {
                        impl.TryDispatch(ref inMessage);
                    }
                }

                --m_DispatchChildrenDepthAndVersion;

                // Call earliest in the stack will have prevDispatchChildren set to 1.
                // If this is the earliest call and it's not the expected value of 0 by this point,
                // that means the list has changed and we should clean up the null children
                if (prevDispatchChildren == 1 && m_DispatchChildrenDepthAndVersion != 0)
                {
                    for (int i = m_Children.Count - 1; i >= 0; --i)
                    {
                        if (m_Children[i] == null)
                        {
                            m_Children.RemoveAt(i);
                        }
                    }

                    m_DispatchChildrenDepthAndVersion = 0;
                }
            }
        }
Пример #6
0
        /// <summary>
        /// Finds or creates a messenger for the given GameObject.
        /// </summary>
        public MessengerImpl Require(GameObject inGameObject)
        {
            if (!m_Initialized)
            {
                Initialize();
            }

            MessengerImpl m = Find(inGameObject);

            if (m == null)
            {
                m = new MessengerImpl(this, inGameObject);
            }
            return(m);
        }
Пример #7
0
        public void Dispose()
        {
            m_Owner     = null;
            m_Manager   = null;
            m_DebugMode = false;

            m_Metadata       = null;
            m_AllowedArgType = null;
            m_Handlers       = null;
            m_Actions        = null;
            if (m_Typed != null)
            {
                m_Typed.Dispose();
                m_Typed = null;
            }
        }
Пример #8
0
        /// <summary>
        /// Broadcasts a message from the root messenger.
        /// </summary>
        public void Broadcast(Message inMessage)
        {
            if (m_Parent == null)
            {
                Send(this, inMessage);
                return;
            }

            if (m_Manager.DebugMode)
            {
                if (m_Destroyed)
                {
                    throw new InvalidOperationException("Messenger has already been destroyed");
                }
                if (!inMessage.Type)
                {
                    throw new ArgumentException("Provided MsgType is null.");
                }
            }

            MessengerImpl root = m_Parent;

            while (root.m_Parent != null)
            {
                root = root.m_Parent;
            }

            MessageWrapper wrapper = new MessageWrapper(root, inMessage);

            if (m_Manager.DebugMode)
            {
                if (wrapper.Metadata.CanLog(LogFlags.Dispatch))
                {
                    m_Manager.Log(Owner.name + " broadcasting message " + inMessage.ToString());
                }
            }

            if ((wrapper.Metadata.Dispatch & MsgDispatch.Immediate) != 0)
            {
                root.TryDispatch(ref wrapper);
            }
            else
            {
                m_Manager.QueueMessage(ref wrapper);
            }
        }
Пример #9
0
        // Validates that the graph has no loops
        private void ValidateGraph(MessengerImpl inNewParent)
        {
            HashSet <MessengerImpl> visited = new HashSet <MessengerImpl>();

            visited.Add(this);

            MessengerImpl current = inNewParent;

            while (current != null)
            {
                if (visited.Contains(current))
                {
                    throw new Exception("Invalid or looping Messenger graph, starting with " + (ReferenceEquals(m_GameObject, null) ? "[Root]" : m_GameObject.name));
                }
                visited.Add(current);
                current = current.m_Parent;
            }
        }
Пример #10
0
        public MessageWrapper(MessengerImpl inTarget, Message inMessage)
        {
            Target  = inTarget;
            Message = inMessage;

            Manager manager = Manager.Get();

            Metadata = manager.Database.Find(inMessage.Type);

            // Argument validation
            if (manager.DebugMode)
            {
                Metadata.Validate(inMessage);
            }
            m_RequeuesLeft = Metadata.RequeueLimit;

            m_ID = s_GlobalID++;
        }
Пример #11
0
        /// <summary>
        /// Registers a handler for the given MsgType.
        /// </summary>
        public void Register(MsgType inType, MessengerImpl inHandler)
        {
            ValidateRegisterArgs(inType, inHandler);

            DelegateBlock handler;

            if (m_Handlers.TryGetValue(inType, out handler))
            {
                handler.Register(inHandler);
            }
            else
            {
                handler = m_Handlers[inType] = new DelegateBlock(this, m_Manager, inType);
                handler.Register(inHandler);
                if (m_Parent != null)
                {
                    m_Parent.Register(inType, this);
                }
            }
        }
Пример #12
0
        /// <summary>
        /// Deregisters a handler for the given MsgType.
        /// </summary>
        public void Deregister(MsgType inType, MessengerImpl inHandler)
        {
            ValidateRegisterArgs(inType, inHandler);

            DelegateBlock handler;

            if (m_Handlers.TryGetValue(inType, out handler))
            {
                handler.Deregister(inHandler);
                if (handler.IsEmpty())
                {
                    handler.Dispose();
                    m_Handlers.Remove(inType);
                    if (m_Parent != null)
                    {
                        m_Parent.Deregister(inType, this);
                    }
                }
            }
        }
Пример #13
0
        public void Deregister(MessengerImpl inHandler)
        {
            if (m_Children != null)
            {
                if (m_DispatchChildrenDepthAndVersion > 0)
                {
                    int index = m_Children.IndexOf(inHandler);
                    if (index >= 0)
                    {
                        m_Children[index] = null;
                    }

                    // Incrementing this means that we've changed the list
                    ++m_DispatchChildrenDepthAndVersion;
                }
                else
                {
                    m_Children.Remove(inHandler);
                }
            }
        }
Пример #14
0
        /// <summary>
        /// Sends a message to the given messenger.
        /// </summary>
        public void Send(MessengerImpl inTarget, Message inMessage)
        {
            if (m_Manager.DebugMode)
            {
                if (m_Destroyed)
                {
                    throw new InvalidOperationException("Messenger has already been destroyed");
                }
                if (!inMessage.Type)
                {
                    throw new ArgumentException("Provided MsgType is null.");
                }
                if (inTarget == null)
                {
                    throw new ArgumentNullException();
                }
            }

            MessageWrapper wrapper = new MessageWrapper(inTarget, inMessage);

            if (m_Manager.DebugMode)
            {
                if (wrapper.Metadata.CanLog(LogFlags.Dispatch))
                {
                    m_Manager.Log(Owner.name + " sending message " + inMessage.ToString() + " to " + inTarget.Owner.name);
                }
            }

            if ((wrapper.Metadata.Dispatch & MsgDispatch.Immediate) != 0)
            {
                inTarget.TryDispatch(ref wrapper);
            }
            else
            {
                m_Manager.QueueMessage(ref wrapper);
            }
        }
Пример #15
0
        /// <summary>
        /// Destroys the messenger.
        /// </summary>
        public void Destroy(bool inbRemove = true)
        {
            if (m_Destroyed)
            {
                return;
            }

            m_Destroyed = true;

            if (m_Parent != null)
            {
                foreach (MsgType type in m_Handlers.Keys)
                {
                    m_Parent.Deregister(type, this);
                }
                m_Parent.m_Children.Remove(this);
                m_Parent = null;
            }

            foreach (var handler in m_Handlers.Values)
            {
                handler.Dispose();
            }
            m_Handlers.Clear();

            if (inbRemove)
            {
                m_Manager.DeregisterMessenger(this);
            }

            for (int i = m_Children.Count - 1; i >= 0; --i)
            {
                m_Children[i].OnParentDestroyed();
            }
            m_Children.Clear();
        }
Пример #16
0
        /// <summary>
        /// Constructs the root messenger.
        /// </summary>
        public MessengerImpl(Manager inManager)
        {
            m_Manager  = inManager;
            m_Handlers = new Dictionary <MsgType, DelegateBlock>(64);

            m_Parent = null;

            // We can expect the root to have many children,
            // so we should pre-allocate a larger list to avoid
            // expanding at runtime
            m_Children = new List <MessengerImpl>(256);

            m_ID        = 0;
            m_IsRoot    = true;
            m_Destroyed = false;

            m_GameObject     = null;
            m_UnityComponent = null;
            m_UnityActive    = true;

            Interface = new Messenger(this);

            m_Manager.RegisterMessenger(this);
        }
Пример #17
0
 public void Initialize(MessengerImpl inMessenger)
 {
     Messenger = inMessenger;
 }
Пример #18
0
 /// <summary>
 /// Requeues a message to be executed at the end of the frame.
 /// </summary>
 public void RequeueMessage(ref MessageWrapper inWrapper, MessengerImpl inTarget)
 {
     m_MessageQueue.Add(new MessageWrapper(inWrapper, inTarget));
 }
Пример #19
0
 /// <summary>
 /// Removes a messenger from the registry.
 /// </summary>
 public void DeregisterMessenger(MessengerImpl inImpl)
 {
     m_MessengerRegistry.Remove(inImpl.ID);
 }
Пример #20
0
 /// <summary>
 /// Registers a messenger to the registry.
 /// </summary>
 public void RegisterMessenger(MessengerImpl inImpl)
 {
     m_MessengerRegistry[inImpl.ID] = inImpl;
 }
Пример #21
0
 private void OnParentDestroyed()
 {
     m_Parent = null;
 }