很多童鞋有可能看不懂第一篇的内容,先理清楚模块,然后跟着敲一遍,这篇文章来研究消息处理中心MsgCenter处理消息的流程。
消息处理流程
- 注册消息:建立ID和委托事件的对应关系
- 分发消息:将消息ID对应的事件加入待处理消息队列
- 处理消息:通过待处理消息集合todoCallBack逐一处理消息
- 接收消息:将接收到的消息转化为本模块的消息格式
注册消息
在注册消息之前需要一些准备工作:
- 建立ID与委托的字典
private Dictionary<int, Callback> callbackDic = new Dictionary<int, Callback>();
- 创建代办事件,队列里面存放委托事件
private Queue<Action> todoCallback = new Queue<Action>();
需要考虑集两个问题:
- 集合中有此ID,继续添加事件给委托
- 集合中没有此ID,添加新的对应关系到字典
具体代码如下:
/// <summary>
/// 注册的多条消息
/// </summary>
/// <param name="callback"></param>
/// <param name="msgIds"></param>
void RegiestMsg(Callback callback,int[] msgIds)
{
if (callback == null)
return;
for(int i =0;i <msgIds.Length;i++)
{
RegiestMsg(callback, msgIds[i]);
}
}
/// <summary>
/// 注册一条消息
/// 将消息id和对应的委托建立联系
/// </summary>
/// <param name="callback"></param>
/// <param name="msgId"></param>
void RegiestMsg(Callback callback, int msgId)
{
if (callback == null || msgId < 0)
return;
Debug.Log("注册消息成功!");
if (callbackDic.ContainsKey(msgId))
{
callbackDic[msgId] += callback;
}
else
{
callbackDic.Add(msgId, callback);
}
}
分发广播消息
分发消息时同样需要考虑ID是否存在,消息内容是否完整,可以节省很多效率。
“=>”为Lambda表达式,就是根据传入的消息ID找到callbackDic中的事件,然后加入代办事件集合todoCallback的队列。
void PostMsg(Msg msg = null)
{
if (msg.msgId > 0 && callbackDic.ContainsKey(msg.msgId) && callbackDic[msg.msgId] != null)
{
lock (todoCallback)
{
todoCallback.Enqueue(() => callbackDic[msg.msgId](msg));
}
}
}
处理消息(更新消息)
void TodoCallbackUpdate()
{
if (todoCallback.Count <= 0)
return;
lock (todoCallback)
{
//**移除并且返回初始的对象**
Action a = todoCallback.Dequeue();
a.Invoke();
}
}
举个栗子:代办事件集合todoCallback就像一个代办清单,首先解决的是第一件事情,然后画线删除,接着做第二件事情,此时第一件事情已经做完了,第二件事情也就成为了初始事件,继续执行,直到把清单的事情都解决。
接收消息
private void MyCallBack(Msg msg)
{
switch (msg.msgId)
{
case 1:
DemoMsg demoMsg = msg as DemoMsg;
Debug.LogFormat("接受第1条消息成功!,id:{0},name:{1},age:{2}", demoMsg.msgId, demoMsg.m_Name, demoMsg.m_Age);
break;
case 2:
DemoMsg demoMsg2 = msg as DemoMsg;
Debug.LogFormat("接受第2条消息成功!,id:{0},name:{1},age:{2}", demoMsg2.msgId, demoMsg2.m_Name, demoMsg2.m_Age);
break;
}
}
测试过程
注册消息
将ID为1和2的消息分别注册到callbackDic 中
private void Start()
{
RegiestMsg(MyCallBack, new int[] { 1, 2 });
}
分发消息和更新消息
private void Update()
{
if (Input.GetKeyDown(KeyCode.Space))
{
DemoMsg msg = new DemoMsg(1, "admin1", 21, this);
PostMsg(msg);
DemoMsg msg2 = new DemoMsg(2, "admin2", 22, this);
PostMsg(msg2);
}
TodoCallbackUpdate();
}
运行程序时出现两次“消息注册成功”!
按下“空格”,接收两条消息。
PS:按下空格的瞬间完成了“发送消息”和接收消息的两个过程,大家仔细体会一下!
整体消息处理流程到这里已经结束了,希望能遇到更多志同道合的朋友一起学习交流,大家加油哦!