107 lines
2.8 KiB
C#
107 lines
2.8 KiB
C#
using System;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using System.Runtime.CompilerServices;
|
|
using NaughtyAttributes.Test;
|
|
using UnityEngine;
|
|
#if UNITY_EDITOR
|
|
using UnityEditor;
|
|
#endif
|
|
|
|
namespace Ktyl.Util
|
|
{
|
|
[CreateAssetMenu(menuName = "ktyl/Events/Game Event")]
|
|
public partial class GameEvent : ScriptableObject
|
|
{
|
|
[SerializeField] private bool _logRaised;
|
|
|
|
protected readonly List<GameEventListener> _listeners = new List<GameEventListener>();
|
|
|
|
private readonly List<GameEventListener> _listenerBuffer = new List<GameEventListener>();
|
|
|
|
public virtual void Raise()
|
|
{
|
|
if (_logRaised)
|
|
{
|
|
Debug.Log($"raised {this}", this);
|
|
}
|
|
|
|
// populate a buffer of listeners, since the original list
|
|
// may be modified as a consequence of triggering the event
|
|
_listenerBuffer.Clear();
|
|
_listenerBuffer.AddRange(_listeners);
|
|
|
|
foreach (var listener in _listenerBuffer)
|
|
{
|
|
listener.OnEventRaised();
|
|
}
|
|
}
|
|
|
|
public void Register(GameEventListener listener)
|
|
{
|
|
if (_listeners.Contains(listener))
|
|
{
|
|
Debug.LogError($"{listener} already registered", this);
|
|
return;
|
|
}
|
|
|
|
_listeners.Add(listener);
|
|
}
|
|
|
|
public void Unregister(GameEventListener listener)
|
|
{
|
|
if (!_listeners.Contains(listener))
|
|
{
|
|
Debug.LogError($"{listener} not already registered");
|
|
return;
|
|
}
|
|
|
|
_listeners.Remove(listener);
|
|
}
|
|
}
|
|
|
|
#region Editor
|
|
#if UNITY_EDITOR
|
|
|
|
public partial class GameEvent
|
|
{
|
|
private int _EDITOR_pingIdx;
|
|
|
|
public void EDITOR_PingNextListener()
|
|
{
|
|
Debug.Log($"ping listener {_EDITOR_pingIdx+1}/{_listeners.Count}", this);
|
|
|
|
EditorGUIUtility.PingObject(_listeners[_EDITOR_pingIdx++]);
|
|
_EDITOR_pingIdx %= _listeners.Count;
|
|
}
|
|
}
|
|
|
|
[CustomEditor(typeof(GameEvent), true)]
|
|
public class GameEventEditor : Editor
|
|
{
|
|
private GameEvent _event;
|
|
|
|
private void OnEnable()
|
|
{
|
|
_event = target as GameEvent;
|
|
}
|
|
|
|
public override void OnInspectorGUI()
|
|
{
|
|
base.OnInspectorGUI();
|
|
|
|
if (GUILayout.Button("Raise"))
|
|
{
|
|
_event.Raise();
|
|
}
|
|
|
|
if (Application.isPlaying && GUILayout.Button("Ping Listeners"))
|
|
{
|
|
_event.EDITOR_PingNextListener();
|
|
}
|
|
}
|
|
}
|
|
|
|
#endif
|
|
#endregion
|
|
} |