-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathChannelControl.cs
More file actions
119 lines (108 loc) · 3 KB
/
ChannelControl.cs
File metadata and controls
119 lines (108 loc) · 3 KB
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
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Newtonsoft.Json.Linq;
namespace Lily
{
public class ChannelControl
{
private Channel _channel;
private TaskCompletionSource<object> _tcs;
private Dictionary<string, TaskCompletionSource<JToken>> _waitingMessages = new Dictionary<string, TaskCompletionSource<JToken>>();
internal ChannelControl(Channel channel)
{
_channel = channel;
_tcs = new TaskCompletionSource<object>();
_tcs.SetResult(null);
}
internal void Reset()
{
_tcs = new TaskCompletionSource<object>();
_waitingMessages = new Dictionary<string, TaskCompletionSource<JToken>>();
foreach (Delegate d in _delegates)
{
_messageReceived -= (EventHandler<MessageReceiveEventArgs>)d;
}
_delegates.Clear();
foreach (Delegate d in _messageUpdatedDelegates)
{
_messageUpdated -= (EventHandler<MessageReceiveEventArgs>)d;
}
_messageUpdatedDelegates.Clear();
}
internal async Task Receive(string id, JToken message)
{
var deferralTcs = new TaskCompletionSource<object>();
var deferral = new Deferral(deferralTcs);
_messageReceived?.Invoke(this, new MessageReceiveEventArgs { Message = message, Deferral = deferral } );
deferral.StartWaiting();
await deferralTcs.Task;
lock (_waitingMessages)
{
var username = message["author"].Value<string>("username");
if (_waitingMessages.TryGetValue(username, out var tcs))
{
tcs.SetResult(message);
_waitingMessages.Remove(username);
}
}
}
internal void Update(string id, JToken message)
{
var deferral = new Deferral(new TaskCompletionSource<object>());
_messageUpdated?.Invoke(this, new MessageReceiveEventArgs { Message = message, Deferral = deferral } );
}
private event EventHandler<MessageReceiveEventArgs> _messageReceived;
HashSet<Delegate> _delegates = new HashSet<Delegate>();
public event EventHandler<MessageReceiveEventArgs> MessageReceived
{
add
{
_messageReceived += value;
_delegates.Add(value);
}
remove
{
_messageReceived -= value;
_delegates.Remove(value);
}
}
private event EventHandler<MessageReceiveEventArgs> _messageUpdated;
HashSet<Delegate> _messageUpdatedDelegates = new HashSet<Delegate>();
public event EventHandler<MessageReceiveEventArgs> MessageUpdated
{
add
{
_messageUpdated += value;
_messageUpdatedDelegates.Add(value);
}
remove
{
_messageUpdated -= value;
_messageUpdatedDelegates.Remove(value);
}
}
public void Release()
{
_tcs.SetResult(null);
}
public Task Wait()
{
return _tcs.Task;
}
public async Task<string> SendMessageAsync(string content)
{
return await _channel.SendMessageRawAsync(content, true);
}
// Waits for a repsonse from a user with the specified name.
public async Task<JToken> WaitForResponseAsync(string username)
{
var tcs = new TaskCompletionSource<JToken>();
lock (_waitingMessages)
{
_waitingMessages.Add(username, tcs);
}
return await tcs.Task;
}
}
}