annotate Implab/AbstractPromise`1.cs @ 247:fb70574741a1 v3

working on promises
author cin
date Fri, 26 Jan 2018 18:46:27 +0300
parents
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
247
fb70574741a1 working on promises
cin
parents:
diff changeset
1 using System;
fb70574741a1 working on promises
cin
parents:
diff changeset
2 using System.Diagnostics;
fb70574741a1 working on promises
cin
parents:
diff changeset
3 using System.Reflection;
fb70574741a1 working on promises
cin
parents:
diff changeset
4 using Implab.Parallels;
fb70574741a1 working on promises
cin
parents:
diff changeset
5
fb70574741a1 working on promises
cin
parents:
diff changeset
6 namespace Implab {
fb70574741a1 working on promises
cin
parents:
diff changeset
7 public class AbstractPromise<T> : AbstractEvent<IResolvable<T>>, IPromise<T> {
fb70574741a1 working on promises
cin
parents:
diff changeset
8
fb70574741a1 working on promises
cin
parents:
diff changeset
9 class ResolvableSignal : IResolvable<T> {
fb70574741a1 working on promises
cin
parents:
diff changeset
10 public Signal Signal { get; private set; }
fb70574741a1 working on promises
cin
parents:
diff changeset
11 public ResolvableSignal() {
fb70574741a1 working on promises
cin
parents:
diff changeset
12 Signal = new Signal();
fb70574741a1 working on promises
cin
parents:
diff changeset
13 }
fb70574741a1 working on promises
cin
parents:
diff changeset
14
fb70574741a1 working on promises
cin
parents:
diff changeset
15
fb70574741a1 working on promises
cin
parents:
diff changeset
16 public void Reject(Exception error) {
fb70574741a1 working on promises
cin
parents:
diff changeset
17 Signal.Set();
fb70574741a1 working on promises
cin
parents:
diff changeset
18 }
fb70574741a1 working on promises
cin
parents:
diff changeset
19
fb70574741a1 working on promises
cin
parents:
diff changeset
20 public void Resolve(T result) {
fb70574741a1 working on promises
cin
parents:
diff changeset
21 Signal.Set();
fb70574741a1 working on promises
cin
parents:
diff changeset
22 }
fb70574741a1 working on promises
cin
parents:
diff changeset
23 }
fb70574741a1 working on promises
cin
parents:
diff changeset
24
fb70574741a1 working on promises
cin
parents:
diff changeset
25 class ResolvableWrapper : IResolvable<T> {
fb70574741a1 working on promises
cin
parents:
diff changeset
26 readonly IResolvable m_resolvable;
fb70574741a1 working on promises
cin
parents:
diff changeset
27 public ResolvableWrapper(IResolvable resolvable) {
fb70574741a1 working on promises
cin
parents:
diff changeset
28
fb70574741a1 working on promises
cin
parents:
diff changeset
29 }
fb70574741a1 working on promises
cin
parents:
diff changeset
30
fb70574741a1 working on promises
cin
parents:
diff changeset
31 public void Reject(Exception reason) {
fb70574741a1 working on promises
cin
parents:
diff changeset
32 m_resolvable.Reject(reason);
fb70574741a1 working on promises
cin
parents:
diff changeset
33 }
fb70574741a1 working on promises
cin
parents:
diff changeset
34
fb70574741a1 working on promises
cin
parents:
diff changeset
35 public void Resolve(T value) {
fb70574741a1 working on promises
cin
parents:
diff changeset
36 m_resolvable.Resolve();
fb70574741a1 working on promises
cin
parents:
diff changeset
37 }
fb70574741a1 working on promises
cin
parents:
diff changeset
38 }
fb70574741a1 working on promises
cin
parents:
diff changeset
39
fb70574741a1 working on promises
cin
parents:
diff changeset
40 PromiseState m_state;
fb70574741a1 working on promises
cin
parents:
diff changeset
41
fb70574741a1 working on promises
cin
parents:
diff changeset
42 T m_result;
fb70574741a1 working on promises
cin
parents:
diff changeset
43
fb70574741a1 working on promises
cin
parents:
diff changeset
44 Exception m_error;
fb70574741a1 working on promises
cin
parents:
diff changeset
45
fb70574741a1 working on promises
cin
parents:
diff changeset
46 public bool IsRejected {
fb70574741a1 working on promises
cin
parents:
diff changeset
47 get {
fb70574741a1 working on promises
cin
parents:
diff changeset
48 return m_state == PromiseState.Rejected;
fb70574741a1 working on promises
cin
parents:
diff changeset
49 }
fb70574741a1 working on promises
cin
parents:
diff changeset
50 }
fb70574741a1 working on promises
cin
parents:
diff changeset
51
fb70574741a1 working on promises
cin
parents:
diff changeset
52 public bool IsFulfilled {
fb70574741a1 working on promises
cin
parents:
diff changeset
53 get {
fb70574741a1 working on promises
cin
parents:
diff changeset
54 return m_state == PromiseState.Fulfilled;
fb70574741a1 working on promises
cin
parents:
diff changeset
55 }
fb70574741a1 working on promises
cin
parents:
diff changeset
56 }
fb70574741a1 working on promises
cin
parents:
diff changeset
57
fb70574741a1 working on promises
cin
parents:
diff changeset
58 public Exception RejectReason {
fb70574741a1 working on promises
cin
parents:
diff changeset
59 get {
fb70574741a1 working on promises
cin
parents:
diff changeset
60 return m_error;
fb70574741a1 working on promises
cin
parents:
diff changeset
61 }
fb70574741a1 working on promises
cin
parents:
diff changeset
62 }
fb70574741a1 working on promises
cin
parents:
diff changeset
63
fb70574741a1 working on promises
cin
parents:
diff changeset
64
fb70574741a1 working on promises
cin
parents:
diff changeset
65 internal void Resolve(T result) {
fb70574741a1 working on promises
cin
parents:
diff changeset
66 if (BeginTransit())
fb70574741a1 working on promises
cin
parents:
diff changeset
67 CompleteResolve();
fb70574741a1 working on promises
cin
parents:
diff changeset
68 }
fb70574741a1 working on promises
cin
parents:
diff changeset
69
fb70574741a1 working on promises
cin
parents:
diff changeset
70 internal void Reject(Exception reason) {
fb70574741a1 working on promises
cin
parents:
diff changeset
71 if (BeginTransit()) {
fb70574741a1 working on promises
cin
parents:
diff changeset
72 m_error = reason;
fb70574741a1 working on promises
cin
parents:
diff changeset
73 m_state = PromiseState.Rejected;
fb70574741a1 working on promises
cin
parents:
diff changeset
74 CompleteTransit();
fb70574741a1 working on promises
cin
parents:
diff changeset
75 }
fb70574741a1 working on promises
cin
parents:
diff changeset
76 }
fb70574741a1 working on promises
cin
parents:
diff changeset
77
fb70574741a1 working on promises
cin
parents:
diff changeset
78
fb70574741a1 working on promises
cin
parents:
diff changeset
79 #region implemented abstract members of AbstractPromise
fb70574741a1 working on promises
cin
parents:
diff changeset
80
fb70574741a1 working on promises
cin
parents:
diff changeset
81 protected override void SignalHandler(IResolvable<T> handler) {
fb70574741a1 working on promises
cin
parents:
diff changeset
82 switch (m_state) {
fb70574741a1 working on promises
cin
parents:
diff changeset
83 case PromiseState.Fulfilled:
fb70574741a1 working on promises
cin
parents:
diff changeset
84 handler.Resolve(m_result);
fb70574741a1 working on promises
cin
parents:
diff changeset
85 break;
fb70574741a1 working on promises
cin
parents:
diff changeset
86 case PromiseState.Rejected:
fb70574741a1 working on promises
cin
parents:
diff changeset
87 handler.Reject(RejectReason);
fb70574741a1 working on promises
cin
parents:
diff changeset
88 break;
fb70574741a1 working on promises
cin
parents:
diff changeset
89 default:
fb70574741a1 working on promises
cin
parents:
diff changeset
90 throw new InvalidOperationException(String.Format("Invalid promise signal: {0}", m_state));
fb70574741a1 working on promises
cin
parents:
diff changeset
91 }
fb70574741a1 working on promises
cin
parents:
diff changeset
92 }
fb70574741a1 working on promises
cin
parents:
diff changeset
93
fb70574741a1 working on promises
cin
parents:
diff changeset
94 protected override Signal GetFulfillSignal() {
fb70574741a1 working on promises
cin
parents:
diff changeset
95 var next = new ResolvableSignal();
fb70574741a1 working on promises
cin
parents:
diff changeset
96 Then(next);
fb70574741a1 working on promises
cin
parents:
diff changeset
97 return next.Signal;
fb70574741a1 working on promises
cin
parents:
diff changeset
98 }
fb70574741a1 working on promises
cin
parents:
diff changeset
99
fb70574741a1 working on promises
cin
parents:
diff changeset
100 #endregion
fb70574741a1 working on promises
cin
parents:
diff changeset
101
fb70574741a1 working on promises
cin
parents:
diff changeset
102 protected void CompleteResolve() {
fb70574741a1 working on promises
cin
parents:
diff changeset
103 m_state = PromiseState.Fulfilled;
fb70574741a1 working on promises
cin
parents:
diff changeset
104 CompleteTransit();
fb70574741a1 working on promises
cin
parents:
diff changeset
105 }
fb70574741a1 working on promises
cin
parents:
diff changeset
106
fb70574741a1 working on promises
cin
parents:
diff changeset
107 public Type ResultType {
fb70574741a1 working on promises
cin
parents:
diff changeset
108 get {
fb70574741a1 working on promises
cin
parents:
diff changeset
109 return typeof(void);
fb70574741a1 working on promises
cin
parents:
diff changeset
110 }
fb70574741a1 working on promises
cin
parents:
diff changeset
111 }
fb70574741a1 working on promises
cin
parents:
diff changeset
112
fb70574741a1 working on promises
cin
parents:
diff changeset
113
fb70574741a1 working on promises
cin
parents:
diff changeset
114 protected void Rethrow() {
fb70574741a1 working on promises
cin
parents:
diff changeset
115 Debug.Assert(m_error != null);
fb70574741a1 working on promises
cin
parents:
diff changeset
116 if (m_error is OperationCanceledException)
fb70574741a1 working on promises
cin
parents:
diff changeset
117 throw new OperationCanceledException("Operation cancelled", m_error);
fb70574741a1 working on promises
cin
parents:
diff changeset
118 else
fb70574741a1 working on promises
cin
parents:
diff changeset
119 throw new TargetInvocationException(m_error);
fb70574741a1 working on promises
cin
parents:
diff changeset
120 }
fb70574741a1 working on promises
cin
parents:
diff changeset
121
fb70574741a1 working on promises
cin
parents:
diff changeset
122 public void Then(IResolvable<T> next) {
fb70574741a1 working on promises
cin
parents:
diff changeset
123 AddHandler(next);
fb70574741a1 working on promises
cin
parents:
diff changeset
124 }
fb70574741a1 working on promises
cin
parents:
diff changeset
125
fb70574741a1 working on promises
cin
parents:
diff changeset
126 public void Then(IResolvable next) {
fb70574741a1 working on promises
cin
parents:
diff changeset
127 AddHandler(new ResolvableWrapper(next));
fb70574741a1 working on promises
cin
parents:
diff changeset
128 }
fb70574741a1 working on promises
cin
parents:
diff changeset
129
fb70574741a1 working on promises
cin
parents:
diff changeset
130 public IPromise<T2> Cast<T2>() {
fb70574741a1 working on promises
cin
parents:
diff changeset
131 return (IPromise<T2>)this;
fb70574741a1 working on promises
cin
parents:
diff changeset
132 }
fb70574741a1 working on promises
cin
parents:
diff changeset
133
fb70574741a1 working on promises
cin
parents:
diff changeset
134 void IPromise.Join() {
fb70574741a1 working on promises
cin
parents:
diff changeset
135 WaitResult(-1);
fb70574741a1 working on promises
cin
parents:
diff changeset
136 if (IsRejected)
fb70574741a1 working on promises
cin
parents:
diff changeset
137 Rethrow();
fb70574741a1 working on promises
cin
parents:
diff changeset
138 }
fb70574741a1 working on promises
cin
parents:
diff changeset
139
fb70574741a1 working on promises
cin
parents:
diff changeset
140 void IPromise.Join(int timeout) {
fb70574741a1 working on promises
cin
parents:
diff changeset
141 WaitResult(timeout);
fb70574741a1 working on promises
cin
parents:
diff changeset
142 if (IsRejected)
fb70574741a1 working on promises
cin
parents:
diff changeset
143 Rethrow();
fb70574741a1 working on promises
cin
parents:
diff changeset
144 }
fb70574741a1 working on promises
cin
parents:
diff changeset
145
fb70574741a1 working on promises
cin
parents:
diff changeset
146 public T Join() {
fb70574741a1 working on promises
cin
parents:
diff changeset
147 WaitResult(-1);
fb70574741a1 working on promises
cin
parents:
diff changeset
148 if (IsRejected)
fb70574741a1 working on promises
cin
parents:
diff changeset
149 Rethrow();
fb70574741a1 working on promises
cin
parents:
diff changeset
150 return m_result;
fb70574741a1 working on promises
cin
parents:
diff changeset
151 }
fb70574741a1 working on promises
cin
parents:
diff changeset
152
fb70574741a1 working on promises
cin
parents:
diff changeset
153 public T Join(int timeout) {
fb70574741a1 working on promises
cin
parents:
diff changeset
154 WaitResult(timeout);
fb70574741a1 working on promises
cin
parents:
diff changeset
155 if (IsRejected)
fb70574741a1 working on promises
cin
parents:
diff changeset
156 Rethrow();
fb70574741a1 working on promises
cin
parents:
diff changeset
157 return m_result;
fb70574741a1 working on promises
cin
parents:
diff changeset
158 }
fb70574741a1 working on promises
cin
parents:
diff changeset
159 }
fb70574741a1 working on promises
cin
parents:
diff changeset
160 }
fb70574741a1 working on promises
cin
parents:
diff changeset
161