[chuck-users] sporking member function and static

Spencer Salazar ssalazar at princeton.edu
Tue Jun 20 11:40:20 EDT 2006


Atte,
Even given proper handling of sporked member functions, there is a  
problem with your code below.  Essentially, you are calling a non- 
static member function from a static function, without an instance of  
the class.  Specifically, when you call T.start(), start() "loses"  
its association with T.  Thus, when you call sendQuarter() from  
within start(), even without the spork, youd get a  
NullPointerException, because sendQuarter(), a non-static function is  
being called without an associated instance.  Essentially, within a  
static function, you cant access non-static member variables or  
functions unless they are associated with an explicit instance of the  
class--ie you need InstanceName.start() or InstanceName.data, not  
just start() or data.  An important side-effect of this is that  
Test.start() and T.start() will behave equivalently.

This is one of the more subtle points about static member functions;  
it would probably help to mention this in the docs, and also I think  
it should be a compile error.

But yes, even with that issue resolved, your code wouldnt work  
because of the sporking member functions issue.  Since static member  
functions seem to work with spork, have you considered making all of  
the members of Time static?  Although thats probably undesirable in  
the long run (you couldnt run multiple different tempos within the  
same chuck virtual machine), it should operate well enough if you  
only need a single master tempo.  Would that work until the current  
sporking behavior is cleaned up?

spencer

On Jun 20, 2006, at 4:15 AM, Atte André Jensen wrote:

> Spencer Salazar wrote:
>
>> I know that sporking member functions is on one of the todo lists,  
>> so  its safe to assume that that functionality isnt working  
>> completely at  the moment.  There are plenty of good reasons to  
>> want to spork a non- static member function though, so it should  
>> be on its way.
>
> That's good to know.
>
> What I need is to spork a member function from within another  
> member function. And contrary to what my simple example suggest,  
> there is indeed something fishy here.
>
> At least I can't make my semi complicated example (attached) work.  
> It's supposed to listen for 5 taps on the a midikeyboard, and on  
> the fifth, stop all signalling shreds, update the tempo and restart  
> the signalling shreds.
>
> As the code is attached i get
> [chuck](VM): NullPointerException: shred[id=2:spork~exp], PC=[3]
> If I try to do as the working mini example attached in the first  
> mail (declaring sendQuarter static) chuck seg faults. I hope this  
> works more convincingly in the upcomming release.
>
> -- 
> peace, love & harmony
> Atte
>
> http://www.atte.dk      | quartet:      http://www.anagrammer.dk
> http://www.atte.dk/gps  | compositions: http://www.atte.dk/ 
> compositions
> public class Time
> {
>     60 => float bpm;
>
>     static dur length_quarter;
>     static dur length_eight;
>     static dur length_sixteen;
>
>     1::minute/bpm => length_quarter;
>     length_quarter/2 => length_eight;
>     length_quarter/4 => length_sixteen;
>
>     static Event quarter;
>     static Event eight;
>     static Event sixteen;
>
>     static int ids[10];
>
>     1 => int midi_dev;
>     MidiIn midi_in;
>     MidiMsg midi_msg;
>     36 => int listen_key;
>     if (!midi_in.open(midi_dev)) me.exit();
>
>     Shakers inst => dac;
>
>     fun static void start()
>     {
> 	spork ~ sendQuarter();
>     }
>
>     fun void stop()
>     {
> 	for(0 => int i; i < ids.cap(); i++)
> 	if(ids[i] != 0)
> 	{
> 	    machine.remove(ids[i]);
> 	    0 => ids[i];
> 	}
> 	
>     }
>
>     fun void addId(int id)
>     {
> 	for(0 => int i; i < ids.cap(); i++)
> 	if(ids[i] == 0)
> 	{
> 	    id => ids[i];
> 	    ids.cap() => i;
> 	}
>
>
>     }
>
>     fun void sendQuarter()
>     {
> 	addId(me.id());
> 	while(true){
> 	    inst.noteOn( 0.5 );
> 	    quarter.broadcast();
> 	    length_quarter => now;
> 	}
>     }
>
>     fun void sendEight()
>     {
> 	while(true){
> 	    quarter.broadcast();
> 	    length_eight => now;
> 	}
>     }
>
>     fun void sendSixteen()
>     {
> 	while(true){
> 	    sixteen.broadcast();
> 	    length_sixteen => now;
> 	}
>     }
>
>
>     fun void update_from_quarter(dur quarter)
>     {
> 	quarter => length_quarter;
> 	1::minute/length_quarter => bpm;
> 	length_quarter/2 => length_eight;
> 	length_quarter/4 => length_sixteen;	
>     }
>
>     fun void listen()
>     {
> 	2::second => dur timeout;
> 	now => time first_tap;
> 	now => time latest_tap;
> 	0 => int tap_count;
> 	4 => int nb_taps;
> 	while(true){
> 	    midi_in => now;
> 	    while(midi_in.recv(midi_msg) )
> 	    {
> 		// listen for noteon (144) on listen_key
> 		if(midi_msg.data1 == 144 &&
> 		//midi_msg.data2 == listen_key &&
> 		midi_msg.data3 != 0)
> 		{
> 		    if(now - latest_tap < timeout)
> 		    {
> 			1 +=> tap_count;
> 			if(tap_count == 1)
> 			{
> 			    //now => first_tap;
> 			}
> 			else if(tap_count == nb_taps )
> 			{
> 			    stop();
> 			    update_from_quarter((now - first_tap)/nb_taps);
> 			    start();
> 			    now => first_tap;
> 			    0 => tap_count;
> 			}
> 		    }
> 		    else
> 		    {
> 			now => first_tap;
> 			0 => tap_count;
> 		    }
> 		    now => latest_tap;
> 		}
> 	    }
> 	}
>     }
>
> }
>
>
>
>
>
> Time T;
> T.start();
> //spork ~ T.sendQuarter();
> //spork ~ T.sendEight();
> //spork ~ T.sendSixteen();
> //spork ~ T.listen();
>
>
> //2::second => now;
> //T.stop();
>
> // keep alive
> while(true){
>     100::minute => now;
> }
> _______________________________________________
> chuck-users mailing list
> chuck-users at lists.cs.princeton.edu
> https://lists.cs.princeton.edu/mailman/listinfo/chuck-users



More information about the chuck-users mailing list