-
Notifications
You must be signed in to change notification settings - Fork 18
/
KeyWatcher.cs
56 lines (48 loc) · 1.45 KB
/
KeyWatcher.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
namespace FundamentalInterfaces;
public class KeyWatcher : IObservable<char>
{
private readonly List<Subscription> _subscriptions = new();
public IDisposable Subscribe(IObserver<char> observer)
{
var sub = new Subscription(this, observer);
_subscriptions.Add(sub);
return sub;
}
public void Run()
{
while (true)
{
// Passing true here stops the console from showing the character
char c = Console.ReadKey(true).KeyChar;
// ToArray duplicates the list, enabling us to iterate over a
// snapshot of our subscribers. This handles the case where an
// observer unsubscribes from inside its OnNext method.
foreach (Subscription sub in _subscriptions.ToArray())
{
sub.Observer.OnNext(c);
}
}
}
private void RemoveSubscription(Subscription sub)
{
_subscriptions.Remove(sub);
}
private class Subscription : IDisposable
{
private KeyWatcher? _parent;
public Subscription(KeyWatcher parent, IObserver<char> observer)
{
_parent = parent;
Observer = observer;
}
public IObserver<char> Observer { get; }
public void Dispose()
{
if (_parent != null)
{
_parent.RemoveSubscription(this);
_parent = null;
}
}
}
}