Skip to content

Instantly share code, notes, and snippets.

@thebeardphantom
Last active February 12, 2022 23:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save thebeardphantom/06cfe3a05987808ab154292d62a8b894 to your computer and use it in GitHub Desktop.
Save thebeardphantom/06cfe3a05987808ab154292d62a8b894 to your computer and use it in GitHub Desktop.
A reimplementation of C# events for Unity 2020+ that's lighter on GC.
using System;
namespace BeardPhantom.LiteEvent
{
public interface ILiteEvent<in TDelegate> where TDelegate : Delegate
{
#region Properties
int ListenerCount { get; }
#endregion
#region Methods
void Clear();
bool Register(TDelegate listener);
bool Unregister(TDelegate listener);
#endregion
}
}
using System.Collections.Generic;
using UnityEngine.Pool;
namespace BeardPhantom.LiteEvent
{
public sealed class LiteEvent : ILiteEvent<LiteEvent.OnEventInvoked>
{
#region Types
public delegate void OnEventInvoked();
#endregion
#region Events
public event OnEventInvoked Event
{
add => Register(value);
remove => Unregister(value);
}
#endregion
#region Fields
private readonly HashSet<OnEventInvoked> _listeners = new();
#endregion
#region Properties
public int ListenerCount => _listeners.Count;
#endregion
#region Methods
public void Invoke()
{
using (ListPool<OnEventInvoked>.Get(out var listenersCopy))
{
listenersCopy.AddRange(_listeners);
foreach (var listener in listenersCopy)
{
listener();
}
}
}
public IEnumerable<OnEventInvoked> GetListeners()
{
using (ListPool<OnEventInvoked>.Get(out var listeners))
{
foreach (var listener in listeners)
{
yield return listener;
}
}
}
public void Clear()
{
_listeners.Clear();
}
public bool Register(OnEventInvoked listener)
{
return _listeners.Add(listener);
}
public bool Unregister(OnEventInvoked listener)
{
return _listeners.Remove(listener);
}
#endregion
}
public sealed class LiteEvent<TArgs> : ILiteEvent<LiteEvent<TArgs>.OnEventInvoked>
{
#region Types
public delegate void OnEventInvoked(in TArgs args);
#endregion
#region Events
public event OnEventInvoked Event
{
add => Register(value);
remove => Unregister(value);
}
#endregion
#region Fields
private readonly HashSet<OnEventInvoked> _listeners = new();
#endregion
#region Properties
public int ListenerCount => _listeners.Count;
#endregion
#region Methods
public IEnumerable<OnEventInvoked> GetListeners()
{
using (ListPool<OnEventInvoked>.Get(out var listeners))
{
foreach (var listener in listeners)
{
yield return listener;
}
}
}
public void Clear()
{
_listeners.Clear();
}
public bool Register(OnEventInvoked listener)
{
return _listeners.Add(listener);
}
public bool Unregister(OnEventInvoked listener)
{
return _listeners.Remove(listener);
}
public void Invoke(in TArgs args)
{
using (ListPool<OnEventInvoked>.Get(out var listenersCopy))
{
listenersCopy.AddRange(_listeners);
foreach (var listener in listenersCopy)
{
listener.Invoke(in args);
}
}
}
#endregion
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment