首先先实现第一种可以跨线程的队列消息机制:
==============================
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;
}
}
这样就实现了跨线程调用