吃鸡游戏——消息处理

前面写过一篇消息处理,那是是很早写的。之前的那种做法是一个字典中键值为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
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章