I think this might be the best solution:
+ Routine { embedInStream { |inval| ^func.value(inval) } }
... because what you want here is not to do anything unnecessarily complicated with scheduling the inner routine. What you really what is to evaluate the function of the inner routine, in the context of the outer routine.
I'm not sure if this is exactly the correct handling of the input and return values -- with this, it's the user's responsibility to return (not yield) the proper inval at the end of the inner routine's function. There might not be a better way to do it. But, if you're not using input values, you wouldn't have to worry about it.
hjh
On Oct 19, 2007, at 1:02 AM, Scott Carver wrote: You're right, I didn't reset it in the example code. However, it doesn't fix the problem - the outer routine continues to play while the inner one is paused, waiting for the Condition.
I think I've figured it out, but it's not an ideal solution (it involves a special embedInStream method for Routines that works slightly differently, as well as a slight modification to Condition.wait). Basically, instead of stopping when it hits the first nil value, the modified .embedInStream continues until the Routine is actually finished. Any nil's are yielded all the way down the chain, so an embedded Routine can pause all of it's parents. I have no idea whether the embedInStream modification safe (it might break other things), but I'm going to see how it works. And, it solves my problem - I can now use Conditions in embedded Routines.
A better solution would be if Condition.wait yielded an inf instead of nil - conceptually, this makes more sense (wait forever, rather than stop playback entirely). Nil could then work as it does now, but some clock/scheduling code would have to be changed to treat inf exactly like it would treat nil (i.e. stop scheduling) - currently, yielding inf crashes SC.
- Scott
On Oct 18, 2007, at 11:48 AM, Julian Rohrhuber wrote:
you are embedding streams (Routine) and not patterns, so you'd have to reset the first routine, since you've used it already.
Routine({ "before1".postln; r.reset.embedInStream; "after1".postln; }).play
The following works as expected:
c = Condition(false);
r = Routine({ "before".postln; c.wait; "after".postln; }).play
c.test_(true).signal;
The Routine advances only when the Condition is changed. However, in a situation where the above Routine is embedded in another Routine, it behaves strangely:
c.test_(false); // reset the condition
Routine({ "before1".postln; r.embedInStream; "after1".postln; }).play
c.test_(true).signal;
will yield: before1 before after1
and then, after changing the Condition: after
The outside Routine is continuing on, instead of waiting for the Condition, though the inside routine is still waiting.
So, what am I doing wrong here? Is there another way I can approach this? Help would be much appreciated!
- Scott
|