Pn loop catch
In some cases, when a Pn loops an event pattern that releases itself
(e.g. because of a Pfindur), it is caught in an infinite loop.
// here is an example:
a = Pn(Pfindur(1, Pbind.new).collect {|x| x }, 100000).asStream;
5.do { a.next(Event.default).postln };
a.next(nil); // signal an end of stream.
// this is no problem:
a = Pn(Pfindur(1, Pbind.new), 100000).asStream;
5.do { a.next(Event.default).postln };
a.next(nil); // signal an end of stream.
// as far as I see this always happens when the inner pattern uses
embedInStream instead of asStream (like in a Pcollect).
This could be solved if we decided to find it correct to assume, when
we pass the first value into embedInStream which is not nil, that all
the other values we pass in are also not nil and thus we can force
the halt.
Then this would solve the problem:
embedInStream { arg event;
var hasInval = event.notNil;
repeats.value.do {
event = pattern.embedInStream(event);
if(hasInval and: {event.isNil}) { ^nil.yield };
};
^event;
}
/////////////////////////////////////////////////////////
this could cause surprise in a case like the following:
//////////
a = Pn(Pseq([1, 2, 3])).asStream;
10.do { a.next(4) }; // passing in a value signalizes that Pn always
expects a value.
a.next(nil);
a.next(nil) // stream ends.
//////////
a = Pn(Pseq([1, 2, 3])).asStream;
10.do { a.next };
a.next(nil);
a.next(nil) // stream does not end.
/////////////////////////////////////////////////////////
so actually it would be better to write a Pne to be used explicitly
for EventStreams.
--
--
.