喫雞遊戲——消息處理

前面寫過一篇消息處理,那是是很早寫的。之前的那種做法是一個字典中鍵值爲string類型,值爲Action來實現類與類之間解耦。這種方式存在一定的弊端,用字符串來做鍵書管理起來並不是很好,約束性不強。這裏可以用type代替,這裏用結構體的type來代替前面的字符串來進行強約束。

這裏跟以前一樣得有一個字典,字典的鍵爲Type,值肯定是一個方法的指針,這裏可以用Action,同樣也可以用接口,Action約束性不夠強,名字可以隨便取,代碼管理混亂,所以這裏還是用接口來實現這樣一個方法。

首先得定義一個接口,將它取名爲:

 public interface IEventListenerBase { };

 public interface IEventListener<T> : IEventListenerBase
 {
     void OnEvent(T eventType);
 }

如果我們只用Action來代替的話 那麼在觀察者哪裏的方法名字就可以隨便取名字,約束性不是很強。如果一個類作爲訂閱者的話那麼就需要繼承這樣一個接口,表示它是一個觀察者。我們只需要在觀察者裏面註冊事件處理的事件,然後目標只需要觸發對應得消息即可。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;

namespace Tool
{

    public static class EventManager
    {


        private static Dictionary<Type, List<IEventListenerBase>> _subscribersList;

        static EventManager()
        {
            _subscribersList = new Dictionary<Type, List<IEventListenerBase>>();
        }


        public static void AddListener<T>(IEventListener<T> listener) where T:struct
        {

            Type eventType = typeof(T);
            if (!_subscribersList.ContainsKey(eventType))
                _subscribersList[eventType] = new List<IEventListenerBase>();

            if (!SubscriptionExists(eventType, listener))
                _subscribersList[eventType].Add(listener);

        }


        public static void RemoveListener<T>(IEventListener<T> listener) where T : struct
        {
            Type eventType = typeof(T);
            if (!_subscribersList.ContainsKey(eventType))
            {
                return;
            }
            List<IEventListenerBase> subscriberList = _subscribersList[eventType];
            for (int i = 0; i < subscriberList.Count; i++)
            {
                if (subscriberList[i] == listener)
                {
                    subscriberList.Remove(subscriberList[i]);

                    if (subscriberList.Count == 0)
                        _subscribersList.Remove(eventType);

                    return;
                }
            }
        }


        public static void TriggerEvent<T>(T newEvent) where T : struct
        {

            List<IEventListenerBase> list;
            if (!_subscribersList.TryGetValue(typeof(T), out list))
                return;
            for (int i = 0; i < list.Count; i++)
            {
                var eventListener = list[i] as IEventListener<T>;
                if (eventListener != null) eventListener.OnEvent(newEvent);
            }
        }


        private static bool SubscriptionExists(Type type, IEventListenerBase receiver)
        {
            List<IEventListenerBase> receivers;
            if (!_subscribersList.TryGetValue(type, out receivers)) return false;
            bool exists = false;
            for (int i = 0; i < receivers.Count; i++)
            {
                if (receivers[i] == receiver)
                {
                    exists = true;
                    break;
                }
            }
            return exists;
        }


    }


    public static class EventRegister
    {
       
        public static void EventStartListening<T>(this IEventListener<T> caller) where T : struct
        {
            EventManager.AddListener<T>(caller);
        }

        public static void EventStopListening<T>(this IEventListener<T> caller) where T : struct
        {
            EventManager.RemoveListener<T>(caller);
        }

    }





    public interface IEventListenerBase { };

    public interface IEventListener<T> : IEventListenerBase
    {
        void OnEvent(T eventType);
    }



}
該類主要有3個方法,分別爲AddListener,RemoveListener,TriggerEvent,他們分別是註冊事件,解綁事件,和觸發一個事件。用法也比較簡單我就不贅述,如果還有什麼疑問,可以聯繫我qq:1850761495
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章