Skip to content

Instantly share code, notes, and snippets.

@seamanmur
Created July 9, 2017 11:48
Show Gist options
  • Save seamanmur/a477681951984c8a9ff7024504aa55d0 to your computer and use it in GitHub Desktop.
Save seamanmur/a477681951984c8a9ff7024504aa55d0 to your computer and use it in GitHub Desktop.
/// <summary>
/// Делегат, представляющий метод обработки события.
/// </summary>
/// <param name="sender">Объект, вызвавший это событие</param>
/// <param name="data">Данные для обработки события.</param>
public delegate void EventHandler(object sender, object data);
//[Serializable]
public class Messenger
{
///<summary>Слушатели событий, которые генерит данный объект.</summary>
private readonly Dictionary<string, EventHandler> __eventListeners = new Dictionary<string, EventHandler>();
/// <summary>
/// Добавляет обработчик события типа type(строка), который будет вызываться этим компонентом
/// </summary>
/// <param name="e">Событие (тип и делегат)</param>
public void AddEventListener(PlainEventArgs e)
{
//Debug.Log("AddEventListener type - " + e._Type);
var t = e._Type;
if (!__eventListeners.ContainsKey(t)) __eventListeners.Add(t, e._Value);
else __eventListeners[t] = (EventHandler)Delegate.Combine(__eventListeners[t], e._Value);
}
/// <summary>
/// Удаляет указанный обработчик события
/// </summary>
/// <param name="e">Событие (тип и делегат)</param>
public void RemoveEventListener(PlainEventArgs e)
{
var t = e._Type;
if(!__eventListeners.ContainsKey(t)) return;
var d = Delegate.Remove(__eventListeners[t], e._Value);
if (d == null) __eventListeners.Remove(t);
else __eventListeners[t] = (EventHandler)d;
}
/// <summary>
/// Есть ли обработчик события данного типа?
/// </summary>
/// <param name="type">тип события</param>
/// <returns>Да - если есть хоть один обработчик</returns>
public bool HasEventListener(string type)
{
//Debug.Log("Has ?- " + type);
//foreach (var pair in __eventListeners)
//{
// Debug.Log("EL - " + pair.Key);
//}
return __eventListeners.ContainsKey(type);
}
/// <summary>
/// Ищет обработчик события по типу
/// </summary>
/// <param name="t">Тип события - строка</param>
/// <returns>Обработчик события - тип/делегат</returns>
public PlainEventArgs FindEvent(string t) { return !__eventListeners.ContainsKey(t) ? null : new PlainEventArgs(t, __eventListeners[t]); }
/// <summary>
/// Выполнение события. Если это событие имеет хоть один обработчик - он будет вызван.
/// </summary>
/// <param name="e">Событие (тип и делегат)</param>
/// <param name="data">Данные, переданные событию</param>
public void DispatchEvent(PlainEventArgs e, object data)
{
var t = e._Type;
if (!__eventListeners.ContainsKey(t)) return;
var handler = __eventListeners[t];
handler(this, data);
}
/// <summary>
/// Выполнение события. Если это событие имеет хоть один обработчик - он будет вызван.
/// </summary>
/// <param name="eName">Событие (имя)</param>
/// <param name="data">Данные, переданные событию</param>
public void DispatchEvent(string eName, object data)
{
if (!__eventListeners.ContainsKey(eName)) return;
var handler = __eventListeners[eName];
handler(this, data);
}
}
//NOTE Только для уменьшения писанины. Можно было бы везде передавать string type, Delegate value
/// <summary>
/// Аргумент для простого события. содержит тип события и соответствующий делегат.
/// </summary>
public class PlainEventArgs : EventArgs
{
internal PlainEventArgs(string type, EventHandler value)
{
_Type = type;
_Value = value;
}
/// <summary>
/// Тип события. (Имя)
/// </summary>
internal string _Type { get; private set; }
/// <summary>
/// Делегат, который должен быть выполнен при возникновении события.
/// </summary>
internal EventHandler _Value { get; private set; }
}
public class Ship : MonoBehaviour
{
...
public Messenger messenger;
public void Awake()
{
messenger = new Messenger();
...
}
public void FixedUpdate()
{
...
if (messenger.HasEventListener("RadarEvent")) messenger.DispatchEvent("RadarEvent", __danger);
}
...
}
public class ShipControl : MonoBehaviour
{
private PlainEventArgs __shipEvent;
...
public void Start()
{
__shipEvent = new PlainEventArgs("ShipChange", (EventHandler)Delegate.CreateDelegate(typeof(EventHandler), this, "OnShipChange"));
}
public void OnDestroy()
{
__ship.messenger.RemoveEventListener(__shipEvent);
}
public void OnShipChange(object sender, object data)
{
//Bla bla bla
}
...
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment