Skip to content

Commit 30d37e2

Browse files
committed
First Public Release of Event Framework
Introducing the first release of Event Framework - including Messenger for managing subscribers, publishing Payloads (events) and getting current statuses.
1 parent 8d9f930 commit 30d37e2

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+1222
-2
lines changed

DevsDaddy/Shared/EventFramework/Core.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.

DevsDaddy/Shared/EventFramework/Core/Extensions.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: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
using System;
2+
using System.Collections.Generic;
3+
4+
namespace DevsDaddy.Shared.EventFramework.Core.Extensions
5+
{
6+
public static class CollectionExtensions
7+
{
8+
public static object[] ToObjectArray<T>(this T[] source)
9+
{
10+
if(source.IsNullOrEmpty())
11+
{
12+
return null;
13+
}
14+
var copy = new object[source.Length];
15+
Array.Copy(source, copy, source.Length);
16+
return copy;
17+
}
18+
19+
public static bool IsNullOrEmpty<T>(this ICollection<T> source)
20+
{
21+
if(source == null)
22+
{
23+
return true;
24+
}
25+
if(source.Count < 1)
26+
{
27+
return true;
28+
}
29+
return false;
30+
}
31+
32+
public static void ForEach<T>(this IEnumerable<T> collection, Action<T> action)
33+
{
34+
foreach (var item in collection)
35+
{
36+
action(item);
37+
}
38+
}
39+
40+
public static bool IsNullOrEmpty(this string source)
41+
{
42+
var isEmpty = string.IsNullOrEmpty(source);
43+
return isEmpty;
44+
}
45+
}
46+
}

DevsDaddy/Shared/EventFramework/Core/Extensions/CollectionExtensions.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.

