144
|
1 using System;
|
|
2 using Implab.Parallels;
|
|
3
|
|
4 namespace Implab {
|
|
5 public abstract class AbstractPromise<T> : AbstractEvent<AbstractPromise<T>.HandlerDescriptor>, IPromise<T> {
|
|
6 public struct HandlerDescriptor {
|
|
7 readonly Action m_handler;
|
|
8 readonly Action<T> m_success;
|
|
9 readonly Action<Exception> m_error;
|
|
10 readonly Action<Exception> m_cancel;
|
|
11 readonly PromiseEventType m_mask;
|
|
12
|
|
13 public HandlerDescriptor(Action<T> success, Action<Exception> error, Action<Exception> cancel) {
|
|
14 m_success = success;
|
|
15 m_error = error;
|
|
16 m_cancel = cancel;
|
145
|
17
|
|
18 m_handler = null;
|
|
19 m_mask = 0;
|
144
|
20 }
|
|
21
|
|
22 public HandlerDescriptor(Action success, Action<Exception> error, Action<Exception> cancel) {
|
|
23 m_handler = success;
|
145
|
24 m_success = null;
|
144
|
25 m_error = error;
|
|
26 m_cancel = cancel;
|
|
27 m_mask = PromiseEventType.Success;
|
|
28 }
|
|
29
|
|
30 public HandlerDescriptor(Action handler, PromiseEventType mask) {
|
|
31 m_handler = handler;
|
|
32 m_mask = mask;
|
145
|
33 m_success = null;
|
|
34 m_error = null;
|
|
35 m_cancel = null;
|
144
|
36 }
|
|
37
|
|
38 public void SignalSuccess(T result) {
|
|
39 if (m_success != null) {
|
|
40 try {
|
|
41 m_success(result);
|
|
42 } catch(Exception err) {
|
|
43 SignalError(err);
|
|
44 }
|
145
|
45 } else if ((m_mask & PromiseEventType.Success) != 0 && m_handler != null) {
|
144
|
46 try {
|
|
47 m_handler();
|
|
48 } catch(Exception err) {
|
|
49 // avoid calling handler twice in case of error
|
|
50 if (m_error != null)
|
|
51 SignalError(err);
|
|
52 }
|
|
53 }
|
|
54 }
|
|
55
|
|
56 public void SignalError(Exception err) {
|
|
57 if (m_error != null) {
|
|
58 try {
|
|
59 m_error(err);
|
|
60 // Analysis disable once EmptyGeneralCatchClause
|
|
61 } catch {
|
|
62 }
|
145
|
63 } else if ((m_mask & PromiseEventType.Error) != 0 && m_handler != null) {
|
144
|
64 try {
|
|
65 m_handler();
|
|
66 // Analysis disable once EmptyGeneralCatchClause
|
|
67 } catch {
|
|
68 }
|
|
69 }
|
|
70 }
|
|
71
|
|
72 public void SignalCancel(Exception reason) {
|
|
73 if (m_cancel != null) {
|
|
74 try {
|
|
75 m_cancel(reason);
|
|
76 } catch (Exception err) {
|
|
77 SignalError(err);
|
|
78 }
|
145
|
79 } else if ((m_mask & PromiseEventType.Cancelled) != 0 && m_handler != null) {
|
144
|
80 try {
|
|
81 m_handler();
|
|
82 // Analysis disable once EmptyGeneralCatchClause
|
|
83 } catch {
|
|
84 }
|
|
85 }
|
|
86 }
|
|
87 }
|
|
88
|
|
89 public Type PromiseType {
|
|
90 get {
|
|
91 return typeof(T);
|
|
92 }
|
|
93 }
|
|
94
|
145
|
95 public T Join() {
|
144
|
96 WaitResult(-1);
|
|
97 return m_result;
|
|
98 }
|
145
|
99 public T Join(int timeout) {
|
144
|
100 WaitResult(timeout);
|
|
101 return m_result;
|
|
102 }
|
|
103
|
145
|
104 void IPromise.Join() {
|
|
105 WaitResult(-1);
|
|
106 }
|
|
107 void IPromise.Join(int timeout) {
|
|
108 WaitResult(timeout);
|
|
109 }
|
|
110
|
144
|
111 public IPromise<T> On(Action<T> success, Action<Exception> error, Action<Exception> cancel) {
|
|
112 AddHandler(new HandlerDescriptor(success, error, cancel));
|
|
113 return this;
|
|
114 }
|
|
115
|
|
116 public IPromise<T> On(Action<T> success, Action<Exception> error) {
|
|
117 AddHandler(new HandlerDescriptor(success, error, null));
|
|
118 return this;
|
|
119 }
|
|
120
|
|
121 public IPromise<T> On(Action<T> success) {
|
|
122 AddHandler(new HandlerDescriptor(success, null, null));
|
|
123 return this;
|
|
124 }
|
|
125
|
|
126 public IPromise<T> On(Action handler, PromiseEventType events) {
|
|
127 AddHandler(new HandlerDescriptor(handler, events));
|
|
128 return this;
|
|
129 }
|
|
130
|
|
131 public IPromise<T> On(Action success, Action<Exception> error, Action<Exception> cancel) {
|
|
132 AddHandler(new HandlerDescriptor(success, error, cancel));
|
|
133 return this;
|
|
134 }
|
|
135
|
|
136 public IPromise<T> On(Action success, Action<Exception> error) {
|
|
137 AddHandler(new HandlerDescriptor(success, error, null));
|
|
138 return this;
|
|
139 }
|
|
140
|
|
141 public IPromise<T> On(Action success) {
|
|
142 AddHandler(new HandlerDescriptor(success, null, null));
|
|
143 return this;
|
|
144 }
|
|
145
|
|
146 IPromise IPromise.On(Action success, Action<Exception> error, Action<Exception> cancel) {
|
|
147 AddHandler(new HandlerDescriptor(success, error, cancel));
|
|
148 return this;
|
|
149 }
|
|
150
|
|
151 IPromise IPromise.On(Action success, Action<Exception> error) {
|
|
152 AddHandler(new HandlerDescriptor(success, error, null));
|
|
153 return this;
|
|
154 }
|
|
155
|
|
156 IPromise IPromise.On(Action success) {
|
|
157 AddHandler(new HandlerDescriptor(success, null, null));
|
|
158 return this;
|
|
159 }
|
|
160
|
145
|
161 IPromise IPromise.On(Action handler, PromiseEventType events) {
|
|
162 AddHandler(new HandlerDescriptor(handler, events));
|
|
163 return this;
|
|
164 }
|
|
165
|
144
|
166 public IPromise<T2> Cast<T2>() {
|
|
167 return (IPromise<T2>)this;
|
|
168 }
|
|
169
|
|
170 #region implemented abstract members of AbstractPromise
|
|
171
|
|
172 protected override Signal GetResolveSignal() {
|
|
173 var signal = new Signal();
|
|
174 AddHandler(new HandlerDescriptor(signal.Set, PromiseEventType.All));
|
|
175 return signal;
|
|
176 }
|
|
177
|
|
178 protected override void SignalSuccess(HandlerDescriptor handler) {
|
|
179 handler.SignalSuccess(m_result);
|
|
180 }
|
|
181
|
|
182 protected override void SignalError(HandlerDescriptor handler, Exception error) {
|
|
183 handler.SignalError(error);
|
|
184 }
|
|
185
|
|
186 protected override void SignalCancelled(HandlerDescriptor handler, Exception reason) {
|
|
187 handler.SignalCancel(reason);
|
|
188 }
|
|
189
|
|
190 #endregion
|
|
191
|
|
192 T m_result;
|
|
193
|
|
194 protected void SetResult(T value) {
|
|
195 if (BeginSetResult()) {
|
|
196 m_result = value;
|
|
197 EndSetResult();
|
|
198 }
|
|
199 }
|
|
200 }
|
|
201 }
|
|
202
|