Skip to content

Commit 470b3b4

Browse files
committed
Implemented support for events without arg
1 parent e48f3e1 commit 470b3b4

18 files changed

Lines changed: 257 additions & 93 deletions

Editor/EditorUI.meta

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
using UnityEditor;
2+
using System;
3+
using UnityEngine;
4+
5+
namespace Editor.EditorUI
6+
{
7+
public class BaseEventListenerCustomInspector : UnityEditor.Editor
8+
{
9+
protected const string EventSOVariableName = "_baseEvent";
10+
11+
protected SerializedProperty _baseEventProp;
12+
13+
protected virtual void OnEnable()
14+
{
15+
_baseEventProp = serializedObject.FindProperty(EventSOVariableName);
16+
}
17+
18+
protected void DrawEventInspector(string label, string tooltip, Func<UnityEngine.Object, bool> validationLogic)
19+
{
20+
serializedObject.Update();
21+
// EditorGUILayout.Space();
22+
// EditorGUILayout.LabelField("Event Configuration", EditorStyles.boldLabel);
23+
24+
EditorGUI.BeginChangeCheck();
25+
var newObj = EditorGUILayout.ObjectField(new GUIContent(label, tooltip), _baseEventProp.objectReferenceValue, typeof(ScriptableObject), false);
26+
27+
if (EditorGUI.EndChangeCheck())
28+
{
29+
if (newObj == null || validationLogic(newObj))
30+
{
31+
_baseEventProp.objectReferenceValue = newObj;
32+
}
33+
else
34+
{
35+
EditorUtility.DisplayDialog("Compatibility Error",
36+
"The selected Asset does not implement the required interface.", "Ok");
37+
}
38+
}
39+
40+
DrawPropertiesExcluding(serializedObject, "m_Script", EventSOVariableName);
41+
serializedObject.ApplyModifiedProperties();
42+
}
43+
}
44+
}

Editor/EditorUI/BaseEventListenerCustomInspector.cs.meta

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
using System;
2+
using SOBaseEvents.Refactor;
3+
using UnityEditor;
4+
5+
namespace Editor.EditorUI
6+
{
7+
[CustomEditor(typeof(EventListener<>), true)]
8+
[CanEditMultipleObjects]
9+
public class EventListenerCustomInspector : BaseEventListenerCustomInspector
10+
{
11+
public override void OnInspectorGUI()
12+
{
13+
DrawEventInspector("Event Asset (Void)",
14+
"Must implement ISOEventRegistry",
15+
obj => ValidationLogic(obj));
16+
}
17+
18+
private bool ValidationLogic(Object obj)
19+
{
20+
return obj is ISOEventBase && obj is ISOEventRegistry;
21+
}
22+
}
23+
}

Editor/EditorUI/EventListenerCustomInspector.cs.meta

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
using System;
2+
using SOBaseEvents.Refactor;
3+
using UnityEditor;
4+
using Object = UnityEngine.Object;
5+
6+
namespace Editor.EditorUI
7+
{
8+
[CustomEditor(typeof(EventListener<,>), true)]
9+
[CanEditMultipleObjects]
10+
public class EventListenerWithArgCustomInspector : BaseEventListenerCustomInspector
11+
{
12+
Type _tArg;
13+
14+
private void OnEnable()
15+
{
16+
base.OnEnable();
17+
var type = target.GetType();
18+
19+
while (type != null && (!type.IsGenericType || type.GetGenericTypeDefinition() != typeof(EventListener<,>)))
20+
{
21+
type = type.BaseType;
22+
}
23+
24+
if (type != null)
25+
{
26+
_tArg = type.GetGenericArguments()[1];
27+
}
28+
}
29+
30+
public override void OnInspectorGUI()
31+
{
32+
DrawEventInspector("Event Asset",
33+
$"Must implement ISOEventRegistry<{(_tArg != null ? _tArg.Name : "T")}>",
34+
obj => ValidationLogic(obj));
35+
}
36+
37+
private bool ValidationLogic(Object obj)
38+
{
39+
var registryInterface = typeof(ISOEventRegistry<>).MakeGenericType(_tArg);
40+
return obj is ISOEventBase && registryInterface.IsAssignableFrom(obj.GetType());
41+
}
42+
}
43+
}
File renamed without changes.

Editor/EventListenerCustomInspector.cs

Lines changed: 0 additions & 90 deletions
This file was deleted.

Runtime/SOBaseEvents/Refactor/EventListener.cs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,31 @@
33

44
namespace SOBaseEvents.Refactor
55
{
6+
public abstract class EventListener<TEvent> : MonoBehaviour where TEvent : class, ISOEventRegistry
7+
{
8+
public event Action OnEventRaised;
9+
10+
[SerializeField] protected ScriptableObject _baseEvent;
11+
12+
protected TEvent _typedEvent => _baseEvent as TEvent;
13+
14+
private void OnEnable()
15+
{
16+
if (_typedEvent != null)
17+
{
18+
_typedEvent.AddListener(OnEventRaised);
19+
}
20+
}
21+
22+
private void OnDisable()
23+
{
24+
if (_typedEvent != null)
25+
{
26+
_typedEvent.RemoveListener(OnEventRaised);
27+
}
28+
}
29+
}
30+
631
public abstract class EventListener<TEvent, TArg> : MonoBehaviour where TEvent : class, ISOEventRegistry<TArg>
732
{
833
public event Action<TArg> OnEventRaised;

Runtime/SOBaseEvents/Refactor/EventSOBase.cs

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,60 @@
44

55
namespace SOBaseEvents.Refactor
66
{
7+
public abstract class EventSOBase : ScriptableObject, ISOEventBase, ISOEventRegistry, ISOEventRaiser
8+
{
9+
private readonly List<Action> _listeners = new();
10+
11+
public void AddListener(Action listener)
12+
{
13+
if (_listeners.Contains(listener))
14+
{
15+
var (objectName, methodName) = GetListenerInfo(listener);
16+
Debug.LogError($"[ScriptableObjectEvents] Listener {methodName} of GameObject {objectName} already registered. Aborting registration.");
17+
return;
18+
}
19+
20+
_listeners.Add(listener);
21+
}
22+
23+
public void RemoveListener(Action listener)
24+
{
25+
if (!_listeners.Contains(listener))
26+
{
27+
var (objectName, methodName) = GetListenerInfo(listener);
28+
Debug.LogError($"[ScriptableObjectEvents] Listener {methodName} of GameObject {objectName} is not registered. Aborting removal.");
29+
return;
30+
}
31+
32+
_listeners.Remove(listener);
33+
}
34+
35+
public void RaiseEvent()
36+
{
37+
for (int i = _listeners.Count - 1; i >= 0; i--)
38+
{
39+
_listeners[i]?.Invoke();
40+
}
41+
}
42+
43+
private (string objectName, string methodName) GetListenerInfo(Action listener)
44+
{
45+
var objectName = string.Empty;
46+
var methodName = listener.Method.Name;
47+
48+
if (listener.Target is MonoBehaviour mb)
49+
{
50+
objectName = mb.gameObject.name;
51+
}
52+
else if (listener.Target != null)
53+
{
54+
objectName = listener.Target.ToString();
55+
}
56+
57+
return (objectName, methodName);
58+
}
59+
}
60+
761
public abstract class EventSOBase<TArg> : ScriptableObject, ISOEventBase, ISOEventRegistry<TArg>, ISOEventRaiser<TArg>
862
{
963
private readonly List<Action<TArg>> _listeners = new();

0 commit comments

Comments
 (0)