-
Notifications
You must be signed in to change notification settings - Fork 126
/
Copy pathEventEngineInterfaces.cs
143 lines (117 loc) · 4.85 KB
/
EventEngineInterfaces.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
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
using System;
using System.Threading.Tasks;
using System.Collections.Generic;
namespace PubnubApi.EventEngine.Core
{
/// <summary>
/// Generic effect handler.
/// </summary>
public interface IEffectHandler
{
Task Cancel();
Task Run(IEffectInvocation invocation);
bool IsBackground(IEffectInvocation invocation);
}
/// <summary>
/// Handler (implementation) for a given invocation. The invocation represents the input arguments of a handler.
/// </summary>
/// <typeparam name="T">Associated invocation</typeparam>
public interface IEffectHandler<T> : IEffectHandler where T : IEffectInvocation
{
Task Run(T invocation);
bool IsBackground(T invocation);
}
public abstract class EffectHandler<T> : IEffectHandler<T>
where T : class, IEffectInvocation
{
public abstract Task Cancel();
public Task Run(IEffectInvocation invocation) => Run(invocation as T);
public bool IsBackground(IEffectInvocation invocation) => IsBackground(invocation as T);
public abstract Task Run(T invocation);
public abstract bool IsBackground(T invocation);
}
/// <summary>
/// Implement a handler a cancellable invocation.
/// </summary>
/// <typeparam name="T1">Connect type invocation</typeparam>
/// <typeparam name="T2">Cancel running invocation</typeparam>
public abstract class EffectCancellableHandler<T1, T2> : EffectHandler<T1>, IEffectHandler<T2>
where T1 : class, IEffectInvocation
where T2 : class, IEffectCancelInvocation
{
// run is not implemented in cancel.
public Task Run(T2 invocation)
{
throw new NotImplementedException();
}
public bool IsBackground(T2 invocation) => false;
}
/// <summary>
/// Implement a handler for two invocations (meant for connect-reconnect pairs). Use EffectDoubleCancellableHandler to implement cancellable handler.
/// </summary>
/// <typeparam name="T1">Run type invocation</typeparam>
/// <typeparam name="T2">Retry type invocation</typeparam>
public abstract class EffectDoubleHandler<T1, T2> : EffectHandler<T1>, IEffectHandler<T2>
where T1 : class, IEffectInvocation
where T2 : class, IEffectInvocation
{
public new Task Run(IEffectInvocation invocation) =>
invocation is T1 ? (this as EffectHandler<T1>).Run(invocation) : Run(invocation as T2);
public new bool IsBackground(IEffectInvocation invocation) =>
invocation is T1 ? (this as EffectHandler<T1>).IsBackground(invocation) : IsBackground(invocation as T2);
public abstract Task Run(T2 invocation);
public abstract bool IsBackground(T2 invocation);
}
/// <summary>
/// Implement a handler for two invocations (meant for connect-reconnect pairs) with a cancel invocation
/// </summary>
/// <typeparam name="T1">Run type invocation</typeparam>
/// <typeparam name="T2">Retry type invocation</typeparam>
/// <typeparam name="T3">Cancel connecting invocation</typeparam>
public abstract class EffectDoubleCancellableHandler<T1, T2, T3> : EffectDoubleHandler<T1, T2>, IEffectHandler<T3>
where T1 : class, IEffectInvocation
where T2 : class, IEffectInvocation
where T3 : class, IEffectCancelInvocation
{
// Run is not implemented in cancel.
public Task Run(T3 invocation)
{
throw new NotImplementedException();
}
public bool IsBackground(T3 invocation) => false;
}
/// <summary>
/// An effect invocation. It represents calling <c>Run()</c> on a registered effect handler - calling it is orchestrated by the dispatcher.
/// </summary>
public interface IEffectInvocation
{
}
/// <summary>
/// A cancel effect invocation. It represents calling <c>Cancel()</c> on a registered effect handler - calling it is orchestrated by the dispatcher.
/// </summary>
public interface IEffectCancelInvocation : IEffectInvocation
{
}
public interface IEvent
{
};
public abstract class State
{
public virtual IEnumerable<IEffectInvocation> OnEntry { get; } = null;
public virtual IEnumerable<IEffectInvocation> OnExit { get; } = null;
/// <summary>
/// The EE transition pure function.
/// </summary>
/// <param name="e">Input event</param>
/// <returns>Target state and invocation list, or null for no-transition</returns>
public abstract TransitionResult Transition(IEvent e);
public TransitionResult With(params IEffectInvocation[] invocations)
{
return new TransitionResult(this, invocations);
}
public static implicit operator TransitionResult(State s)
{
return new TransitionResult(s);
}
}
}