[Unity 代码写法整理]消息机制(二)

首先先实现第一种可以跨线程的队列消息机制:

==============================

1.消息体AbstractMessage:

  public abstract class AbstractMessage
  {
      public string messageName;
  }

 ==============================

2.消息队列MessageQueue:

Queue<AbstractMessage> MessageQueue

先不封装,直接用Queue结构,把操作写到MessageCenter里,如果MessageCenter较庞大,再考虑封装。

==============================

3.消息处理函数Handler

Action<AbstractMessage> handler

用System命名空间里现成的委托Action最方便,如果MessageCenter较庞大,再考虑封装。

==============================

4.消息中心MessageCenter

public class MessageCenter : MonoSingleton<MessageCenter>
{
    private Dictionary<string,Action<AbstractMessage>> messageDic = new Dictionary<string,Action<AbstractMessage>>();

    private Queue<AbstractMessage> messageQueue = new Queue<AbstractMessage>();

    //Call per frame
    privatevoid Update()
    {
        while(messageQueue.Peek() != null)
        {
            AbstractMessage message = messageQueue.Dequeue();
            HandleMessage(message);
        }
    }

    //HandleMessage 处理发送的消息
    private void HandleMessage(AbstractMessage message)
    {
        string messageName = message.messageName;
        if(messageDic.ContainsKey(messageName))
        {
            messageDic[messageName](message);
            return;
        }
        Debug.LogError("This message has not registed : " + message.messageName);
    }

    //RegistMessage 注册消息
    public void RegistMessage(string messageName,Action<AbstractMessage> handler)
    {
        if(messageDic.ContainsKey(messageName))
        {
            messageDic[messageName] += handler;
            return;
        }
        messageDic[messageName] = handler;
    }    

    //UnRegistMessage 注销消息
    public void UnRegistMessage(string messageName,Action<AbstractMessage> handler)
    {
        if(messageDic.ContainsKey(messageName))
        {
            if(messageDic[messageName].GetInvocationList().Length > 1)
            {
                messageDic[messageName] -= handler;
                return;
            }
            messageDic.Remove(messageName);
            return;
        }
        Debug.LogError("This Message Not Registed : " + messageName);
    }

    //DispatchMessage 发消息
    public void DispatchMessage(AbstractMessage message)
    {
        messageQueue.Enqueue(message);
    }
}

完全手写,可能有错误。调用的时候主要是这3个方法,RegiestMessage、UnRegistMessage、DispatchMessage,分别是,注册消息,注销消息,发消息。

==============================

5.实际应用

//创建实际消息体
public class TestMessage : AbstractMessage
{
    public string Data;
    public TestMessage(string _messageName,string data)
    {
        messageName = _messageName;
        Data = _data;
    }
}

public class Test : Monobehaviour
{
    //消息名称
    public const string TEST_MESSAGE = "Test_Message_Name";
    
    //UI
    public Text textUI;
    
    //不建议用生命周期函数注册,不可控,先凑合用着~
    private void OnEnable()
    {
        MessageCenter.Instance.RegistMessage(TEST_MESSAGE,OnGetTestMessage);
    }

    //不建议用生命周期函数注销,不可控,先凑合用着~
    private void OnDisable()
    {
        MessageCenter.Instance.UnRegistMessage(TEST_MESSAGE,OnGetTestMessage);
    }
    
    private void Start()
    {
    
        //启动子线程
        Thread thread = new Thread(()=>
        {
            Thread.Sleep(1000);
            TestMessage message = new TestMessage(Test.TEST_MESSAGE,"I want to display in 
 textUI");
            MessageCenter.Instace.DispatchMessage(message);
        }).Start();
    }

    //接收到消息后的回调
    private void OnGetTestMessage(AbstractMessage message)
    {
        TestMessage testMessage = message as TestMessage;
        textUI.text = testMessage.Data;
    }

}

这样就实现了跨线程调用

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值