事件觸發器作為unity常用的子產品解耦工具,其主要功能有三點:
訂閱事件
移除事件
事件觸發,并傳給監聽的回調方法
之前在網上看了很多文章,通常是用一個消息體對象作為回調參數,但是我個人還是比較喜歡使用泛型的方式進行回調,參考了之前項目的工具類,便動手開始實作。話不多說,先上代碼:
using System.Collections;
using System.Collections.Generic;
public class ObserverEvents
{
Dictionary actions = null;
///
/// 訂閱
///
public void Subscribe(string eventName, object action)
{
if (actions == null)
actions = new Dictionary();
ArrayList callback;
if (actions.TryGetValue(eventName, out callback))
{
if (!callback.Contains(action))
callback.Add(action);
}
else
{
callback = new ArrayList();
callback.Add(action);
actions[eventName] = callback;
}
}
///
/// 登出整個事件
///
public void Unsubscribe(string eventName)
{
if (actions == null) return;
ArrayList callback;
if (actions.TryGetValue(eventName, out callback))
{
callback.Clear();
actions.Remove(eventName);
}
}
///
/// 登出某一事件中的單個回調
///
///
///
public void Unsubscribe(string eventName, object action)
{
if (actions == null) return;
ArrayList callback;
if (actions.TryGetValue(eventName, out callback))
{
if (callback.Contains(action))
{
callback.Remove(action);
if (callback.Count == 0)
actions.Remove(eventName);
}
}
}
public ArrayList GetActions(string eventName)
{
if (actions == null) return null;
ArrayList callBack;
if (actions.TryGetValue(eventName, out callBack))
return callBack;
return null;
}
}
ObserverEvents事件容器類,用于存儲參數個數一樣的不同僚件
using System;
using System.Collections;
using System.Collections.Generic;
///
/// 事件觸發器
///
public class EventDispather
: Singleton //注釋:這裡其實是Singleton 但是簡書上Singleton後面加上'<>'就沒有高亮了,不懂,有哪位兄弟能告訴一下嗎?
{
private EventDispather() { }
///
/// 建立參數個數不同的事件容器
///
private ObserverEvents events = new ObserverEvents();
private ObserverEvents eventsT1 = new ObserverEvents();
private ObserverEvents eventsT2 = new ObserverEvents();
private ObserverEvents eventsT3 = new ObserverEvents();
#region 事件的訂閱
public void SubscribeEvent(string eventName, Action act)
{
events.Subscribe(eventName, act);
}
public void SubscribeEvent(string eventName, Action act)
{
eventsT1.Subscribe(eventName, act);
}
public void SubscribeEvent(string eventName, Action act)
{
eventsT2.Subscribe(eventName, act);
}
public void SubscribeEvent(string eventName, Action act)
{
eventsT3.Subscribe(eventName, act);
}
#endregion
#region 登出事件
public void Unsubscribe(string eventName, Action act)
{
events.Unsubscribe(eventName, act);
}
public void Unsubscribe(string eventName, Action act)
{
eventsT1.Unsubscribe(eventName, act);
}
public void Unsubscribe(string eventName, Action act)
{
eventsT2.Unsubscribe(eventName, act);
}
public void Unsubscribe(string eventName, Action act)
{
eventsT3.Unsubscribe(eventName, act);
}
public void RemoveEvent(string eventName)
{
events.Unsubscribe(eventName);
eventsT1.Unsubscribe(eventName);
eventsT2.Unsubscribe(eventName);
eventsT3.Unsubscribe(eventName);
}
#endregion
#region 事件觸發
public void PostEvent(string eventNme)
{
var actions = events.GetActions(eventNme);
if (actions != null)
{
for (int i = actions.Count - 1; i >= 0; i--)
{
var action = actions[i];
if (action == null)
actions.Remove(action);
else
{
var act = action as Action;
if (act != null)
act(eventNme);
}
}
}
}
public void PostEvent(string eventNme, T param)
{
var actions = eventsT1.GetActions(eventNme);
if (actions != null)
{
for (int i = actions.Count - 1; i >= 0; i--)
{
var action = actions[i];
if (action == null)
actions.Remove(action);
else
{
var act = action as Action;
if (act != null)
act(eventNme, param);
}
}
}
}
public void PostEvent(string eventNme, T1 param1, T2 param2)
{
var actions = events.GetActions(eventNme);
if (actions != null)
{
for (int i = actions.Count - 1; i >= 0; i--)
{
var action = actions[i];
if (action == null)
actions.Remove(action);
else
{
var act = action as Action;
if (act != null)
act(eventNme, param1, param2);
}
}
}
}
public void PostEvent(string eventNme, T1 param1, T2 param2, T3 param3)
{
var actions = events.GetActions(eventNme);
if (actions != null)
{
for (int i = actions.Count - 1; i >= 0; i--)
{
var action = actions[i];
if (action == null)
actions.Remove(action);
else
{
var act = action as Action;
if (act != null)
act(eventNme, param1, param2, param3);
}
}
}
}
#endregion
}
EventDispather使用單例模闆,具體實作請看之前的分享。
EventDispather内部建立了4個ObserverEvents事件容器,分别對應無參和至多3個參數的事件(PS:如果想更多參數的可以自行擴充),然後根據對應的事件進行注冊、查找與回調
測試代碼
string event_name = "test";
Action act0 = (name) =>
{
Debug.Log(name);
};
Action act1 = (name, content) =>
{
Debug.Log(name + " string: " + content);
};
Action act2 = (name, num) =>
{
Debug.Log(name + " num: " + num);
};
//注冊事件
EventDispather.Instance.SubscribeEvent(event_name, act0);
EventDispather.Instance.SubscribeEvent(event_name, act1);
EventDispather.Instance.SubscribeEvent(event_name, act2);
//事件送出
EventDispather.Instance.PostEvent(event_name);
EventDispather.Instance.PostEvent(event_name, "你好");
EventDispather.Instance.PostEvent(event_name, 521);
//登出事件
EventDispather.Instance.Unsubscribe(event_name, act0);
EventDispather.Instance.Unsubscribe(event_name, act1);
EventDispather.Instance.Unsubscribe(event_name, act2);
測試結果
test
test string: 你好
test num: 521
是不是感覺很easy~
但是對于我們程式員來說不隻是要掌握更多的記住,更要能夠溫故知新,隻有每天不斷的學習才不會原地踏步,被世界遠遠的甩在身後。
最後送上我喜歡的一句話:
放棄并不難,但堅持一定很酷 !