1 /*
2  * Hunt - A refined core library for D programming language.
3  *
4  * Copyright (C) 2018-2019 HuntLabs
5  *
6  * Website: https://www.huntlabs.net/
7  *
8  * Licensed under the Apache-2.0 License.
9  *
10  */
11 
12 module hunt.concurrency.CompletableFuture;
13 
14 import hunt.concurrency.Future;
15 import hunt.concurrency.Promise;
16 
17 import hunt.Exceptions;
18 import hunt.Functions;
19 
20 /**
21 * <p>A CompletableFuture that is also a Promise.</p>
22 *
23 * @param <S> the type of the result
24 */
25 class Completable(S) : CompletableFuture!S , Promise!S {
26     override
27     void succeeded(S result) {
28         complete(result);
29     }
30 
31     override
32     void failed(Exception x) {
33         completeExceptionally(x);
34     }
35 
36     string id() {
37         return _id;
38     }
39 
40     void id(string id) { _id = id;}
41 
42     this() {
43         _id = "undefined";
44         super();
45     }
46 
47     private string _id;
48 }
49 
50 
51 
52 /**
53 */
54 class CompletableFuture(T)
55 {
56 
57     /**
58      * If not already completed, sets the value returned by {@link
59      * #get()} and related methods to the given value.
60      *
61      * @param value the result value
62      * @return {@code true} if this invocation caused this CompletableFuture
63      * to transition to a completed state, else {@code false}
64      */
65     bool complete(T value) {
66         completeValue(value);
67         postComplete();
68         return false;
69     }
70 
71     private T result; 
72     private bool m_isDone;
73 
74     this() { }
75 
76     this(T r) {
77         completeValue(r);
78     }
79 
80     //this(Supplier!T supplier)
81     //{
82     //    assert(supplier !is null);
83     //    this.supplier = supplier;
84     //    m_isDone = false;
85     //}
86 
87     bool isDone() {
88         return m_isDone;
89     }
90 
91     T get() {
92         return result;
93     }    
94 
95     void cancel() {
96         if(m_cancelled)
97             return;
98         m_cancelled = true;
99         postComplete();
100     }
101 
102     bool isCancelled() {
103         return m_cancelled;
104     }
105     private bool m_cancelled;
106 
107     bool completeExceptionally(Throwable ex) {
108         if (ex is null) throw new NullPointerException("");
109         // bool triggered = internalComplete(new AltResult(ex));
110         altResult = ex;
111         postComplete();
112         return false;
113     }
114 
115     private Throwable altResult;
116 
117     private void completeValue(T r) {
118         result = r;
119         m_isDone = true;
120     }
121 
122     /**
123     * Pops and tries to trigger all reachable dependents.  Call only
124     * when known to be done.
125     */
126     private void postComplete() {
127         /*
128         * On each step, variable f holds current dependents to pop
129         * and run.  It is extended along only one path at a time,
130         * pushing others to avoid unbounded recursion.
131         */
132         // debug writeln("postComplete in thread ", Thread.getThis().id);
133         // m_isDone = true;
134         foreach(Consumer!T a;  acceptList)
135             a(result);
136     }
137 
138     CompletableFuture!T thenAccept(Consumer!T action) {
139         // CompletableFuture!void d = new CompletableFuture!void();
140         if(m_isDone) {
141             // d.completeValue(result);
142             action(result);
143         } else {
144             acceptList ~= action;
145         }
146 
147         return this;
148     }
149 
150     private Consumer!T[] acceptList;
151     // private CompletableFuture!void[] acceptList;
152 
153   /* ------------- Encoding and decoding outcomes -------------- */
154 
155     // static  class AltResult { // See above
156     //     Throwable ex;        // null only for NIL
157     //     this(Throwable x) { this.ex = x; }
158     // }
159 
160 }