-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathInterfaceCompatibleSignalBus.cs
More file actions
77 lines (64 loc) · 1.97 KB
/
InterfaceCompatibleSignalBus.cs
File metadata and controls
77 lines (64 loc) · 1.97 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
using System;
using System.Collections.Generic;
using UnityEngine;
///<Summary>Interface compatible version</Summary>
///<remarks>dont use with struct signals to avoid garbage generation by boxing </remarks>
public static class SignalBus
{
static Dictionary<Type, Action<object>> actions;
static Dictionary<Type, Type[]> cachedInterfacesByType;
public static IDisposable Subscribe<T>(Action<T> action)
{
Action<object> objectAction = new Action<object>(o => action((T)o));
Type paramType = typeof(T);
if (actions.ContainsKey(paramType))
actions[paramType] += objectAction;
else
actions.Add(paramType, objectAction);
return new Subscription(paramType, objectAction);
}
public static void Fire<T>(T t)
{
if (actions.TryGetValue(typeof(T), out var action))
action(t);
else Debug.LogError($"Type of {typeof(T)} is trying to be fired as signal but is not subscribed anywhere");
}
public static void AbstractFire<T>(T t, bool includeConcrete = false)
{
if (includeConcrete)
Fire(t);
Action<object> actionFromDic;
Type[] types = GetOrCreateInterfaceArrayForType(typeof(T));
foreach (Type type in types)
{
if (actions.TryGetValue(type, out actionFromDic))
actionFromDic?.Invoke(t);
}
}
static Type[] GetOrCreateInterfaceArrayForType(Type type)
{
Type[] interfaces;
if (cachedInterfacesByType.TryGetValue(type, out interfaces))
return interfaces;
interfaces = type.GetInterfaces();
cachedInterfacesByType.Add(type, interfaces);
return interfaces;
}
static void Unsusbscribe(Type paramType, Action<object> action)
{
if (actions.ContainsKey(paramType))
actions[paramType] -= action;
}
//Subscription registered for Interface compatible version
class Subscription : IDisposable
{
Type paramType;
Action<object> boundAction;
public Subscription(Type paramType, Action<object> boundAction)
{
this.paramType = paramType;
this.boundAction = boundAction;
}
public void Dispose() => Unsusbscribe(paramType, boundAction);
}
}