前面寫過一篇消息處理,那是是很早寫的。之前的那種做法是一個字典中鍵值爲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