我们发现,在申请对象部分可以简化成如下:
// var msgRecord = MsgRecord.Allocate(); // // msgRecord.Name = msgName; // msgRecord.OnMsgReceived = onMsgReceived; // // mMsgRecorder.Add(msgRecord); mMsgRecorder.Add(MsgRecord.Allocate(msgName, onMsgReceived));只需要向 MsgRecord.Allocate 增加参数,代码如下:
public static MsgRecord Allocate(string msgName,Action<object> onMsgReceived) { MsgRecord retMsgRecord = null; retMsgRecord = mMsgRecordPool.Count > 0 ? mMsgRecordPool.Pop() : new MsgRecord(); retMsgRecord.Name = msgName; retMsgRecord.OnMsgReceived = onMsgReceived; return retMsgRecord; }代码不难,那么到这里,我们的完整的第十三个示例就写完了。
完整示例代码如下:
using System; using System.Collections; using System.Collections.Generic; using UnityEngine; namespace QFramework { public abstract partial class MonoBehaviourSimplify { List<MsgRecord> mMsgRecorder = new List<MsgRecord>(); private class MsgRecord { private static readonly Stack<MsgRecord> mMsgRecordPool = new Stack<MsgRecord>(); public static MsgRecord Allocate(string msgName,Action<object> onMsgReceived) { MsgRecord retMsgRecord = null; retMsgRecord = mMsgRecordPool.Count > 0 ? mMsgRecordPool.Pop() : new MsgRecord(); retMsgRecord.Name = msgName; retMsgRecord.OnMsgReceived = onMsgReceived; return retMsgRecord; } public void Recycle() { Name = null; OnMsgReceived = null; mMsgRecordPool.Push(this); } public string Name; public Action<object> OnMsgReceived; } protected void RegisterMsg(string msgName, Action<object> onMsgReceived) { MsgDispatcher.Register(msgName, onMsgReceived); mMsgRecorder.Add(MsgRecord.Allocate(msgName, onMsgReceived)); } private void OnDestroy() { OnBeforeDestroy(); foreach (var msgRecord in mMsgRecorder) { MsgDispatcher.UnRegister(msgRecord.Name,msgRecord.OnMsgReceived); msgRecord.Recycle(); } mMsgRecorder.Clear(); } protected abstract void OnBeforeDestroy(); } public class MsgDistapcherInMonoBehaviourSimplify : MonoBehaviourSimplify { #if UNITY_EDITOR [UnityEditor.MenuItem("QFramework/13.消息机制集成到 MonoBehaviourSimplify", false, 14)] private static void MenuClicked() { UnityEditor.EditorApplication.isPlaying = true; new GameObject("MsgReceiverObj") .AddComponent<MsgDistapcherInMonoBehaviourSimplify>(); } #endif private void Awake() { RegisterMsg("Do", DoSomething); RegisterMsg("Do", DoSomething); RegisterMsg("DO1", _ => { }); RegisterMsg("DO2", _ => { }); RegisterMsg("DO3", _ => { }); } private IEnumerator Start() { MsgDispatcher.Send("Do","hello"); yield return new WaitForSeconds(1.0f); MsgDispatcher.Send("Do","hello1"); } void DoSomething(object data) { // do something Debug.LogFormat("Received Do msg:{0}",data); } protected override void OnBeforeDestroy() { } } }运行结果如下图:
菜单栏如下图:
目录如下图:
到这里我们可以进行一次导出了。
关于发送事件的简单封装在上一篇,我们在 MonoBehaviourSimplify 中集成了消息功能。而在做消息功能的过程中,又接触了对象池实现了一个非常简单版本。
今天呢我们在接着学习。
我们先回顾下 MonoBehaviourSimplify 中关于消息功能的使用方法。
注册消息,直接用 RegisterMsg,而注销则在 OnDestroy 的时候统一进行注销。
那么单独注销时候怎么办呢?这是第一个问题。
第二个问题是,发送消息,我们使用的是 MsgDispatcher.Send 这个方法。
和我们的注册消息的方法不是统一的。这是第二个问题。
第一个问题解决很简单,只要增加针对一个消息注销的方法就好了。
代码如下:
FindAll 是一个查询方法,在 mMsgRecorder 内查询出所有符合条件的项。代码没有太大的难度。