cmake build system: visiblity support for clang
[supercollider.git] / SCClassLibrary / Common / Core / Thread.sc
blob2925b53caa714002b85926cb230270be3222b92c
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.
10 Thread : 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;
16         var environment;
17         var <>exceptionHandler;
18         var <executingPath, <oldExecutingPath;
20         *new { arg func, stackSize = (512);
21                 ^super.new.init(func, stackSize)
22         }
23         init { arg argFunc, argStackSize = 512;
24                 _Thread_Init
25                 ^this.primitiveFailed
26         }
27         copy { ^this } // sorry cannot copy
29         clock_ { arg inClock;
30                 clock = inClock;
31                 beats = clock.secs2beats(seconds);
32         }
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         randSeed_ { arg seed;
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.
44                 _Thread_RandSeed
45                 ^this.primitiveFailed;
46         }
47         randData_ { arg data;
48                 _Thread_SetRandData
49                 ^this.primitiveFailed;
50         }
51         randData {
52                 _Thread_GetRandData
53         }
54         failedPrimitiveName { _PrimName }
56         handleError { arg error;
57                 (exceptionHandler ? parent).handleError(error)
58         }
60         // these make Thread act like an Object not like Stream.
61         next { ^this }
62         value { ^this }
63         valueArray { ^this }
65         *primitiveError { _PrimitiveError }
66         *primitiveErrorString { _PrimitiveErrorString; }
68         storeOn { arg stream; stream << "nil"; }
69         archiveAsCompileString { ^true }
70         checkCanArchive { "cannot archive Threads".warn }
73 Routine : Thread {
75         *run { arg func, stackSize, clock, quant;
76                 var routine = super.new(func, stackSize);
77                 ^routine.play(clock ? SystemClock, quant);
78         }
80         // resume, next, value, run are synonyms
81         next { arg inval;
82                 _RoutineResume
83                 ^this.primitiveFailed
84         }
85         value { arg inval;
86                 _RoutineResume
87                 ^this.primitiveFailed
88         }
89         resume { arg inval;
90                 _RoutineResume
91                 ^this.primitiveFailed
92         }
93         run { arg inval;
94                 _RoutineResume
95                 ^this.primitiveFailed
96         }
98         valueArray { arg inval;
99                 ^this.value(inval)
100         }
102         reset {
103                 _RoutineReset
104                 ^this.primitiveFailed
105         }
106                 // the _RoutineStop primitive can't stop the currently running Routine
107                 // but a user should be able to use .stop anywhere
108         stop {
109                 if(this === thisThread) { nil.alwaysYield }
110                         { this.prStop };
111         }
112         prStop {
113                 _RoutineStop
114                 ^this.primitiveFailed
115         }
117         p { ^Prout(func) }
119         storeArgs { ^[func] }
120         storeOn { arg stream;
121                 stream << this.class.name;
122                 this.storeParamsOn(stream);
123                 this.storeModifiersOn(stream);
124         }
126         // PRIVATE
127         awake { arg inBeats, inSeconds, inClock;
128                 var temp = inBeats; // prevent optimization
130                 ^this.next(inBeats)
131         }
132         prStart { arg inval;
133                 func.value(inval);
134                 // if the user's function returns then always yield nil
135                 nil.alwaysYield;
136         }