Frage

I've been following this snake example and decided to modify it to generate new apples only in empty (i.e. non-snake) cells. However, that's introduced a cyclic dependency between Observables, since generating new apples now depends not only on the last position but on the whole snake:

// stream of last `length` positions -- snake cells
var currentSnake = currentPosition.slidingWindowBy(length);

// stream of apple positions
var apples = appleStream(currentSnake);

// length of snake
var length = apples.scan(1, function(l) { return l + 1; });

Is there a nice way to resolve the cycle?

I can imagine how this would work in a messy state machine but not with clean FRP.

The closest I can think of is coalescing apples and length into one stream and making that stream generate its own "currentSnake" from currentPosition.

applesAndLength --> currentPosition
         ^          ^
         |         /
        currentSnake

I haven't thought about the implementation much, though.

War es hilfreich?

Lösung

Once it has been constructed, Bacon can usually handle a cyclic dependency between Observables. It is constructing them that's a bit tricky.

In a language like Javascript, to create a structure with a cycle in it (i.e. a doubly-linked list), you need a mutable variable. For regular objects you use a regular variable or field to do that, e.g.

var tail = { prev: null, next: null };
var head = { prev: null, next: tail };
tail.prev = head; // mutating 'tail' here!

In Bacon, we operate on Observables instead of variables and objects, so we need some kind of a mutable observable to reach the same ends. Thankfully, Bacon.Bus is just the kind of observable we need:

var apples = new Bacon.Bus(); // plugged in later
var length = apples.scan(1, function(l) { return l + 1; });
var currentSnake = currentPosition.slidingWindowBy(length);
apples.plug(appleStream(currentSnake)); // mutating 'apples' here!

In my experience, it is preferrable to cut the cycles at EventStreams instead of Properties, because initial values tend to get lost otherwise; thus the reordering of apples and length.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top