事件系统对于游戏项目来说是必不可少的系统模块,它能够有效地降低代码的耦合度。
using System;
using System.Collections.Generic;
namespace TEngine.Runtime
{
/// <summary>
/// 事件数据
/// </summary>
class DEventDelegateData
{
/// <summary>
/// 事件ID
/// </summary>
private int m_eventType = 0;
/// <summary>
/// 该事件所有的委托回调列表
/// </summary>
public List<Delegate> m_listExist = new List<Delegate>();
/// <summary>
/// 待新增的回调列表
/// </summary>
private List<Delegate> m_addList = new List<Delegate>();
/// <summary>
/// 待移除的回调列表
/// </summary>
private List<Delegate> m_deleteList = new List<Delegate>();
/// <summary>
/// 是否在执行回调中
/// </summary>
private bool m_isExcute = false;
/// <summary>
/// 是否已经脏了
/// </summary>
private bool m_dirty = false;
public DEventDelegateData(int evnetType)
{
m_eventType = evnetType;
}
/// <summary>
/// 添加事件回调
/// </summary>
/// <param name="handler"></param>
/// <returns></returns>
public bool AddHandler(Delegate handler)
{
if (m_listExist.Contains(handler))
{
Log.Fatal("Repeated Add Handler");
return false;
}
if (m_isExcute)
{
m_dirty = true;
m_addList.Add(handler);
}
else
{
m_listExist.Add(handler);
}
return true;
}
/// <summary>
/// 移除事件回调
/// </summary>
/// <param name="hander"></param>
public void RmvHandler(Delegate hander)
{
if (m_isExcute)
{
m_dirty = true;
m_deleteList.Add(hander);
}
else
{
if (!m_listExist.Remove(hander))
{
Log.Fatal("Delete handle failed, not exist, EventId: {0}", StringId.HashToString(m_eventType));
}
}
}
/// <summary>
/// 检查事件的委托回调是否发生了修改,如果有,则把新增的加入、待移除的除掉
/// </summary>
private void CheckModify()
{
m_isExcute = false;
if (m_dirty)
{
for (int i = 0; i < m_addList.Count; i++)
{
m_listExist.Add(m_addList[i]);
}
m_addList.Clear();
for (int i = 0; i < m_deleteList.Count; i++)
{
m_listExist.Remove(m_deleteList[i]);
}
m_deleteList.Clear();
}
}
/// <summary>
/// 执行回调【无参数】
/// </summary>
public void Callback()
{
m_isExcute = true;
for (var i = 0; i < m_listExist.Count; i++)
{
var d = m_listExist[i];
Action action = d as Action;
if (action != null)
{
action();
}
}
CheckModify();
}
/// <summary>
/// 执行回调【一个参数】
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="arg1">参数</param>
public void Callback<T>(T arg1)
{
m_isExcute = true;
for (var i = 0; i < m_listExist.Count; i++)
{
var d = m_listExist[i];
var action = d as Action<T>;
if (action != null)
{
action(arg1);
}
}
CheckModify();
}
/// <summary>
/// 执行回调【2个参数】
/// </summary>
/// <typeparam name="T"></typeparam>
/// <typeparam name="U"></typeparam>
/// <param name="arg1">参数1</param>
/// <param name="arg2">参数2</param>
public void Callback<T, U>(T arg1, U arg2)
{
m_isExcute = true;
for (var i = 0; i < m_listExist.Count; i++)
{
var d = m_listExist[i];
var action = d as Action<T, U>;
if (action != null)
{
action(arg1, arg2);
}
}
CheckModify();
}
/// <summary>
/// 执行回调【3个参数】
/// </summary>
/// <typeparam name="T"></typeparam>
/// <typeparam name="U"></typeparam>
/// <typeparam name="V"></typeparam>
/// <param name="arg1">参数1</param>
/// <param name="arg2">参数2</param>
/// <param name="arg3">参数3</param>
public void Callback<T, U, V>(T arg1, U arg2, V arg3)
{
m_isExcute = true;
for (var i = 0; i < m_listExist.Count; i++)
{
var d = m_listExist[i];
var action = d as Action<T, U, V>;
if (action != null)
{
action(arg1, arg2, arg3);
}
}
CheckModify();
}
/// <summary>
/// 执行回调【4个参数】
/// </summary>
/// <typeparam name="T"></typeparam>
/// <typeparam name="U"></typeparam>
/// <typeparam name="V"></typeparam>
/// <typeparam name="W"></typeparam>
/// <param name="arg1">参数1</param>
/// <param name="arg2">参数2</param>
/// <param name="arg3">参数3</param>
/// <param name="arg4">参数4</param>
public void Callback<T, U, V, W>(T arg1, U arg2, V arg3, W arg4)
{
m_isExcute = true;
for (var i = 0; i < m_listExist.Count; i++)
{
var d = m_listExist[i];
var action = d as Action<T, U, V, W>;
if (action != null)
{
action(arg1, arg2, arg3, arg4);
}
}
CheckModify();
}
/// <summary>
/// 执行回调【5个参数】
/// </summary>
/// <typeparam name="T"></typeparam>
/// <typeparam name="U"></typeparam>
/// <typeparam name="V"></typeparam>
/// <typeparam name="W"></typeparam>
/// <typeparam name="X"></typeparam>
/// <param name="arg1">参数1</param>
/// <param name="arg2">参数2</param>
/// <param name="arg3">参数3</param>
/// <param name="arg4">参数4</param>
/// <param name="arg5">参数5</param>
public void Callback<T, U, V, W, X>(T arg1, U arg2, V arg3, W arg4, X arg5)
{
m_isExcute = true;
for (var i = 0; i < m_listExist.Count; i++)
{
var d = m_listExist[i];
var action = d as Action<T, U, V, W, X>;
if (action != null)
{
action(arg1, arg2, arg3, arg4, arg5);
}
}
CheckModify();
}
}
/// <summary>
/// 事件注册分发器
/// </summary>
class DEventDispatcher
{
/// <summary>
/// 事件字典列表
/// </summary>
static Dictionary<int, DEventDelegateData> m_eventTable = new Dictionary<int, DEventDelegateData>();
#region 事件管理接口
/// <summary>
/// 添加事件监听
/// </summary>
/// <param name="eventType">事件ID</param>
/// <param name="handler">回调</param>
/// <returns></returns>
public bool AddEventListener(int eventType, Delegate handler)
{
DEventDelegateData data;
if (!m_eventTable.TryGetValue(eventType, out data))
{
data = new DEventDelegateData(eventType);
m_eventTable.Add(eventType, data);
}
return data.AddHandler(handler);
}
/// <summary>
/// 注销事件回调
/// </summary>
/// <param name="eventType"></param>
/// <param name="handler"></param>
public void RemoveEventListener(int eventType, Delegate handler)
{
DEventDelegateData data;
if (m_eventTable.TryGetValue(eventType, out data))
{
data.RmvHandler(handler);
}
}
#endregion
#region 事件分发接口
/// <summary>
/// 事件发送【无参数】
/// </summary>
/// <param name="eventType">事件ID</param>
public void Send(int eventType)
{
DEventDelegateData d;
if (m_eventTable.TryGetValue(eventType, out d))
{
d.Callback();
}
}
/// <summary>
/// 事件发送【1个参数】
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="eventType">事件ID</param>
/// <param name="arg1">参数1</param>
public void Send<T>(int eventType, T arg1)
{
DEventDelegateData d;
if (m_eventTable.TryGetValue(eventType, out d))
{
d.Callback(arg1);
}
}
/// <summary>
/// 事件发送【2个参数】
/// </summary>
/// <typeparam name="T"></typeparam>
/// <typeparam name="U"></typeparam>
/// <param name="eventType">事件ID</param>
/// <param name="arg1">参数1</param>
/// <param name="arg2">参数2</param>
public void Send<T, U>(int eventType, T arg1, U arg2)
{
DEventDelegateData d;
if (m_eventTable.TryGetValue(eventType, out d))
{
d.Callback(arg1, arg2);
}
}
/// <summary>
/// 事件发送【3个参数】
/// </summary>
/// <typeparam name="T"></typeparam>
/// <typeparam name="U"></typeparam>
/// <typeparam name="V"></typeparam>
/// <param name="eventType">事件ID</param>
/// <param name="arg1">参数1</param>
/// <param name="arg2">参数2</param>
/// <param name="arg3">参数3</param>
public void Send<T, U, V>(int eventType, T arg1, U arg2, V arg3)
{
DEventDelegateData d;
if (m_eventTable.TryGetValue(eventType, out d))
{
d.Callback(arg1, arg2, arg3);
}
}
/// <summary>
/// 事件发送【4个参数】
/// </summary>
/// <typeparam name="T"></typeparam>
/// <typeparam name="U"></typeparam>
/// <typeparam name="V"></typeparam>
/// <typeparam name="W"></typeparam>
/// <param name="eventType">事件ID</param>
/// <param name="arg1">参数1</param>
/// <param name="arg2">参数2</param>
/// <param name="arg3">参数3</param>
/// <param name="arg4">参数4</param>
public void Send<T, U, V, W>(int eventType, T arg1, U arg2, V arg3, W arg4)
{
DEventDelegateData d;
if (m_eventTable.TryGetValue(eventType, out d))
{
d.Callback(arg1, arg2, arg3, arg4);
}
}
/// <summary>
/// 事件发送【5个参数】
/// </summary>
/// <typeparam name="T"></typeparam>
/// <typeparam name="U"></typeparam>
/// <typeparam name="V"></typeparam>
/// <typeparam name="W"></typeparam>
/// <typeparam name="X"></typeparam>
/// <param name="eventType">事件ID</param>
/// <param name="arg1">参数1</param>
/// <param name="arg2">参数2</param>
/// <param name="arg3">参数3</param>
/// <param name="arg4">参数4</param>
/// <param name="arg5">参数5</param>
public void Send<T, U, V, W, X>(int eventType, T arg1, U arg2, V arg3, W arg4, X arg5)
{
DEventDelegateData d;
if (m_eventTable.TryGetValue(eventType, out d))
{
d.Callback(arg1, arg2, arg3, arg4, arg5);
}
}
#endregion
}
}
上面是包含事件的注册、注销以及事件的分发等接口的封装。