-
Notifications
You must be signed in to change notification settings - Fork 2k
Event Aggregator proposal #424
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
zaradai
wants to merge
1
commit into
UnityTechnologies:main
Choose a base branch
from
zaradai:EventAggregator
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+501
−79
Open
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
14 changes: 14 additions & 0 deletions
14
UOP1_Project/Assets/ScriptableObjects/Events/EventAggregatorSO.asset
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
%YAML 1.1 | ||
%TAG !u! tag:unity3d.com,2011: | ||
--- !u!114 &11400000 | ||
MonoBehaviour: | ||
m_ObjectHideFlags: 0 | ||
m_CorrespondingSourceObject: {fileID: 0} | ||
m_PrefabInstance: {fileID: 0} | ||
m_PrefabAsset: {fileID: 0} | ||
m_GameObject: {fileID: 0} | ||
m_Enabled: 1 | ||
m_EditorHideFlags: 0 | ||
m_Script: {fileID: 11500000, guid: c3683d4b74c443d4a48ca7b36086f246, type: 3} | ||
m_Name: EventAggregatorSO | ||
m_EditorClassIdentifier: |
8 changes: 8 additions & 0 deletions
8
UOP1_Project/Assets/ScriptableObjects/Events/EventAggregatorSO.asset.meta
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
14 changes: 14 additions & 0 deletions
14
UOP1_Project/Assets/ScriptableObjects/Events/UnityEventBusSO.asset
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
%YAML 1.1 | ||
%TAG !u! tag:unity3d.com,2011: | ||
--- !u!114 &11400000 | ||
MonoBehaviour: | ||
m_ObjectHideFlags: 0 | ||
m_CorrespondingSourceObject: {fileID: 0} | ||
m_PrefabInstance: {fileID: 0} | ||
m_PrefabAsset: {fileID: 0} | ||
m_GameObject: {fileID: 0} | ||
m_Enabled: 1 | ||
m_EditorHideFlags: 0 | ||
m_Script: {fileID: 11500000, guid: c44145970255443c86929d77c7ac2d2a, type: 3} | ||
m_Name: UnityEventBusSO | ||
m_EditorClassIdentifier: |
8 changes: 8 additions & 0 deletions
8
UOP1_Project/Assets/ScriptableObjects/Events/UnityEventBusSO.asset.meta
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,142 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using System.Reflection; | ||
|
||
|
||
/// <summary> | ||
/// Enables loose coupling of events from publishers to subscribers | ||
/// | ||
/// inspired from https://github.com/Caliburn-Micro/Caliburn.Micro/blob/master/src/Caliburn.Micro.Core/IEventAggregator.cs | ||
/// and also https://github.com/google/guava/blob/master/guava/src/com/google/common/eventbus/EventBus.java | ||
/// | ||
/// Runs within single threaded unity environment so no need to lock any structures. | ||
/// There is no current requirement to dispatch or consume events asynchronously and sync with unity main thread. | ||
/// </summary> | ||
public interface IEventAggregator | ||
{ | ||
void Subscribe(object observer); | ||
|
||
void Unsubscribe(object observer); | ||
|
||
void Publish(object msg); | ||
} | ||
|
||
public class EventAggregator : IEventAggregator | ||
{ | ||
private readonly Dictionary<Type, HashSet<Handler>> _handlers = new Dictionary<Type, HashSet<Handler>>(); | ||
private readonly Dictionary<object, Subscriptions> _subByObserver = new Dictionary<object, Subscriptions>(); | ||
private readonly object[] _paramHolder = {null}; | ||
|
||
public void Subscribe(object observer) | ||
{ | ||
if (observer == null) | ||
{ | ||
throw new ArgumentNullException(nameof(observer)); | ||
} | ||
|
||
if (_subByObserver.ContainsKey(observer)) | ||
{ | ||
return; | ||
} | ||
|
||
var subs = new Subscriptions(); | ||
|
||
var interfaces = observer.GetType().GetTypeInfo().ImplementedInterfaces | ||
.Where(x => x.GetTypeInfo().IsGenericType && x.GetGenericTypeDefinition() == typeof(IHandle<>)); | ||
|
||
foreach (var @interface in interfaces) | ||
{ | ||
var type = @interface.GetTypeInfo().GenericTypeArguments[0]; | ||
var method = @interface.GetRuntimeMethod("Handle", new[] {type}); | ||
|
||
if (method != null) | ||
{ | ||
var handler = new Handler(method, observer); | ||
|
||
if (!_handlers.TryGetValue(type, out var handlers)) | ||
{ | ||
handlers = new HashSet<Handler>(); | ||
_handlers[type] = handlers; | ||
} | ||
|
||
handlers.Add(handler); | ||
subs.Interested[type] = handler; | ||
} | ||
} | ||
|
||
if (subs.Interested.Count > 0) | ||
{ | ||
_subByObserver[observer] = subs; | ||
} | ||
} | ||
|
||
public void Unsubscribe(object observer) | ||
{ | ||
if (observer == null) | ||
{ | ||
throw new ArgumentNullException(nameof(observer)); | ||
} | ||
|
||
|
||
if (_subByObserver.TryGetValue(observer, out var subscriptions)) | ||
{ | ||
_subByObserver.Remove(observer); | ||
|
||
foreach (var entry in subscriptions.Interested) | ||
{ | ||
if (_handlers.TryGetValue(entry.Key, out var handlers)) | ||
{ | ||
handlers.Remove(entry.Value); | ||
} | ||
} | ||
} | ||
} | ||
|
||
public void Publish(object msg) | ||
{ | ||
if (msg == null) | ||
{ | ||
throw new ArgumentNullException(nameof(msg)); | ||
} | ||
|
||
if (_handlers.TryGetValue(msg.GetType(), out var handlers)) | ||
{ | ||
_paramHolder[0] = msg; | ||
|
||
foreach (var handler in handlers) | ||
{ | ||
handler.Notify(_paramHolder); | ||
} | ||
} | ||
} | ||
|
||
private class Subscriptions | ||
{ | ||
private readonly Dictionary<Type, Handler> _interested = new Dictionary<Type, Handler>(); | ||
|
||
public Dictionary<Type, Handler> Interested => _interested; | ||
} | ||
|
||
private class Handler | ||
{ | ||
private readonly MethodInfo _method; | ||
private readonly object _observer; | ||
|
||
public Handler(MethodInfo method, object observer) | ||
{ | ||
_method = method; | ||
_observer = observer; | ||
} | ||
|
||
public void Notify(object[] param) | ||
{ | ||
_method.Invoke(_observer, param); | ||
} | ||
} | ||
|
||
public interface IHandle<T> | ||
{ | ||
void Handle(T msg); | ||
} | ||
} |
11 changes: 11 additions & 0 deletions
11
UOP1_Project/Assets/Scripts/Events/EventAggregator.cs.meta
Oops, something went wrong.
Oops, something went wrong.
4 changes: 4 additions & 0 deletions
4
UOP1_Project/Assets/Scripts/Events/Input/AttackCancelledEvent.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
public class AttackCancelledEvent | ||
{ | ||
public static readonly AttackCancelledEvent Event = new AttackCancelledEvent(); | ||
} |
3 changes: 3 additions & 0 deletions
3
UOP1_Project/Assets/Scripts/Events/Input/AttackCancelledEvent.cs.meta
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
public class AttackEvent | ||
{ | ||
public static readonly AttackEvent Event = new AttackEvent(); | ||
} |
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
using UnityEngine; | ||
|
||
public class CameraMoveEvent | ||
{ | ||
public Vector2 Movement { get; set; } | ||
public bool IsDeviceMouse { get; set; } | ||
} |
3 changes: 3 additions & 0 deletions
3
UOP1_Project/Assets/Scripts/Events/Input/CameraMoveEvent.cs.meta
Oops, something went wrong.
4 changes: 4 additions & 0 deletions
4
UOP1_Project/Assets/Scripts/Events/Input/DisableMouseControlEvent.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
public class DisableMouseControlEvent | ||
{ | ||
public static readonly DisableMouseControlEvent Event = new DisableMouseControlEvent(); | ||
} |
3 changes: 3 additions & 0 deletions
3
UOP1_Project/Assets/Scripts/Events/Input/DisableMouseControlEvent.cs.meta
Oops, something went wrong.
4 changes: 4 additions & 0 deletions
4
UOP1_Project/Assets/Scripts/Events/Input/EnableMouseControlEvent.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
public class EnableMouseControlEvent | ||
{ | ||
public static readonly EnableMouseControlEvent Event = new EnableMouseControlEvent(); | ||
} |
3 changes: 3 additions & 0 deletions
3
UOP1_Project/Assets/Scripts/Events/Input/EnableMouseControlEvent.cs.meta
Oops, something went wrong.
4 changes: 4 additions & 0 deletions
4
UOP1_Project/Assets/Scripts/Events/Input/JumpCancelledEvent.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
public class JumpCancelledEvent | ||
{ | ||
public static readonly JumpCancelledEvent Event = new JumpCancelledEvent(); | ||
} |
3 changes: 3 additions & 0 deletions
3
UOP1_Project/Assets/Scripts/Events/Input/JumpCancelledEvent.cs.meta
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
public class JumpEvent | ||
{ | ||
public static readonly JumpEvent Event = new JumpEvent(); | ||
} |
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
using UnityEngine; | ||
|
||
public class MoveEvent | ||
{ | ||
public Vector2 Movement { get; set; } | ||
} |
Oops, something went wrong.
4 changes: 4 additions & 0 deletions
4
UOP1_Project/Assets/Scripts/Events/Input/OpenInventoryEvent.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
public class OpenInventoryEvent | ||
{ | ||
public static readonly OpenInventoryEvent Event = new OpenInventoryEvent(); | ||
} |
3 changes: 3 additions & 0 deletions
3
UOP1_Project/Assets/Scripts/Events/Input/OpenInventoryEvent.cs.meta
Oops, something went wrong.
4 changes: 4 additions & 0 deletions
4
UOP1_Project/Assets/Scripts/Events/Input/StartedRunningEvent.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
public class StartedRunningEvent | ||
{ | ||
public static readonly StartedRunningEvent Event = new StartedRunningEvent(); | ||
} |
3 changes: 3 additions & 0 deletions
3
UOP1_Project/Assets/Scripts/Events/Input/StartedRunningEvent.cs.meta
Oops, something went wrong.
4 changes: 4 additions & 0 deletions
4
UOP1_Project/Assets/Scripts/Events/Input/StoppedRunningEvent.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
public class StoppedRunningEvent | ||
{ | ||
public static readonly StoppedRunningEvent Event = new StoppedRunningEvent(); | ||
} |
3 changes: 3 additions & 0 deletions
3
UOP1_Project/Assets/Scripts/Events/Input/StoppedRunningEvent.cs.meta
Oops, something went wrong.
22 changes: 22 additions & 0 deletions
22
UOP1_Project/Assets/Scripts/Events/ScriptableObjects/EventAggregatorSO.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
using UnityEngine; | ||
|
||
[CreateAssetMenu(fileName = "EventAggregatorSO", menuName = "Events/Event Aggregator")] | ||
public class EventAggregatorSO : ScriptableObject, IEventAggregator | ||
{ | ||
private readonly EventAggregator _eventAggregator = new EventAggregator(); | ||
|
||
public void Subscribe(object observer) | ||
{ | ||
_eventAggregator.Subscribe(observer); | ||
} | ||
|
||
public void Unsubscribe(object observer) | ||
{ | ||
_eventAggregator.Unsubscribe(observer); | ||
} | ||
|
||
public void Publish(object msg) | ||
{ | ||
_eventAggregator.Publish(msg); | ||
} | ||
} |
3 changes: 3 additions & 0 deletions
3
UOP1_Project/Assets/Scripts/Events/ScriptableObjects/EventAggregatorSO.cs.meta
Oops, something went wrong.
23 changes: 23 additions & 0 deletions
23
UOP1_Project/Assets/Scripts/Events/ScriptableObjects/UnityEventBusSO.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
using UnityEngine; | ||
using UnityEngine.Events; | ||
|
||
[CreateAssetMenu(fileName = "UnityEventBusSO", menuName = "Events/Unity Event Bus")] | ||
public class UnityEventBusSO : ScriptableObject, IUnityEventBus | ||
{ | ||
private readonly UnityEventBus _unityEventBus = new UnityEventBus(); | ||
|
||
public void Subscribe<T>(UnityAction<T> action) | ||
{ | ||
_unityEventBus.Subscribe(action); | ||
} | ||
|
||
public void Unsubscribe<T>(UnityAction<T> action) | ||
{ | ||
_unityEventBus.Unsubscribe(action); | ||
} | ||
|
||
public void Publish<T>(T msg) | ||
{ | ||
_unityEventBus.Publish(msg); | ||
} | ||
} |
3 changes: 3 additions & 0 deletions
3
UOP1_Project/Assets/Scripts/Events/ScriptableObjects/UnityEventBusSO.cs.meta
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using UnityEngine.Events; | ||
|
||
/// <summary> | ||
/// Enables loose coupling of events from publishers to subscribers | ||
/// | ||
/// A UnityAction based subscription where the T is event type used to find | ||
/// a suitable UnityAction. | ||
/// | ||
/// Note the code is typesafe although somewhat ugly with HashSet<object> holder. | ||
/// | ||
/// </summary> | ||
public interface IUnityEventBus | ||
{ | ||
public void Subscribe<T>(UnityAction<T> action); | ||
|
||
public void Unsubscribe<T>(UnityAction<T> action); | ||
|
||
public void Publish<T>(T msg); | ||
} | ||
|
||
public class UnityEventBus : IUnityEventBus | ||
{ | ||
private readonly Dictionary<Type, HashSet<object>> _handlers = new Dictionary<Type, HashSet<object>>(); | ||
|
||
public void Subscribe<T>(UnityAction<T> action) | ||
{ | ||
if (action == null) | ||
{ | ||
throw new ArgumentNullException(nameof(action)); | ||
} | ||
|
||
var type = typeof(T); | ||
|
||
if (!_handlers.TryGetValue(type, out var handlers)) | ||
{ | ||
handlers = new HashSet<object>(); | ||
_handlers[type] = handlers; | ||
} | ||
|
||
handlers.Add(action); | ||
} | ||
|
||
public void Unsubscribe<T>(UnityAction<T> action) | ||
{ | ||
if (action == null) | ||
{ | ||
throw new ArgumentNullException(nameof(action)); | ||
} | ||
|
||
var type = typeof(T); | ||
|
||
if (_handlers.TryGetValue(type, out var handlers)) | ||
{ | ||
handlers.Remove(action); | ||
} | ||
} | ||
|
||
public void Publish<T>(T msg) | ||
{ | ||
if (msg == null) | ||
{ | ||
throw new ArgumentNullException(nameof(msg)); | ||
} | ||
|
||
if (_handlers.TryGetValue(msg.GetType(), out var handlers)) | ||
{ | ||
foreach (var handler in handlers.Cast<UnityAction<T>>()) | ||
{ | ||
handler.Invoke(msg); | ||
} | ||
} | ||
} | ||
} |
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The naming here is gorgeous!