DevsDaddy/Shared/EventFramework/Core/Messenger.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: 164 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,164 @@
1+
using System;
2+
using System.Reflection;
3+
using UnityEngine;
4+
5+
namespace DevsDaddy.Shared.EventFramework.Core.Messenger
6+
{
7+
/// <summary>
8+
/// Event Subscriber Class
9+
/// </summary>
10+
internal class EventSubscriber : IDisposable
11+
{
12+
private WeakReference _callbackTarget;
13+
private MethodInfo _callbackMethod;
14+
15+
private WeakReference _predicateTarget;
16+
private MethodInfo _predicateMethod;
17+
18+
public bool IsAlive
19+
{
20+
get
21+
{
22+
if(_callbackMethod == null)
23+
{
24+
return false;
25+
}
26+
if(_callbackMethod.IsStatic)
27+
{
28+
return true;
29+
}
30+
if(_callbackTarget == null ||
31+
!_callbackTarget.IsAlive ||
32+
_callbackTarget.Target == null)
33+
{
34+
return false;
35+
}
36+
return true;
37+
}
38+
}
39+
40+
public Type PayloadType
41+
{
42+
get;
43+
}
44+
45+
public int Id
46+
{
47+
get;
48+
}
49+
50+
public override int GetHashCode()
51+
{
52+
return Id;
53+
}
54+
55+
public EventSubscriber(Type payloadType, Delegate callback, Delegate predicate = null)
56+
{
57+
// validate params
58+
if(payloadType == null)
59+
{
60+
throw new ArgumentNullException(nameof(payloadType));
61+
}
62+
if(callback == null)
63+
{
64+
throw new ArgumentNullException(nameof(callback));
65+
}
66+
67+
// assign values to vars
68+
PayloadType = payloadType;
69+
Id = callback.GetHashCode();
70+
_callbackMethod = callback.Method;
71+
72+
// check if callback method is not a static method
73+
if(!_callbackMethod.IsStatic &&
74+
callback.Target != null)
75+
{
76+
// init weak reference to callback owner
77+
_callbackTarget = new WeakReference(callback.Target);
78+
}
79+
80+
// --- init predicate ---
81+
if(predicate == null)
82+
{
83+
return;
84+
}
85+
_predicateMethod = predicate.Method;
86+
87+
if(!_predicateMethod.IsStatic &&
88+
!Equals(predicate.Target, callback.Target))
89+
{
90+
_predicateTarget = new WeakReference(predicate.Target);
91+
}
92+
}
93+
94+
public void Invoke<T>(T payload)
95+
{
96+
// validate callback method info
97+
if(_callbackMethod == null)
98+
{
99+
Debug.LogError($"{nameof(_callbackMethod)} is null.");
100+
return;
101+
}
102+
if(!_callbackMethod.IsStatic &&
103+
(_callbackTarget == null ||
104+
!_callbackTarget.IsAlive))
105+
{
106+
Debug.LogWarning($"{nameof(_callbackMethod)} is not alive.");
107+
return;
108+
}
109+
110+
// get reference to the predicate function owner
111+
if(_predicateMethod != null)
112+
{
113+
object predicateTarget = null;
114+
if(!_predicateMethod.IsStatic)
115+
{
116+
if(_predicateTarget != null &&
117+
_predicateTarget.IsAlive)
118+
{
119+
predicateTarget = _predicateTarget.Target;
120+
}
121+
else if(_callbackTarget != null &&
122+
_callbackTarget.IsAlive)
123+
{
124+
predicateTarget = _callbackTarget.Target;
125+
}
126+
}
127+
128+
// check if predicate returned 'true'
129+
var isAccepted = (bool)_predicateMethod.Invoke(predicateTarget, new object[] {payload});
130+
if(!isAccepted)
131+
{
132+
// TODO log ?
133+
return;
134+
}
135+
}
136+
137+
// invoke callback method
138+
object callbackTarget = null;
139+
if(!_callbackMethod.IsStatic &&
140+
_callbackTarget != null && _callbackTarget.IsAlive)
141+
{
142+
callbackTarget = _callbackTarget.Target;
143+
}
144+
_callbackMethod.Invoke(callbackTarget, new object[] {payload});
145+
}
146+
147+
public void Dispose()
148+
{
149+
_callbackMethod = null;
150+
if(_callbackTarget != null)
151+
{
152+
_callbackTarget.Target = null;
153+
_callbackTarget = null;
154+
}
155+
156+
_predicateMethod = null;
157+
if(_predicateTarget != null)
158+
{
159+
_predicateTarget.Target = null;
160+
_predicateTarget = null;
161+
}
162+
}
163+
}
164+
}

DevsDaddy/Shared/EventFramework/Core/Messenger/EventSubscriber.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: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
namespace DevsDaddy.Shared.EventFramework.Core.Messenger
2+
{
3+
/// <summary>
4+
/// Event Messenger Interface
5+
/// </summary>
6+
public interface IEventMessenger : IEventMessengerPublish, IEventMessengerSubscribe, IEventMessengerUnsubscribe { }
7+
}

DevsDaddy/Shared/EventFramework/Core/Messenger/IEventMessenger.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: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
using DevsDaddy.Shared.EventFramework.Core.Payloads;
2+
3+
namespace DevsDaddy.Shared.EventFramework.Core.Messenger
4+
{
5+
/// <summary>
6+
/// Event Messenger Publish Interface
7+
/// </summary>
8+
public interface IEventMessengerPublish
9+
{
10+
/// <summary>
11+
/// Publish Payload
12+
/// </summary>
13+
/// <param name="payload"></param>
14+
/// <typeparam name="T"></typeparam>
15+
/// <returns></returns>
16+
IEventMessengerPublish Publish<T>(T payload) where T : IPayload;
17+
18+
/// <summary>
19+
/// Get Current Payload State or Null
20+
/// </summary>
21+
/// <typeparam name="T"></typeparam>
22+
/// <returns></returns>
23+
T GetState<T>() where T : class, IPayload;
24+
}
25+
}

0 commit comments

Comments
 (0)