Skip to content

Commit d6e149b

Browse files
committed
Added Safe Event
1 parent c9aabb7 commit d6e149b

13 files changed

+306
-0
lines changed

Runtime.meta

Lines changed: 8 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
using System;
2+
3+
namespace TNRD.Events
4+
{
5+
public class DuplicateSubscriptionException : Exception
6+
{
7+
}
8+
}

Runtime/DuplicateSubscriptionException.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.

Runtime/SafeEvent.cs

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using UnityEngine;
4+
5+
namespace TNRD.Events
6+
{
7+
public struct SafeEvent
8+
{
9+
private HashSet<Action> subscriptions;
10+
11+
public int Count => subscriptions?.Count ?? 0;
12+
13+
public void RemoveAllSubscriptions()
14+
{
15+
subscriptions.Clear();
16+
}
17+
18+
public void Invoke()
19+
{
20+
foreach (var subscription in subscriptions)
21+
{
22+
#if UNITY_EDITOR || DEBUG
23+
ThrowIfInvalidSubscription(subscription);
24+
#endif
25+
subscription?.Invoke();
26+
}
27+
}
28+
29+
private static void ThrowIfInvalidSubscription(Action subscription)
30+
{
31+
if (subscription?.Target == null)
32+
{
33+
throw new SubscriptionIsNullException();
34+
}
35+
36+
if (subscription.Target is Component component && !component)
37+
{
38+
throw new SubscriptionIsNullException();
39+
}
40+
41+
if (subscription.Target is GameObject gameObject && !gameObject)
42+
{
43+
throw new SubscriptionIsNullException();
44+
}
45+
}
46+
47+
public void Subscribe(Action action)
48+
{
49+
if (subscriptions == null)
50+
{
51+
subscriptions = new HashSet<Action>();
52+
}
53+
54+
if (subscriptions.Contains(action))
55+
{
56+
#if UNITY_EDITOR || DEBUG
57+
throw new DuplicateSubscriptionException();
58+
#endif
59+
return;
60+
}
61+
62+
subscriptions.Add(action);
63+
}
64+
65+
public void Unsubscribe(Action action)
66+
{
67+
subscriptions?.Remove(action);
68+
}
69+
70+
public static SafeEvent operator +(SafeEvent safeEvent, Action action)
71+
{
72+
safeEvent.Subscribe(action);
73+
return safeEvent;
74+
}
75+
76+
public static SafeEvent operator -(SafeEvent safeEvent, Action action)
77+
{
78+
safeEvent.Unsubscribe(action);
79+
return safeEvent;
80+
}
81+
}
82+
}

Runtime/SafeEvent.cs.meta

Lines changed: 11 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Runtime/SafeEventOneParameter.cs

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using UnityEngine;
4+
5+
namespace TNRD.Events
6+
{
7+
public struct SafeEvent<T>
8+
{
9+
private HashSet<Action<T>> subscriptions;
10+
11+
public int Count => subscriptions?.Count ?? 0;
12+
13+
public void RemoveAllSubscriptions()
14+
{
15+
subscriptions.Clear();
16+
}
17+
18+
public void Invoke(T obj)
19+
{
20+
foreach (var subscription in subscriptions)
21+
{
22+
#if UNITY_EDITOR || DEBUG
23+
ThrowIfInvalidSubscription(subscription);
24+
#endif
25+
subscription?.Invoke(obj);
26+
}
27+
}
28+
29+
private static void ThrowIfInvalidSubscription(Action<T> subscription)
30+
{
31+
if (subscription?.Target == null)
32+
{
33+
throw new SubscriptionIsNullException();
34+
}
35+
36+
if (subscription.Target is Component component && !component)
37+
{
38+
throw new SubscriptionIsNullException();
39+
}
40+
41+
if (subscription.Target is GameObject gameObject && !gameObject)
42+
{
43+
throw new SubscriptionIsNullException();
44+
}
45+
}
46+
47+
public void Subscribe(Action<T> action)
48+
{
49+
if (subscriptions == null)
50+
{
51+
subscriptions = new HashSet<Action<T>>();
52+
}
53+
54+
if (subscriptions.Contains(action))
55+
{
56+
#if UNITY_EDITOR || DEBUG
57+
throw new DuplicateSubscriptionException();
58+
#endif
59+
return;
60+
}
61+
62+
subscriptions.Add(action);
63+
}
64+
65+
public void Unsubscribe(Action<T> action)
66+
{
67+
subscriptions?.Remove(action);
68+
}
69+
70+
public static SafeEvent<T> operator +(SafeEvent<T> safeEvent, Action<T> action)
71+
{
72+
safeEvent.Subscribe(action);
73+
return safeEvent;
74+
}
75+
76+
public static SafeEvent<T> operator -(SafeEvent<T> safeEvent, Action<T> action)
77+
{
78+
safeEvent.Unsubscribe(action);
79+
return safeEvent;
80+
}
81+
}
82+
}

Runtime/SafeEventOneParameter.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.

Runtime/SafeEventTwoParameters.cs

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using UnityEngine;
4+
5+
namespace TNRD.Events
6+
{
7+
public struct SafeEvent<T, T2>
8+
{
9+
private HashSet<Action<T, T2>> subscriptions;
10+
11+
public int Count => subscriptions?.Count ?? 0;
12+
13+
public void RemoveAllSubscriptions()
14+
{
15+
subscriptions.Clear();
16+
}
17+
18+
public void Invoke(T arg1, T2 arg2)
19+
{
20+
foreach (var subscription in subscriptions)
21+
{
22+
#if UNITY_EDITOR || DEBUG
23+
ThrowIfInvalidSubscription(subscription);
24+
#endif
25+
subscription?.Invoke(arg1, arg2);
26+
}
27+
}
28+
29+
private static void ThrowIfInvalidSubscription(Action<T, T2> subscription)
30+
{
31+
if (subscription?.Target == null)
32+
{
33+
throw new SubscriptionIsNullException();
34+
}
35+
36+
if (subscription.Target is Component component && !component)
37+
{
38+
throw new SubscriptionIsNullException();
39+
}
40+
41+
if (subscription.Target is GameObject gameObject && !gameObject)
42+
{
43+
throw new SubscriptionIsNullException();
44+
}
45+
}
46+
47+
public void Subscribe(Action<T, T2> action)
48+
{
49+
if (subscriptions == null)
50+
{
51+
subscriptions = new HashSet<Action<T, T2>>();
52+
}
53+
54+
if (subscriptions.Contains(action))
55+
{
56+
#if UNITY_EDITOR || DEBUG
57+
throw new DuplicateSubscriptionException();
58+
#endif
59+
return;
60+
}
61+
62+
subscriptions.Add(action);
63+
}
64+
65+
public void Unsubscribe(Action<T, T2> action)
66+
{
67+
subscriptions?.Remove(action);
68+
}
69+
70+
public static SafeEvent<T, T2> operator +(SafeEvent<T, T2> safeEvent, Action<T, T2> action)
71+
{
72+
safeEvent.Subscribe(action);
73+
return safeEvent;
74+
}
75+
76+
public static SafeEvent<T, T2> operator -(SafeEvent<T, T2> safeEvent, Action<T, T2> action)
77+
{
78+
safeEvent.Unsubscribe(action);
79+
return safeEvent;
80+
}
81+
}
82+
}

Runtime/SafeEventTwoParameters.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: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
using System;
2+
3+
namespace TNRD.Events
4+
{
5+
public class SubscriptionIsNullException : Exception
6+
{
7+
}
8+
}

0 commit comments

Comments
 (0)