1 // you must not make any change at all to the order or number of
2 // instance variables in these classes!
3 // You should also not muck with the contents of the instance
4 // variables unless you are sure you know what you are doing.
5 // You may add methods.
7 // Thread inherits from Stream for the benefit of its subclass Routine which can
8 // behave like a Stream. Thread itself is not used like a Stream.
11 var <state=0, func, stack, method, block, frame, ip=0, sp=0;
12 var numpop=0, receiver, numArgsPushed=0;
13 var parent, terminalValue;
14 var <primitiveError=0, <primitiveIndex=0, randData=0;
15 var <beats=0.0, <seconds=0.0, <clock, <nextBeat, <>endBeat, <>endValue;
17 var <>exceptionHandler;
18 var <executingPath, <oldExecutingPath;
20 *new { arg func, stackSize = (512);
21 ^super.new.init(func, stackSize)
23 init { arg argFunc, argStackSize = 512;
27 copy { ^this } // sorry cannot copy
31 beats = clock.secs2beats(seconds);
33 seconds_ { arg inSeconds; seconds = inSeconds; beats = clock.secs2beats(inSeconds); }
34 beats_ { arg inBeats; beats = inBeats; seconds = clock.beats2secs(inBeats); }
35 isPlaying { ^state == 5 }
38 // You supply an integer seed.
39 // This method creates a new state vector and stores it in randData.
40 // A state vector is an Int32Array of three 32 bit words.
41 // SuperCollider uses the taus88 random number generator which has a
42 // period of 2**88, and passes all standard statistical tests.
43 // Normally Threads inherit the randData state vector from the Thread that created it.
45 ^this.primitiveFailed;
49 ^this.primitiveFailed;
54 failedPrimitiveName { _PrimName }
56 handleError { arg error;
57 (exceptionHandler ? parent).handleError(error)
60 // these make Thread act like an Object not like Stream.
65 *primitiveError { _PrimitiveError }
66 *primitiveErrorString { _PrimitiveErrorString; }
68 storeOn { arg stream; stream << "nil"; }
69 archiveAsCompileString { ^true }
70 checkCanArchive { "cannot archive Threads".warn }
75 *run { arg func, stackSize, clock, quant;
76 var routine = super.new(func, stackSize);
77 ^routine.play(clock ? SystemClock, quant);
80 // resume, next, value, run are synonyms
98 valueArray { arg inval;
104 ^this.primitiveFailed
106 // the _RoutineStop primitive can't stop the currently running Routine
107 // but a user should be able to use .stop anywhere
109 if(this === thisThread) { nil.alwaysYield }
114 ^this.primitiveFailed
119 storeArgs { ^[func] }
120 storeOn { arg stream;
121 stream << this.class.name;
122 this.storeParamsOn(stream);
123 this.storeModifiersOn(stream);
127 awake { arg inBeats, inSeconds, inClock;
128 var temp = inBeats; // prevent optimization
134 // if the user's function returns then always yield nil