Skip to content

Instantly share code, notes, and snippets.

@clinuxrulz
Last active June 16, 2019 10:52
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save clinuxrulz/9f1bf3eafb38085517cb96d67522a84b to your computer and use it in GitHub Desktop.
Save clinuxrulz/9f1bf3eafb38085517cb96d67522a84b to your computer and use it in GitHub Desktop.
Coalesce free Cell::switchC
export class Cell<A> {
.
.
.
static switchC<A>(cca : Cell<Cell<A>>) : Cell<A> {
return Transaction.run(() => {
const za = cca.sampleLazy().map((ba : Cell<A>) => ba.sample()),
out = new StreamWithSend<A>();
let outValue: A = null;
let pumping = false;
const pump = () => {
if (pumping) {
return;
}
pumping = true;
Transaction.currentTransaction.prioritized(out.getVertex__(), () => {
out.send_(outValue);
outValue = null;
pumping = false;
});
};
let last_ca : Cell<A> = null;
const cca_value = Operational.value(cca),
src = new Source(
cca_value.getVertex__(),
() => {
let kill2 : () => void = last_ca === null ? null :
Operational.value(last_ca).listen_(out.getVertex__(),
(a : A) => { outValue = a; pump(); }, false);
const kill1 = cca_value.listen_(out.getVertex__(), (ca : Cell<A>) => {
last_ca = ca;
// Connect before disconnect to avoid memory bounce, when switching to same cell twice.
let nextKill2 = Operational.value(ca).listen_(out.getVertex__(),
(a : A) => {
outValue = a;
pump();
},
false);
if (kill2 !== null)
kill2();
kill2 = nextKill2;
}, false);
return () => { kill1(); kill2(); };
}
);
out.setVertex__(new Vertex("switchC", 0, [src]));
return out.holdLazy(za);
});
}
.
.
.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment