Unity遊戲框架搭建筆記---強類型局部消息系統

前面幾篇基礎文章

Unity遊戲框架搭建筆記---測試驅動,UnityTestRunner

Unity遊戲框架搭建筆記---強類型消息系統(私以爲最佳實踐)

Unity遊戲框架搭建筆記---強類型消息系統(複用廣播)

 

 

局部的消息系統,慣例先放使用方法。

public class Test : MonoBehaviour 
{
    private IEventBroadcaster broadcaster;
    private EventBroadcaster _eventBroadcaster;
    void Start()
    {
        _eventBroadcaster = new EventBroadcaster();
        broadcaster = _eventBroadcaster;
        broadcaster.Register<string>(EventBroadcaster.NAME_CHANGE,OnNameChange);
    }

    private int i;
    
    private void Update()
    {
        if (Input.GetKeyDown(KeyCode.Space))
        {
            i++;
            _eventBroadcaster.Name = i.ToString();
        }
    }

    private void OnNameChange(string name)
    {
        print(name);
    }
}

//需要繼承IEventBroadcaster
public class EventBroadcaster : IEventBroadcaster
{
    public const string NAME_CHANGE = "NAME_CHANGE";

    private string name;

    public string Name
    {
        get => name;
        set
        {
            name = value;
            LocalEventService.TriggerEvent(this, NAME_CHANGE, name);
        }
    }
}

實現思路跟全局的消息系統類似,只不過加了個IEventBroadcaster來做key,下面放代碼

        class MulCallbackContainer<T> : ICallBackBase
        {
            public string Tag;
            public Action<T> Action;

            public MulCallbackContainer(string tag, Action<T> action)
            {
                Tag = tag;
                Action = action;
            }

            public void Trigger(string tag, T value)
            {
                if(tag != Tag ) return;
                Action(value);
            }
        }       
        internal static void Register<T>(IEventBroadcaster eventBroadcaster, string tag, Action<T> cb)
        {
            var type = typeof(T);
            
            if (!_subscribersDic.TryGetValue(eventBroadcaster, out var dic))
            {
                dic = new Dictionary<Type, List<ICallBackBase>>();
                _subscribersDic.Add(eventBroadcaster, dic);
            }
            if (!dic.TryGetValue(type, out var list))
            {
                list = new List<ICallBackBase>();
                dic.Add(type, list);
            }
            if (!CallBackExists(list, tag, cb))
            {
                ICallBackBase callBackBase = new MulCallbackContainer<T>(tag, cb);
                list.Add(callBackBase);
            }
            else
            {
                Log.Warning("repeated register....");
            }
        }

        public static void TriggerEvent<T>(IEventBroadcaster eventBroadcaster, string tag, T value)
        {
            var type = typeof(T);

            if (!_subscribersDic.TryGetValue(eventBroadcaster, out var dic)) return;
            if (!dic.TryGetValue(type, out var list)) return;
            // ReSharper disable once PossibleInvalidCastExceptionInForeachLoop
            foreach (MulCallbackContainer<T> callbackContainer in list)
            {
                callbackContainer.Trigger(tag, value);
            }
        }

只放了註冊和觸發,並沒有很複雜的邏輯,下面放單元測試代碼

        [Test]
        public void 局部事件()
        {
            IEventBroadcaster eventBroadcaster = Substitute.For<IEventBroadcaster>();
            eventBroadcaster.Register<AMsg>(AMsgCB);
            eventBroadcaster.TriggerEvent(new AMsg());
            Assert.IsTrue(IsCall);
        }

        private bool IsCall = false;
        private void AMsgCB(AMsg obj)
        {
            IsCall = true;
        }

All Success! 消息系統基本就這樣

GIT--https://github.com/so-sos-so/SoF

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章