Merge pull request #506 from andrewcsmith/patch-2
[supercollider.git] / SCClassLibrary / Common / Core / Ref.sc
blob0759074e28843bb61386c4a3e20194401d2b61ea
1 // a Ref is a handle to a value. you can use it to return results by reference
2 // example:
3 //              x = Ref.new(nil);
4 //              z = obj.method(x); // method puts something in reference
5 //              x.value.doSomething; // retrieve value
6 //
7 // it is also used as a quoting device to insulate from multiChannelPerform in UGens
8 //
9 // A special syntax shortcut for Ref.new( expr ) is to use a backquote: `expr
11 Ref : AbstractFunction
13         var <>value;
14         *new { arg thing; ^super.new.value_(thing) }
15         set { arg thing; value = thing }
16         get { ^value }
17         dereference { ^value }
18         asRef { ^this }
19         valueArray { ^value }
20         valueEnvir { ^value }
21         valueArrayEnvir { ^value }
23         // behave like a stream
24         next { ^value }
25 //      embedInStream { arg inval;
26 //              ^this.value.embedInStream(inval)
27 //      }
28         // prevent multichannel expansion in ugens
29         asUGenInput { ^this }
31         printOn { arg stream;
32                 stream << "`(" << value << ")";
33         }
34         storeOn { arg stream;
35                 stream << "`(" <<< value << ")";
36         }
37         at { | key | ^value.at(key) }
38         put  { | key, val | value.put(key, val) }
39         seq { | pat | value = pat.embedInStream(this) }
40         asControlInput { ^value.asControlInput }
42         // Some UGens take Buffer data which
43         // the user might want to specify simply as `[0.9, 0.1, 0.3]
44         asBufWithValues {
45                 ^LocalBuf.newFrom(value);
46         }
48         // Allow to multichannel expand ugen specs, like those of Klank,
49         // in the case of which two is the rank, but could be otherwise.
50         multichannelExpandRef { |rank|
51                 var array, refarray;
52                 array = this.value.asArray;
53                 if(array.maxSizeAtDepth(rank) <= 1) { ^this }; // no need to expand
54                 refarray = array.flopDeep(rank).collect { |item| this.class.new(item) };
55                 ^refarray.unbubble
56         }
59 RefCopy : Ref
61         next { ^value.copy }