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, >threadPlayer;
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 }
37 threadPlayer { ^threadPlayer ?? { this.findThreadPlayer } }
39 var parent = this.parent;
40 ^if(parent.notNil and: { parent !== thisProcess.mainThread }) {
48 // You supply an integer seed.
49 // This method creates a new state vector and stores it in randData.
50 // A state vector is an Int32Array of three 32 bit words.
51 // SuperCollider uses the taus88 random number generator which has a
52 // period of 2**88, and passes all standard statistical tests.
53 // Normally Threads inherit the randData state vector from the Thread that created it.
55 ^this.primitiveFailed;
59 ^this.primitiveFailed;
64 failedPrimitiveName { _PrimName }
66 handleError { arg error;
67 (exceptionHandler ? parent).handleError(error)
70 // these make Thread act like an Object not like Stream.
75 *primitiveError { _PrimitiveError }
76 *primitiveErrorString { _PrimitiveErrorString; }
78 storeOn { arg stream; stream << "nil"; }
79 archiveAsCompileString { ^true }
80 checkCanArchive { "cannot archive Threads".warn }
85 *run { arg func, stackSize, clock, quant;
86 var routine = super.new(func, stackSize);
87 ^routine.play(clock ? SystemClock, quant);
90 // resume, next, value, run are synonyms
101 ^this.primitiveFailed
105 ^this.primitiveFailed
108 valueArray { arg inval;
114 ^this.primitiveFailed
116 // the _RoutineStop primitive can't stop the currently running Routine
117 // but a user should be able to use .stop anywhere
119 if(this === thisThread) { nil.alwaysYield }
124 ^this.primitiveFailed
129 storeArgs { ^[func] }
130 storeOn { arg stream;
131 stream << this.class.name;
132 this.storeParamsOn(stream);
133 this.storeModifiersOn(stream);
137 awake { arg inBeats, inSeconds, inClock;
138 var temp = inBeats; // prevent optimization
144 // if the user's function returns then always yield nil