How to see when a function has finished/ended?

hello!

In the code below, how do I delay the execution of the routine (2nd line) until all is executed in the function (1st line)? In other words, how do I start ~reward.play when ~forestDepth[0].value(4,16) finished?

(
~forestDepth[0].value(4,16);
~reward.play;
)

I could make a Routine with a wait time in between the two lines, but I guess there is simpler/better way of doing this. I guess I am looking for something similar to s.waitForBoot {


The following didn’t work:

(
~forestDepth[0].value(4,16);
(~forestDepth[0].isClosed).if{~reward.play;}
)

Thank you! k

Mmm, it’s difficult to help without knowing what ~forestDepth[0].value(4,16) does…

1 Like

thanks! yes, there is a t.playNextBar { in it, maybe that is causing the problem…
I’ll try something…

Geoffroy is right. What do you mean with ~forestDepth[0].value(4,16) finished? If that is a Synth that you want to wait to finish, then you can write something to tell you when that Synth is finished and tell the function { ~reward.play } to execute when it finishes. If however it is just a function, then the thread will wait until the function finishes, and there is nothing you have to do.

If ~forestDepth[0].value(4.16) is a routine, then you can put ~reward.play inside a line in the function that is the routine code.

If you are looking for a way to call a function from some place in a routine without including it in the routine’s code, then you might think of adding the function as a dependant to an object and then sending that object the message changed when you want to execute the function. But to know which coding is actually useful in your case, you must explain what forestDepth does or how it is coded.

1 Like

Apologies @Iannis_Zannos, @Geoffroy!

I think the problem was that ~global variable declarations (~hiThetaEnergy, ~timeThreshold) used in the ~reward.play routine were inside the t.playNextBar{ :


~forestDepth[0] = { |bps,bpb|
	t.playNextBar {
		//nf settings:
		~hiThetaEnergy = 10;
		~timeThreshold = 10;
		//forest:
		Ndef(\wind2).play;
		Ndef(\wind2).fadeTime = 6;
		Ndef(\wind2).xset(\amp, 0.1, \lpf, 2500);
		//shaman:
		Ndef(\0).stop;Ndef(\1).stop;Ndef(\2).stop;
		~notes = Array.fill3D(3, bpb, 5, nil);
		t.clear;
	};
};

Moving them outside the t.playNextBar{ makes it work:

~forestDepth[0] = { |bps,bpb|
	//nf settings:
	~hiThetaEnergy = 10;
	~timeThreshold = 10;
	t.playNextBar {
		//forest:
		Ndef(\wind2).play;
		Ndef(\wind2).fadeTime = 6;
		Ndef(\wind2).xset(\amp, 0.1, \lpf, 2500);
		//shaman:
		Ndef(\0).stop;Ndef(\1).stop;Ndef(\2).stop;
		~notes = Array.fill3D(3, bpb, 5, nil);
		t.clear;
	};
};

The routine to clarify it further:

~reward= Routine(
	~timer = [0,0,0,0];
	// 0: elapsed time since routine started
	// 1: total time above ~threshold
	// 2: current time spent above ~threshold
	// 3: how often was ~timeThreshold met
	{inf.do{ |i|
		~timer[0] = ~timer[0]+1;
		(~energyTheta >= ~hiThetaEnergy).if {
			~timer[1] = ~timer[1]+1;
			~timer[2] = ~timer[2]+1;

			(~timer[2]%~timeThreshold == 0).if {
				~timer[3] = ~timer[3]+1
			}
		} {
			~timer[2] = 0; //restart
		};
		~timer.postln;
		1.wait}});

Yes, entirely my fault! Very sorry :blush:


If however it is just a function, then the thread will wait until the function finishes, and there is nothing you have to do.

Thanks - I think I understand now:

t.playNextBar { is pointing to do something outside the function, hence it is later in the thread (or in another thread). Now, executing the following line works:

~forestDepth[0].value(4,16);~reward.play;

cheers! k

You can declare these variables locally inside the routine if needed

1 Like