Passing "...args" to a play function in an event?

Hopefully this is a simple question:

I have an event that I’m trying to set up that allows a custom function to be run with some common wrapper code. The expectation is that the customFunction will be copied and overwritten by a number of classes, but the play function will remain the same and contain all of the necessary plumbing, event sending and teardown, so the custom function can focus solely on the logic.

Boilerplate, it looks like this:

(
~customEvent = (
    customFunction: #{
        arg ...args;
        ("CUSTOM FUNCTION: " + args).postln;
        true;
    },
    play: #{
        arg ...args;
        ("PLAY" + args).postln;
        // Setup
        // Run Common Code
        ~customFunction.value(args);
        // Run Common Code
        // Cleanup
        true;
    });
)

I’ve noticed that I can call code like ~customEvent.customFunction(1,2,3,4) and it appropriately internalizes the values passed to it, but when I do the same for the play function, the “…args” value is empty.

From reading the docs, I see that the play function is special, but what I can’t seem to find is how to pass arguments to it, and especially how to pass the catchall ellipsis to it.

Is there a way to do this, and if so, how ? If not, how should I be thinking about this ??

thanks!
John

Unfortunately, I think you’ll have to pick a name other than play.

A pseudo-method defined in an event can’t override any real methods with the same name. So, it’s calling Event:play. It happens that this method calls your play function, but with its own argument values, not yours.

(This is a weakness off “fake method” dispatching in SC. There was a long conversation about it a couple months ago, with the upshot that allowing this sort of per-object override would be very slow.)

hjh

@jamshark70 - Bummer. That being said, it looks like in the documentation that there is an event with an argument defined. e.g.:

(freq: 800).play;
(play: {  "I rather do something else: ".post; ~x.postln; }, x: 800.rand).play;

Even if I can’t specify a catch-all, if there is a way to introspect to see what’s been passed, that should be good enough for my purposes. Does that exist ?

Edit: I think I’m reading that wrong - x: in the second one is a variable in the event, not a variable passed to the event. I’ll keep digging.

Just checked – nothing is passed in.

So I guess you’ll have to go with th environment variables.

hjh

Hrm. That’s strange.
Should I understand it to mean that any variable used in a play function (e.g. via the tilde notation) has been passed in by the “:” parameters ?

The intended usage was to put all the required information into the event, and then play it. (Normally, it’s a Pbind that produces an event, and an EventStreamPlayer plays the event – since the play itself isn’t under the user’s control, there hasn’t been much need for args to be passed in. Maybe it would be better to add that.)

Every name: value in the event will be available as a ~name variable in the play function (because of the use in line 73.

hjh

I think I see what the intent was. I guess I figured there would be some sort of class hierarchy and a locally defined play event could do whatever it wanted, but would be tied to the functionality of the parent, ultimately triggering some sort of event.

Thanks for the clarification, I’ll read some more code and see what I can do to get this working. It may make sense for my play function to do something like:

play: #{ 
  ~setup()
  ~customfunction()
  ~teardown()

I’m sure it’ll make sense once I get my head around it - it’s just behaving a bit differently from what I expected.

To close the loop here - it looks like the “currentEnvironment” variable contains the values needed to do what I want to do. In case anyone else runs across the same problem.