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