1open Wonka_types;
2
3let talkbackPlaceholder = (._: talkbackT) => ();
4
5let captureTalkback = (
6 source: sourceT('a),
7 sinkWithTalkback: (.signalT('a), (.talkbackT) => unit) => unit
8) => {
9 let talkback = ref(talkbackPlaceholder);
10
11 source((.signal) => {
12 switch (signal) {
13 | Start(x) => talkback := x
14 | _ => ()
15 };
16
17 sinkWithTalkback(.signal, talkback^)
18 });
19};
20
21type trampolineT = {
22 mutable exhausted: bool,
23 mutable inLoop: bool,
24 mutable gotSignal: bool
25};
26
27let makeTrampoline = (sink: sinkT('a), f: (.unit) => option('a)) => {
28 let state: trampolineT = {
29 exhausted: false,
30 inLoop: false,
31 gotSignal: false
32 };
33
34 let loop = () => {
35 let rec explode = () =>
36 switch (f(.)) {
37 | Some(x) => {
38 state.gotSignal = false;
39 sink(.Push(x));
40 if (state.gotSignal) explode();
41 }
42 | None => {
43 state.exhausted = true;
44 sink(.End)
45 }
46 };
47
48 state.inLoop = true;
49 explode();
50 state.inLoop = false;
51 };
52
53 sink(.Start((.signal) => {
54 switch (signal, state.exhausted) {
55 | (Pull, false) => {
56 state.gotSignal = true;
57 if (!state.inLoop) loop();
58 }
59 | _ => ()
60 }
61 }));
62};