TaskとRoutine
.wait
を使って時間を制御したい場合、TaskやRoutineを使う。Taskの特徴は一時停止・再開できること。一方Routineの特徴は、一時停止・再開は出来ないが.yield
が使えることである。ということで、Task・Routineで使えそうに見えるメッセージについて比較した。
TaskとRoutineの比較
メッセージ\ | Task | Routine |
---|---|---|
.play | 使える | 使える |
.start | 使える | ERROR |
.resume | 使える | .nextと同じ |
.pause | 使える(.stopと同じ) | ERROR |
.stop | 使える(.pauseと同じ) | 使える |
.reset | 使える | 使える |
.next | nil | 使える |
.value | nil | .nextと同じ |
TaskとRoutineの使い分け
Task | SuperCollider 3.9dev Helpによると、
Tasks are not 100% interchangeable with Routines. Condition does not work properly inside of a Task. Stopping a task and restarting it quickly may yield surprising results (see example below), but this is necessary to prevent tasks from becoming unstable if they are started and/or stopped in rapid succession.
また
As a result, Task should be used for processes that need to start and stop relatively infrequently, but for which maximum stability is required. If you need fine-grained control over when and how the process stops and resumes (as is the case, for instance, with condition), Routine is preferred.
とある。内部でコンディションを持つならRoutineがおすすめ、ということだと思われる。
ところでforkは?
forkは
Returns a Routine using the receiver as it's function, and plays it in a TempoClock.
である。and plays it in a TempoClockがポイントで、forkは実行すると即座にplayされてしまう、すなわちあとから実行・途中で止めることが出来ない。
コード確認
//Task ( t = Task({ inf.do({|i| ("Task" + i).postln; 1.wait; }); }); ) //Routine ( r = Routine({ inf.do({|i| ("Routine" + i).postln; 1.wait; }); }); ) //Task t.play; t.start; t.resume; t.pause; t.stop; t.reset; t.next;//nil t.value;//nil //Routine r.play; r.start;//ERROR: Message 'start' not understood. r.resume; r.pause;//ERROR: Message 'pause' not understood. r.stop; r.reset; r.next; r.value; //fork /* Returns a Routine using the receiver as it's function, and plays it in a TempoClock. */ ( f = fork({ inf.do({|i| ("fork" + i).postln; 1.wait; }); }); )
参考
Task | SuperCollider 3.9dev Help