其實事件系統(tǒng)這個東西有好多好多輪子了翁都,我只是又自己造了一個碍论。
相比于我之前看到的一些事件系統(tǒng),優(yōu)點就在于不用蛋疼的轉(zhuǎn)類型吧柄慰。
不足之處鳍悠,還希望大佬能夠指點。
下面直接上代碼
- 事件系統(tǒng)
using System.Collections.Generic;
namespace SFw.Core
{
/// <summary>
/// 事件處理委托
/// </summary>
/// <param name="args">事件參數(shù)</param>
/// <typeparam name="T">事件類型</typeparam>
public delegate void EventHandler<in T>(T args) where T : Event<T>;
/// <summary>
/// 事件接口
/// </summary>
public interface IEvent//為了解決EventCrossThreadHelper中事件數(shù)據(jù)的存儲
{
/// <summary>
/// 事件發(fā)送者
/// </summary>
object Sender { get; set; }
/// <summary>
/// 觸發(fā)事件
/// </summary>
/// <param name="sender">傳參自動修改Sender</param>
void Trigger(object sender = null);
}
/// <summary>
/// 事件基類
/// </summary>
/// <typeparam name="T">事件類型</typeparam>
public abstract partial class Event<T> : IEvent where T : Event<T>, IEvent
{
/// <summary>
/// 觸發(fā)事件
/// </summary>
/// <param name="sender">傳參自動修改Sender</param>
public void Trigger(object sender = null)
{
Sender = sender ?? Sender;
Trigger((T)this);
}
/// <summary>
/// 事件發(fā)送方
/// </summary>
public object Sender { get; set; }
}
/// <summary>
/// 事件管理類
/// </summary>
/// <typeparam name="T">事件類型</typeparam>
public partial class Event<T> : IEvent where T : Event<T>, IEvent
{
/// <summary>
/// 添加事件
/// </summary>
/// <param name="eventHandler"></param>
public static void Add(EventHandler<T> eventHandler)
{
_event += eventHandler;
}
/// <summary>
/// 移除事件
/// </summary>
/// <param name="eventHandler"></param>
public static void Remove(EventHandler<T> eventHandler)
{
_event -= eventHandler;
}
/// <summary>
/// 觸發(fā)事件
/// </summary>
/// <param name="args"></param>
public static void Trigger(T args = default)
{
_event?.Invoke(args);
}
/// <summary>
/// 支線程想主線程觸發(fā)事件:主要是為了解決網(wǎng)絡部分數(shù)據(jù)處理的問題
/// </summary>
/// <param name="args"></param>
public static void JumpTrigger(T args = default)
{
EventCrossThreadHelper.AddEvent(args);
}
private static event EventHandler<T> _event;
}
/// <summary>
/// 跨線程觸發(fā)事件輔助類(主要用于將網(wǎng)絡/串口數(shù)據(jù)同步到主線程)
/// </summary>
public class EventCrossThreadHelper
{
/// <summary>
/// 主線程需要循環(huán)調(diào)用此方法
/// </summary>
public static void MainThreadUpdate()
{
if (_eventQueue.Count > 0)
{
lock (_lockHelper)
{
int count = 0;
while (_eventQueue.Count > 0 && count < MaxHandleCount)
{
_eventQueue.Dequeue()?.Trigger();
count++;
}
}
}
}
/// <summary>
/// 添加事件
/// </summary>
/// <param name="eventArg"></param>
public static void AddEvent(IEvent eventArg)
{
lock (_lockHelper)
{
_eventQueue.Enqueue(eventArg);
}
}
/// <summary>
/// 每一幀處理事件的最大數(shù)量
/// </summary>
public static int MaxHandleCount = 30;
static Queue<IEvent> _eventQueue = new Queue<IEvent>();
static object _lockHelper = new object();
}
}
- 使用
using SFw.Core;
using UnityEngine;
public class Test : MonoBehaviour
{
void Start()
{
EventTest.Add(Handler);
}
private void Update()
{
if (Input.GetKeyDown(KeyCode.A))
{
EventTest.Trigger();//觸發(fā)方式1
var args = new EventTest {Count = 10};
EventTest.Trigger(args);//觸發(fā)方式2
args.Trigger();//觸發(fā)方式3
var sender = new object();
args.Trigger(sender);//觸發(fā)方式4
}
}
private void Handler(EventTest args)
{
Debug.Log(args);
Debug.Log(args?.Sender);
Debug.Log(args?.Count);
}
}
ps. 之所以搞這個東西出來坐搔,是因為寫事件相關的代碼時藏研,總是要蛋疼的轉(zhuǎn)類型,實在感覺有些煩概行。不足之處蠢挡,還請各位大佬指正。