事件系统
- Unity
- 2024-07-22
- 374热度
- 0评论
一、 委托与事件
1.1 委托
delegate是一个关键字,用来声明委托类型,Delegate是一个类,是委托类型的基类,但只有系统和编辑器可以显示地从Delegate类或者MulticastDelegate类派生,通常我们使用delegate关键字来定义委托类型。
委托是一种引用类型(类似于函数指针),允许我们封装方法的引用,通过使用委托,我们可以将方法作为参数传递给其他方法,或者将方法类型组合在一起,从而实现更加灵活地编程。
1.2 事件
事件是一种特殊的委托实例化,用于外部接口,事件基于委托而并非委托,可以看成委托的代理,外部类只能通过+=
和-=
来注册和注销事件,而不能主动触发事件。
1.3 委托与事件的区别
- 事件是对委托的包装,保护了委托字段,对外不开放,只提供添加和移除事件的方法。
- 事件的触发是在对象的内部。
- 事件是一种更安全、更易用的方式来处理回调。
二、事件系统
- EventManager: 事件管理系统类, 包括了注册、注销、广播事件, 其中能够监听5个以内的事件
using LFrameWork;
using System;
using System.Collections.Generic;
namespace Client.Event
{
public class EventManager
{
private Dictionary<EventType, Delegate> _eventTable;
protected override void OnInit()
{
_eventTable = new Dictionary<EventType, Delegate>();
}
private void OnListenerAdding(EventType eventType, Delegate action)
{
if (!_eventTable.ContainsKey(eventType))
{
_eventTable.Add(eventType, null);
}
Delegate @delegate = _eventTable[eventType];
if (@delegate != null && @delegate.GetType() != action.GetType())
{
GameLogger.LogError($"事件添加的类型不同, {eventType} DelagateType{@delegate.GetType()} actionType {action.GetType()}");
}
}
public void RegisterEvent(EventType eventType, CallBack action)
{
OnListenerAdding(eventType, action);
if (_eventTable.TryGetValue(eventType, out var @delegate))
{
_eventTable[eventType] = (CallBack)@delegate + action;
}
}
public void RegisterEvent<T>(EventType eventType, CallBack<T> action)
{
OnListenerAdding(eventType, action);
if (_eventTable.TryGetValue(eventType, out var @delegate))
{
_eventTable[eventType] = (CallBack<T>)@delegate + action;
}
}
public void RegisterEvent<T, X>(EventType eventType, CallBack<T, X> action)
{
OnListenerAdding(eventType, action);
if (_eventTable.TryGetValue(eventType, out var @delegate))
{
_eventTable[eventType] = (CallBack<T, X>)@delegate + action;
}
}
public void RegisterEvent<T, X, Y>(EventType eventType, CallBack<T, X, Y> action)
{
OnListenerAdding(eventType, action);
if (_eventTable.TryGetValue(eventType, out var @delegate))
{
_eventTable[eventType] = (CallBack<T, X, Y>)@delegate + action;
}
}
public void RegisterEvent<T, X, Y, Z>(EventType eventType, CallBack<T, X, Y, Z> action)
{
OnListenerAdding(eventType, action);
if (_eventTable.TryGetValue(eventType, out var @delegate))
{
_eventTable[eventType] = (CallBack<T, X, Y, Z>)@delegate + action;
}
}
public void RegisterEvent<T, X, Y, Z,W>(EventType eventType, CallBack<T, X, Y, Z,W> action)
{
OnListenerAdding(eventType, action);
if (_eventTable.TryGetValue(eventType, out var @delegate))
{
_eventTable[eventType] = (CallBack<T, X, Y, Z, W>)@delegate + action;
}
}
private void OnListenerRemoving(EventType eventType, Delegate callBack)
{
if (_eventTable.ContainsKey(eventType))
{
Delegate @delegate = _eventTable[eventType];
if (@delegate == null)
{
GameLogger.LogError($"移除监听错误: 事件{eventType}没有对应的委托");
}
else if (@delegate.GetType() != callBack.GetType())
{
GameLogger.LogError($"移除监听错误: 尝试为事件{eventType}移除不同类型的委托,当前委托类型为{@delegate.GetType()},要移除的类型为{callBack.GetType()}");
}
else
{
GameLogger.LogError($"移除监听错误: 没有事件码 {eventType}");
}
}
}
private void OnListenerRemoved(EventType eventType)
{
if (_eventTable[eventType] == null) _eventTable.Remove(eventType);
}
public void UnRegisterEvent(EventType eventType, CallBack callBack)
{
OnListenerRemoving(eventType, callBack);
_eventTable[eventType] = (CallBack)_eventTable[eventType] - callBack;
OnListenerRemoved(eventType);
}
public void UnRegisterEvent<T>(EventType eventType, CallBack<T> callBack)
{
OnListenerRemoving(eventType, callBack);
_eventTable[eventType] = (CallBack<T>)_eventTable[eventType] - callBack;
OnListenerRemoved(eventType);
}
public void UnRegisterEvent<T, X>(EventType eventType, CallBack<T, X> callBack)
{
OnListenerRemoving(eventType, callBack);
_eventTable[eventType] = (CallBack<T, X>)_eventTable[eventType] - callBack;
OnListenerRemoved(eventType);
}
public void UnRegisterEvent<T, X, Y>(EventType eventType, CallBack<T, X, Y> callBack)
{
OnListenerRemoving(eventType, callBack);
_eventTable[eventType] = (CallBack<T, X, Y>)_eventTable[eventType] - callBack;
OnListenerRemoved(eventType);
}
public void UnRegisterEvent<T, X, Y, Z>(EventType eventType, CallBack<T, X, Y, Z> callBack)
{
OnListenerRemoving(eventType, callBack);
_eventTable[eventType] = (CallBack<T, X, Y, Z>)_eventTable[eventType] - callBack;
OnListenerRemoved(eventType);
}
public void UnRegisterEvent<T, X, Y, Z, W>(EventType eventType, CallBack<T, X, Y, Z, W> callBack)
{
OnListenerRemoving(eventType, callBack);
_eventTable[eventType] = (CallBack<T, X, Y, Z, W>)_eventTable[eventType] - callBack;
OnListenerRemoved(eventType);
}
public void BroadCast(EventType eventType)
{
try
{
if (_eventTable.TryGetValue(eventType, out var @delegate))
{
CallBack callBack = @delegate as CallBack;
callBack?.Invoke();
}
}
catch
{
GameLogger.LogError($"BroadCast EventType {eventType} error");
}
}
public void BroadCast<T>(EventType eventType, T arg)
{
try
{
if (_eventTable.TryGetValue(eventType, out var @delegate))
{
CallBack<T> callBack = @delegate as CallBack<T>;
callBack?.Invoke(arg);
}
}
catch
{
GameLogger.LogError($"BroadCast EventType {eventType} error");
}
}
public void BroadCast<T, X>(EventType eventType, T arg1, X arg2)
{
try
{
if (_eventTable.TryGetValue(eventType, out var @delegate))
{
CallBack<T, X> callBack = @delegate as CallBack<T, X>;
callBack?.Invoke(arg1, arg2);
}
}
catch
{
GameLogger.LogError($"BroadCast EventType {eventType} error");
}
}
public void BroadCast<T, X, Y>(EventType eventType, T arg1, X arg2, Y arg3)
{
try
{
if (_eventTable.TryGetValue(eventType, out var @delegate))
{
CallBack<T, X, Y> callBack = @delegate as CallBack<T, X, Y>;
callBack?.Invoke(arg1, arg2, arg3);
}
}
catch
{
GameLogger.LogError($"BroadCast EventType {eventType} error");
}
}
public void BroadCast<T, X, Y, Z>(EventType eventType, T arg1, X arg2, Y arg3, Z arg4)
{
try
{
if (_eventTable.TryGetValue(eventType, out var @delegate))
{
CallBack<T, X, Y, Z> callBack = @delegate as CallBack<T, X, Y, Z>;
callBack?.Invoke(arg1, arg2, arg3, arg4);
}
}
catch
{
GameLogger.LogError($"BroadCast EventType {eventType} error");
}
}
public void BroadCast<T, X, Y, Z, W>(EventType eventType, T arg1, X arg2, Y arg3, Z arg4, W arg5)
{
try
{
if (_eventTable.TryGetValue(eventType, out var @delegate))
{
CallBack<T, X, Y, Z, W> callBack = @delegate as CallBack<T, X, Y, Z, W>;
callBack?.Invoke(arg1, arg2, arg3, arg4, arg5);
}
}
catch
{
GameLogger.LogError($"BroadCast EventType {eventType} error");
}
}
protected override void OnRelease()
{
_eventTable.Clear();
}
}
}
-
EventType: 事件系统类型(枚举值)
namespace Client.Event { public enum EventType { Main, } }
-
CallBack: 事件委托类型
namespace Client.Event { public delegate void CallBack(); public delegate void CallBack
(T arg); public delegate void CallBack (T arg1, X arg2); public delegate void CallBack (T arg1, X arg2, Y arg3); public delegate void CallBack (T arg1, X arg2, Y arg3, Z arg4); public delegate void CallBack (T arg1, X arg2, Y arg3, Z arg4, W arg5); }