Unity全局消息通知

Unity全局消息通知_第1张图片

本文介绍一个通用方便的全局消息工具,使用此工具可以随意在任何脚本里边注册消息,发送消息,处理消息
同一个消息可以在多个脚本里边同时注册,同时接收到消息通知

消息处理类,包括消息的注册,发送

public class YHMessageCenter
{
    private static YHMessageCenter _messageCenter = null;
    
    private MessageQueue _messageQueue = new MessageQueue();
    private MessageHandlerList _messageHandlerList = new MessageHandlerList();
    
    public static YHMessageCenter GetInstance()
    {
        if (_messageCenter == null)
            _messageCenter = new YHMessageCenter();
        
        return _messageCenter;
    }
    
    public void PostYHMessage(MessageBase message)
    {
        _messageQueue.EnqueueMessage(message);
    }
    
    public MessageBase GetYHMessage()
    {
        return _messageQueue.DequeueMessage();
    }
    
    public void RegisterYHMessageHandler(MessageType messageID, MessageHandler handler)
    {
        _messageHandlerList.RegisterYHMessageHandler(messageID, handler);
    }
    
    public void UnRegisterYHMessageHandler(MessageType messageID, MessageHandler handler)
    {
        _messageHandlerList.UnRegisterYHMessageHandler(messageID, handler);
    }
    
    public MessageHandler GetYHMessageHandler(MessageType messageID)
    {
        return _messageHandlerList.GetYHMessageHandler(messageID);
    }
}

消息接收方法管理类,主要管理哪些类型的消息在什么样的方法中执行

public delegate void MessageHandler(MessageBase param);

public class MessageHandlerList
{
    private Dictionary _messageHandlerList = new Dictionary();
    
    public void RegisterYHMessageHandler(MessageType messageID, MessageHandler handler)
    {
        if (_messageHandlerList == null) return;
        
        MessageHandler delegater;
        if (_messageHandlerList.TryGetValue(messageID, out delegater))
        {
            Delegate[] delegates = delegater.GetInvocationList();
            if (Array.IndexOf(delegates, handler) == -1)
            {
                _messageHandlerList[messageID] += handler;
            }
        }
        else
        {
            _messageHandlerList.Add(messageID, handler);
        }
    }
    
    public void UnRegisterYHMessageHandler(MessageType messageID, MessageHandler handler)
    {
        if (_messageHandlerList == null) return;
        
        if (_messageHandlerList.ContainsKey(messageID))
        {
            _messageHandlerList[messageID] -= handler;
            
            if (_messageHandlerList[messageID] == null)
            {
                _messageHandlerList.Remove(messageID);
            }
        }
    }
    
    public MessageHandler GetYHMessageHandler(MessageType messageID)
    {
        MessageHandler delegater = null;
        
        if (_messageHandlerList.TryGetValue(messageID, out delegater))
            return delegater;
        
        return null;
    }
}

存储消息的队列

public class MessageQueue
{
    private Queue _messageQueue = new Queue();
    private Object _messageQueueLock = new Object();
    
    private Queue messageQueue
    {
        set
        {
            _messageQueue = value;
        }
        get
        {
            return _messageQueue;
        }
    }
    
    public MessageBase DequeueMessage()
    {
        lock (_messageQueueLock)
        {
            if (_messageQueue.Count != 0)
            {
                return _messageQueue.Dequeue();
            }
        }
        
        return null;
    }
    
    public void EnqueueMessage(MessageBase message)
    {
        lock (_messageQueueLock)
        {
            if (message.unique)
            {
                bool included = false;
                MessageBase[] array = messageQueue.ToArray();
                for (int i = 0; i < array.Length; I++)
                {
                    MessageBase mb = array[I];
                    if (mb.messageID == message.messageID)
                    {
                        included = true;
                        break;
                    }
                }
                
                if (included)
                {
                    MessageQueue _messageQueueBk = new MessageQueue();
                    for (int i = 0; i < array.Length; I++)
                    {
                        MessageBase mb = array[I];
                        if (mb.messageID == message.messageID)
                            continue;
                        _messageQueueBk.EnqueueMessage(mb);
                    }
                    _messageQueueBk.EnqueueMessage(message);
                    messageQueue = _messageQueueBk.messageQueue;
                }
                else
                    _messageQueue.Enqueue(message);
            }
            else
                _messageQueue.Enqueue(message);
        }
    }
}

消息枚举

 public enum MessageType
 {
     Test = 1,
 }

消息类型

基类
public class MessageBase
{
    public MessageType id;
}

子类
public class TestMessage : MessageBase
{
    public TestMessage()
    {
        id = MessageType. Test;
    }
}
消息转发类,负责消息的实时转发

把YHMessageProcessor脚本挂载到刚开始运行程序的随便一个物体上边

public class YHMessageProcessor : MonoBehaviour
{
    void Update()
    {
        MessageBase message = null;
        List unhandledMessageList = new List();
        while ((message = YHMessageCenter.GetInstance().GetYHMessage()) != null)
        {
            bool handled = DispatchMessage(message);
            if (!handled)
                unhandledMessageList.Add(message);
        }
        
        if (unhandledMessageList.Count > 0)
        {
            for (int i = 0; i < unhandledMessageList.Count; I++)
            {
                YHMessageCenter.GetInstance().PostYHMessage(unhandledMessageList[I]);
            }
        }
    }
    
    private bool DispatchMessage(MessageBase message)
    {
        MessageHandler handler = YHMessageCenter.GetInstance().GetYHMessageHandler(message.messageID);
        
        if (handler != null)
        {
            handler(message);
        }
        else
        {
            if (message.mustbeHandled == true)
                return false;
        }
        return true;
    }
}
测试代码
    发送消息
    YHMessageCenter.GetInstance().PostYHMessage(new TestMessage());
private void OnEnable()
{
    注册消息
    YHMessageCenter.GetInstance().RegisterYHMessageHandler(MessageType.Test, Test);
}

private void OnDisable()
{
    移除消息
    YHMessageCenter.GetInstance().UnRegisterYHMessageHandler(MessageType.Test, Test);
}

private void Test(MessageBase message)
{
    //do something
}

你可能感兴趣的:(Unity全局消息通知)