Skip to content

Instantly share code, notes, and snippets.

@yangruihan
Last active February 15, 2019 08:06
Show Gist options
  • Select an option

  • Save yangruihan/a239d7c38bd5b61d4fa3e77cf31cb750 to your computer and use it in GitHub Desktop.

Select an option

Save yangruihan/a239d7c38bd5b61d4fa3e77cf31cb750 to your computer and use it in GitHub Desktop.
Unity EventDispatcher
using System.Collections.Generic;
using UnityEngine;
using System;
public delegate void EventHandler(short type);
public delegate void EventHandler<in T>(short type, T msg);
/// <summary>
/// 事件派发器
/// </summary>
public class EventDispatcher
{
private readonly Dictionary<short, List<Delegate>> _eventHandlerDic = new Dictionary<short, List<Delegate>>();
private readonly Dictionary<short, List<Delegate>> _oneShotHandlerDic = new Dictionary<short, List<Delegate>>();
private readonly List<List<Delegate>> _tempHandlerList = new List<List<Delegate>>();
public void ClearEventHandler()
{
Dictionary<short, List<Delegate>>.Enumerator enumerator;
if (_eventHandlerDic != null)
{
enumerator = _eventHandlerDic.GetEnumerator();
while (enumerator.MoveNext())
{
enumerator.Current.Value.Clear();
}
}
if (_oneShotHandlerDic != null)
{
enumerator = _oneShotHandlerDic.GetEnumerator();
while (enumerator.MoveNext())
{
enumerator.Current.Value.Clear();
}
}
_tempHandlerList.Clear();
}
public void PresizeHandler(short type, int size)
{
if (!_eventHandlerDic.ContainsKey(type))
{
_eventHandlerDic.Add(type, new List<Delegate>(size));
}
}
public void ClearNullEventHandler()
{
var count = _tempHandlerList.Count;
if (count > 0)
{
for (var i = 0; i < count; i++)
{
var eventListeners = _tempHandlerList[i];
var len = eventListeners.Count;
var newLen = 0;
for (var j = 0; j < len; j++)
{
if (eventListeners[j] != null)
{
if (newLen != j)
eventListeners[newLen] = eventListeners[j];
newLen++;
}
}
eventListeners.RemoveRange(newLen, len - newLen);
}
_tempHandlerList.Clear();
}
}
#region 无参数事件
public void AddEventHandler(short type, EventHandler handler)
{
AddEventHandlerInternal(_eventHandlerDic, type, handler);
}
public void RemoveEventHandler(short type, EventHandler handler)
{
RemoveEventHandlerInternal(_eventHandlerDic, type, handler);
}
public void AddOneShotEventHandler(short type, EventHandler handler)
{
AddEventHandlerInternal(_oneShotHandlerDic, type, handler);
}
public void RemoveOneShotEventHandler(short type, EventHandler handler)
{
RemoveEventHandlerInternal(_oneShotHandlerDic, type, handler);
}
public void SendEvent(short type)
{
var eventListeners = GetEventHandlerList(_eventHandlerDic, type, false);
if (eventListeners != null)
{
var len = eventListeners.Count;
for (var i = 0; i < len; i++)
{
if (eventListeners[i] == null)
continue;
var tEvent = (EventHandler) eventListeners[i];
tEvent(type);
}
}
var oneShotListeners = GetEventHandlerList(_oneShotHandlerDic, type, false);
if (oneShotListeners != null)
{
var len = oneShotListeners.Count;
for (var i = 0; i < len; i++)
{
if (oneShotListeners[i] == null)
continue;
var tEvent = (EventHandler) oneShotListeners[i];
tEvent(type);
}
oneShotListeners.Clear();
}
}
#endregion
#region 单参数事件
public void AddEventHandler<T>(short type, EventHandler<T> handler)
{
try
{
AddEventHandlerInternal(_eventHandlerDic, type, handler);
}
catch
{
Debug.LogError("trying to add handler error, type:" + type + " handler:" + handler);
}
}
public void RemoveEventHandler<T>(short type, EventHandler<T> handler)
{
RemoveEventHandlerInternal(_eventHandlerDic, type, handler);
}
public void AddOneShotEventHandler<T>(short type, EventHandler<T> handler)
{
AddEventHandlerInternal(_oneShotHandlerDic, type, handler);
}
public void RemoveOneShotEventHandler<T>(short type, EventHandler<T> handler)
{
RemoveEventHandlerInternal(_oneShotHandlerDic, type, handler);
}
public void SendEvent<T>(short type, T msg)
{
var eventListeners = GetEventHandlerList(_eventHandlerDic, type, false);
if (eventListeners != null)
{
var len = eventListeners.Count;
for (var i = 0; i < len; i++)
{
if (eventListeners[i] == null)
continue;
var tEvent = (EventHandler<T>) eventListeners[i];
tEvent(type, msg);
}
}
var oneShotListeners = GetEventHandlerList(_oneShotHandlerDic, type, false);
if (oneShotListeners != null)
{
var len = oneShotListeners.Count;
for (var i = 0; i < len; i++)
{
if (oneShotListeners[i] == null)
continue;
var tEvent = (EventHandler<T>) oneShotListeners[i];
tEvent(type, msg);
}
oneShotListeners.Clear();
}
}
#endregion
private void AddEventHandlerInternal(Dictionary<short, List<Delegate>> dic, short type, Delegate handler)
{
var eventListeners = GetEventHandlerList(dic, type, true);
var newEvent = true;
#if DEBUG
if (eventListeners.Contains(handler))
{
Debug.LogError("repeat to add " + handler);
newEvent = false;
}
#endif
if (newEvent)
{
eventListeners.Add(handler);
}
}
private void RemoveEventHandlerInternal(Dictionary<short, List<Delegate>> dic, short type, Delegate handler)
{
var eventListeners = GetEventHandlerList(dic, type, false);
if (eventListeners == null)
return;
var index = eventListeners.IndexOf(handler);
if (index != -1)
{
eventListeners[index] = null;
if (!_tempHandlerList.Contains(eventListeners))
_tempHandlerList.Add(eventListeners);
}
}
private List<Delegate> GetEventHandlerList(Dictionary<short, List<Delegate>> dic, short type, bool autoCreate)
{
if (dic.TryGetValue(type, out var eventList))
return eventList;
else
{
if (autoCreate)
{
eventList = new List<Delegate>();
dic.Add(type, eventList);
return eventList;
}
return null;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment