-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathGlobalEvent.cs
109 lines (101 loc) · 3.76 KB
/
GlobalEvent.cs
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
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
using System.Collections.Generic;
namespace ru.mofrison.GlobalEvent
{
/// <summary>
/// A base class that is used to implement the mechanism for subscribing to global events
/// Supports adding multiple subscribers as delegates at once
/// </summary>
/// <typeparam name="T">Extended from <see cref="GlobalEvent<T>"/></typeparam>
public abstract class GlobalEvent<T> where T : GlobalEvent<T>
{
/// <summary>
/// Container for global event handlers
/// </summary>
/// <param name="globalEvent">Signal instance</param>
public delegate void Hendler(T globalEvent);
private static Hendler hendlers;
private static HashSet<int> hashs = new HashSet<int>();
/// <summary>
/// Checks if this handler is subscribed to this event
/// </summary>
/// <param name="hendler">Event handler</param>
/// <returns>Returns <see cref="true"/> if the handler was already subscribed to this event</returns>
private static bool Contains(Hendler hendler)
{
return hashs.Contains(hendler.GetHashCode());
}
/// <summary>
/// Adds handlers
/// </summary>
/// <param name="hendler">Method reference or delegates with one parameter of type <see cref="T"/></param>
public static void Subscribe(Hendler hendler)
{
for (int i = 0; i < hendler.GetInvocationList().Length; i++)
{
AddHendler((Hendler)(hendler.GetInvocationList()[i]));
}
}
/// <summary>
/// Removes handlers
/// </summary>
/// <param name="hendler">Method reference or delegates with one parameter of type <see cref="T"/></param>
public static void Unsubscribe(Hendler hendler)
{
for (int i = 0; i < hendler.GetInvocationList().Length; i++)
{
RemoveHendler((Hendler)(hendler.GetInvocationList()[i]));
}
}
/// <summary>
/// The method required to send the global event
/// </summary>
/// <param name="globalEvent">Typed event instance</param>
protected static void Handle(T globalEvent)
{
try
{
hendlers.Invoke(globalEvent);
}
catch (System.NullReferenceException e)
{
throw new Exception(e.Message);
}
}
/// <summary>
/// Adds a method if it hasn't already been added
/// </summary>
/// <param name="hendler">Reference to a method</param>
private static void AddHendler(Hendler hendler)
{
var hash = hendler.GetHashCode();
if (!hashs.Contains(hash))
{
hendlers += hendler;
hashs.Add(hash);
}
else throw new Exception($"The {hendler.Method} has already been added in {typeof(T)} hendlers");
}
/// <summary>
/// Remove a method if it has been added
/// </summary>
/// <param name="hendler">Reference to a method</param>
private static void RemoveHendler(Hendler hendler)
{
var hash = hendler.GetHashCode();
if (hashs.Contains(hash))
{
hendlers -= hendler;
hashs.Remove(hash);
}
else throw new Exception($"The {hendler.Method} has not been added in {typeof(T)} hendlers");
}
/// <summary>
/// Exception generated if no one is subscribed to it at the time of sending the global event.
/// </summary>
public class Exception : System.Exception
{
public Exception(string message) : base(message)
{ }
}
}
}