首次提交
This commit is contained in:
128
Assets/Scripts/NBC/Core/Runtime/Event/EventArgs.cs
Normal file
128
Assets/Scripts/NBC/Core/Runtime/Event/EventArgs.cs
Normal file
@@ -0,0 +1,128 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace NBC
|
||||
{
|
||||
/// <summary>
|
||||
/// 事件对象 用于派发事件传参数使用
|
||||
/// </summary>
|
||||
public class EventArgs
|
||||
{
|
||||
public EventArgs()
|
||||
{
|
||||
}
|
||||
|
||||
public EventArgs(string type)
|
||||
{
|
||||
Type = type;
|
||||
}
|
||||
|
||||
public EventArgs(string type, object data)
|
||||
{
|
||||
Type = type;
|
||||
Data = data;
|
||||
}
|
||||
|
||||
// private static readonly Queue<EventArgs> _poolQueue = new Queue<EventArgs>();
|
||||
|
||||
/// <summary>
|
||||
/// 派发事件的对象
|
||||
/// </summary>
|
||||
public IEventDispatcher Sender;
|
||||
|
||||
/// <summary>
|
||||
/// 派发事件夹带的普通参数
|
||||
/// </summary>
|
||||
public object Data;
|
||||
|
||||
/// <summary>
|
||||
/// 事件类型
|
||||
/// </summary>
|
||||
public string Type;
|
||||
|
||||
/// <summary>
|
||||
/// 是否停止事件派发
|
||||
/// </summary>
|
||||
public bool IsPropagationImmediateStopped;
|
||||
|
||||
/// <summary>
|
||||
/// 流转传递参数(用于高优先级往低优先级传递)
|
||||
/// </summary>
|
||||
public object TransmitData;
|
||||
|
||||
/// <summary>
|
||||
/// 停止一个事件的派发
|
||||
/// </summary>
|
||||
public void StopImmediatePropagation()
|
||||
{
|
||||
IsPropagationImmediateStopped = true;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 设置流转数据
|
||||
/// </summary>
|
||||
/// <param name="data">需要流转的数据</param>
|
||||
public void SetTransmitData(object data)
|
||||
{
|
||||
TransmitData = data;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 清理对象
|
||||
/// </summary>
|
||||
protected void Clean()
|
||||
{
|
||||
Data = null;
|
||||
IsPropagationImmediateStopped = false;
|
||||
}
|
||||
|
||||
public static T Create<T>(string type) where T : EventArgs, new()
|
||||
{
|
||||
EventArgs eventArgs;
|
||||
// if (_poolQueue.Count > 0)
|
||||
// {
|
||||
// eventArgs = _poolQueue.Dequeue();
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// var t = typeof(T);
|
||||
// eventArgs = Activator.CreateInstance(t) as EventArgs;
|
||||
// _poolQueue.Enqueue(eventArgs);
|
||||
// }
|
||||
var t = typeof(T);
|
||||
eventArgs = Activator.CreateInstance(t) as EventArgs;
|
||||
|
||||
if (eventArgs != null)
|
||||
{
|
||||
eventArgs.Type = type;
|
||||
}
|
||||
|
||||
return eventArgs as T;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 派发一个特定事件
|
||||
/// </summary>
|
||||
/// <param name="target">派发一个事件</param>
|
||||
/// <param name="type">事件类型</param>
|
||||
/// <param name="data">事件附带参数</param>
|
||||
public static void DispatchEvent(IEventDispatcher target, string type, object data)
|
||||
{
|
||||
var ev = Create<EventArgs>(type);
|
||||
ev.Data = data;
|
||||
target.DispatchEvent(ev);
|
||||
Release(ev);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 释放事件对象
|
||||
/// </summary>
|
||||
/// <param name="ev"></param>
|
||||
public static void Release(EventArgs ev)
|
||||
{
|
||||
ev.Clean();
|
||||
// _poolQueue.Enqueue(ev);
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Assets/Scripts/NBC/Core/Runtime/Event/EventArgs.cs.meta
Normal file
11
Assets/Scripts/NBC/Core/Runtime/Event/EventArgs.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 371d9cba4de694e47a6a6f28b7f0c956
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
217
Assets/Scripts/NBC/Core/Runtime/Event/EventDispatcher.cs
Normal file
217
Assets/Scripts/NBC/Core/Runtime/Event/EventDispatcher.cs
Normal file
@@ -0,0 +1,217 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace NBC
|
||||
{
|
||||
struct EventBin
|
||||
{
|
||||
public string type;
|
||||
public Action<EventArgs> listener;
|
||||
public object thisObject;
|
||||
public int priority;
|
||||
public EventDispatcher target;
|
||||
public bool dispatchOnce;
|
||||
}
|
||||
|
||||
public class EventDispatcher : IEventDispatcher
|
||||
{
|
||||
private readonly Dictionary<string, List<EventBin>>
|
||||
_dicEventListener = new Dictionary<string, List<EventBin>>();
|
||||
|
||||
// private Queue<EventBin> _curNeedDispatcherListeners;
|
||||
private readonly Stack<EventBin> _onceList = new Stack<EventBin>();
|
||||
|
||||
public IEventDispatcher On(string type, Action<EventArgs> listener, object caller, int priority = 0,
|
||||
bool once = false)
|
||||
{
|
||||
List<EventBin> list;
|
||||
if (HasEventListener(type))
|
||||
{
|
||||
list = _dicEventListener[type];
|
||||
}
|
||||
else
|
||||
{
|
||||
list = new List<EventBin>();
|
||||
_dicEventListener[type] = list;
|
||||
}
|
||||
|
||||
InsertEventBin(list, type, listener, caller, priority, once);
|
||||
return this;
|
||||
}
|
||||
|
||||
public IEventDispatcher Once(string type, Action<EventArgs> listener, object caller, int priority = 0)
|
||||
{
|
||||
On(type, listener, caller, priority, true);
|
||||
return this;
|
||||
}
|
||||
|
||||
public IEventDispatcher Off(string type, Action<EventArgs> listener, object caller)
|
||||
{
|
||||
RemoveListener(type, listener, caller);
|
||||
return this;
|
||||
}
|
||||
|
||||
public IEventDispatcher OffAll(string type = "")
|
||||
{
|
||||
if (type != "" && HasEventListener(type))
|
||||
{
|
||||
_dicEventListener.Remove(type);
|
||||
}
|
||||
else
|
||||
{
|
||||
_dicEventListener.Clear();
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public IEventDispatcher OffAllCaller(object caller)
|
||||
{
|
||||
List<EventBin> arr = new List<EventBin>();
|
||||
foreach (var v in _dicEventListener.Values)
|
||||
{
|
||||
foreach (var eventBin in v)
|
||||
{
|
||||
if (eventBin.thisObject == caller)
|
||||
{
|
||||
arr.Add(eventBin);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var e in arr)
|
||||
{
|
||||
RemoveListener(e.type, e.listener, e.thisObject);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public bool HasEventListener(string type)
|
||||
{
|
||||
return _dicEventListener.ContainsKey(type);
|
||||
}
|
||||
|
||||
public void DispatchEvent(EventArgs ev)
|
||||
{
|
||||
ev.Sender = this;
|
||||
notifyListener(ev);
|
||||
}
|
||||
|
||||
public bool DispatchEventWith(string type, object data = null)
|
||||
{
|
||||
if (HasEventListener(type))
|
||||
{
|
||||
EventArgs eventArgs = EventArgs.Create<EventArgs>(type);
|
||||
eventArgs.Data = data;
|
||||
DispatchEvent(eventArgs);
|
||||
EventArgs.Release(eventArgs);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
private bool InsertEventBin(List<EventBin> list, string type, Action<EventArgs> listener, object thisObject,
|
||||
int priority = 0, bool dispatchOnce = false)
|
||||
|
||||
{
|
||||
var insertIndex = -1;
|
||||
var length = list.Count;
|
||||
for (var i = 0; i < length; i++)
|
||||
{
|
||||
var bin = list[i];
|
||||
if (bin.listener == listener && bin.thisObject == thisObject && bin.target == this)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (insertIndex == -1 && bin.priority < priority)
|
||||
{
|
||||
insertIndex = i;
|
||||
}
|
||||
}
|
||||
|
||||
var eventBin = new EventBin
|
||||
{
|
||||
type = type,
|
||||
listener = listener,
|
||||
thisObject = thisObject,
|
||||
priority = priority,
|
||||
target = this,
|
||||
dispatchOnce = dispatchOnce
|
||||
};
|
||||
|
||||
if (insertIndex != -1)
|
||||
{
|
||||
list.Insert(insertIndex, eventBin);
|
||||
}
|
||||
else
|
||||
{
|
||||
list.Add(eventBin);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private void RemoveListener(string type, Action<EventArgs> listener, object caller)
|
||||
{
|
||||
if (HasEventListener(type))
|
||||
{
|
||||
RemoveEventBin(_dicEventListener[type], listener, caller);
|
||||
}
|
||||
}
|
||||
|
||||
private bool RemoveEventBin(List<EventBin> list, Action<EventArgs> listener, object caller)
|
||||
{
|
||||
var length = list.Count;
|
||||
for (var i = 0; i < length; i++)
|
||||
{
|
||||
var bin = list[i];
|
||||
if (bin.listener == listener && bin.thisObject == caller && bin.target == this)
|
||||
{
|
||||
list.RemoveAt(i);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private void notifyListener(EventArgs eventArgs)
|
||||
{
|
||||
if (!_dicEventListener.ContainsKey(eventArgs.Type)) return;
|
||||
var list = _dicEventListener[eventArgs.Type];
|
||||
var length = list.Count;
|
||||
if (length <= 0) return;
|
||||
var curNeedDispatcherListeners = new Queue<EventBin>();
|
||||
|
||||
var curIndex = 0;
|
||||
while (curIndex < list.Count)
|
||||
{
|
||||
var eventBin = list[curIndex];
|
||||
|
||||
curNeedDispatcherListeners.Enqueue(eventBin);
|
||||
curIndex++;
|
||||
}
|
||||
|
||||
while (curNeedDispatcherListeners.Count > 0)
|
||||
{
|
||||
var eventBin = curNeedDispatcherListeners.Dequeue();
|
||||
eventBin.listener?.Invoke(eventArgs);
|
||||
if (eventBin.dispatchOnce)
|
||||
{
|
||||
_onceList.Push(eventBin);
|
||||
}
|
||||
if(eventArgs.IsPropagationImmediateStopped) break;
|
||||
}
|
||||
|
||||
|
||||
while (_onceList.Count > 0)
|
||||
{
|
||||
var eventBin = _onceList.Pop();
|
||||
eventBin.target.Off(eventBin.type, eventBin.listener, eventBin.thisObject);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1d03163cd522f1f44a06979858fa2ee5
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
71
Assets/Scripts/NBC/Core/Runtime/Event/IEventDispatcher.cs
Normal file
71
Assets/Scripts/NBC/Core/Runtime/Event/IEventDispatcher.cs
Normal file
@@ -0,0 +1,71 @@
|
||||
using System;
|
||||
|
||||
namespace NBC
|
||||
{
|
||||
public interface IEventDispatcher
|
||||
{
|
||||
/// <summary>
|
||||
/// 注册一个消息
|
||||
/// </summary>
|
||||
/// <param name="type">消息类型</param>
|
||||
/// <param name="listener">监听函数</param>
|
||||
/// <param name="caller">监听对象</param>
|
||||
/// <param name="priority">优先级</param>
|
||||
/// <param name="once">是否只执行一次监听</param>
|
||||
/// <returns></returns>
|
||||
IEventDispatcher On(string type, Action<EventArgs> listener, object caller, int priority = 0,
|
||||
bool once = false);
|
||||
|
||||
/// <summary>
|
||||
/// 注册一个监听一次的消息
|
||||
/// </summary>
|
||||
/// <param name="type">消息类型</param>
|
||||
/// <param name="listener">监听函数</param>
|
||||
/// <param name="caller">监听对象</param>
|
||||
/// <param name="priority">优先级</param>
|
||||
/// <returns></returns>
|
||||
IEventDispatcher Once(string type, Action<EventArgs> listener, object caller, int priority = 0);
|
||||
|
||||
/// <summary>
|
||||
/// 取消监听
|
||||
/// </summary>
|
||||
/// <param name="type"></param>
|
||||
/// <param name="listener"></param>
|
||||
/// <param name="caller"></param>
|
||||
/// <returns></returns>
|
||||
IEventDispatcher Off(string type, Action<EventArgs> listener, object caller);
|
||||
|
||||
/// <summary>
|
||||
/// 取消这个消息的所有监听
|
||||
/// </summary>
|
||||
/// <param name="type"></param>
|
||||
IEventDispatcher OffAll(string type = "");
|
||||
|
||||
/// <summary>
|
||||
/// 取消接受对象上的所有消息
|
||||
/// </summary>
|
||||
/// <param name="caller"></param>
|
||||
/// <returns></returns>
|
||||
IEventDispatcher OffAllCaller(object caller);
|
||||
|
||||
/// <summary>
|
||||
/// 是否存在监听
|
||||
/// </summary>
|
||||
/// <param name="type"></param>
|
||||
/// <returns></returns>
|
||||
bool HasEventListener(string type);
|
||||
|
||||
/// <summary>
|
||||
/// 派发消息
|
||||
/// </summary>
|
||||
/// <param name="ev"></param>
|
||||
void DispatchEvent(EventArgs ev);
|
||||
|
||||
/// <summary>
|
||||
/// 根据消息类型派发消息
|
||||
/// </summary>
|
||||
/// <param name="type"></param>
|
||||
/// <param name="data"></param>
|
||||
bool DispatchEventWith(string type, object data = null);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ee3ce226192bcd648bc228e5e92b6ee2
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user