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

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