Broadcasters best practices
-
Just to sorta blunder in and ask possibly a stupid question... namespaces are just containers for related functions and variables right? You can't actually instance a namespace IE: use it as a kind of class ?
-
-
Right I see. So an Object Factory is what I would want if I wanted to create a class.
-
@Orvillain not really. A object factory creates a data structure with a densely packed memory layout that can be used for a neat implementation of MIDI logic, but it lacks most of the features that you would expect from a object-oriented class object (like methods or polymorphism).
What are you trying to achieve?
-
@Christoph-Hart said in Broadcasters best practices:
@Orvillain not really. A object factory creates a data structure with a densely packed memory layout that can be used for a neat implementation of MIDI logic, but it lacks most of the features that you would expect from a object-oriented class object (like methods or polymorphism).
What are you trying to achieve?
I'm mainly pondering what would be the cleanest way to create an object prototype and then instantiate however many of them I'd like - and each instance automatically creates the relevant DSP nodes, UI widgets, and various methods and callbacks required.
In Python you'd do something like:
class WhateverTheClassIsCalled(inheritance here) def __init__(self, and then any initialisation arguments here) self.blah = blah def do_a_thing(self, blahblahblah) thing_is_done = blahblahblah(bloo bloo bloo) return thing_is_done for i in range(0, 32): instance_var = WhateverTheClassIsCalled(blahblahblah, bloloooooloooo)
That sort of thing. In Python it is fairly trivial to put together a class this way, and tbh, syntax aside it looks like the Factory Object approach might do the same sort of thing???
BTW - the above is probably the best code I've ever written. :face_with_tears_of_joy:
-
@Orvillain One cool thing about namespaces is that each comes with 32 high-speed reg variables.
-
You can do this kind of simple object oriented stuff by creating a JSON object and attaching functions as member, which will then access the JSON properties through the
this.property
syntax:// This as close as you'll get to object oriented programming in HISE Script function createInstance(valueToUse) { var prototype = { create: function() { // Access properties of the "class" object with this Console.print(this.value); }, value: valueToUse // store the "constructor argument" as "class member" }; return prototype; } // And now let's add polymorphism: function createSubClassInstance(valueToUse) { var prototype = createInstance(valueToUse); prototype.create = function() { Console.print(this.value + ": SUBCLASS"); }; return prototype; } // Create two instances of the "class" var x1 = createInstance(90); var x2 = createInstance(120); var x3 = createSubClassInstance(500); // call the method of each instance x1.create(); x2.create(); x3.create();
-
@Christoph-Hart said in Broadcasters best practices:
You can do this kind of simple object oriented stuff by creating a JSON object and attaching functions as member, which will then access the JSON properties through the
this.property
syntax:// This as close as you'll get to object oriented programming in HISE Script function createInstance(valueToUse) { var prototype = { create: function() { // Access properties of the "class" object with this Console.print(this.value); }, value: valueToUse // store the "constructor argument" as "class member" }; return prototype; } // And now let's add polymorphism: function createSubClassInstance(valueToUse) { var prototype = createInstance(valueToUse); prototype.create = function() { Console.print(this.value + ": SUBCLASS"); }; return prototype; } // Create two instances of the "class" var x1 = createInstance(90); var x2 = createInstance(120); var x3 = createSubClassInstance(500); // call the method of each instance x1.create(); x2.create(); x3.create();
Ahhhhhh, yes I think I get that. I will give it a try! Thank you!
-
@Christoph-Hart Nice, that's the kind of thing I was thinking of
-
-
I just tried using the broadcaster wizard for the first time. I selected
ComponentVisibility
in the second screen, this is what it gave meconst var showAboutBroadcaster = Engine.createBroadcaster({ "id": "showAboutBroadcaster", "args": ["component", "isVisible"], "tags": [] }); // attach to event Type showAboutBroadcaster.attachToComponentProperties(["pnlAboutContainer"], "Temp"); // attach first listener showAboutBroadcaster.addComponentPropertyListener(["pnlAboutContainer"], ["visible"], "temp", function(index, component, isVisible){ return isVisible; });
This gives an error
argument amount mismatch: 2, Expected: 3
I changed it to
attachToComponentVisibility
and the issue is resolved. -
@Christoph-Hart said in Broadcasters best practices:
You can do this kind of simple object oriented stuff by creating a JSON object and attaching functions as member, which will then access the JSON properties through the
this.property
syntax:// This as close as you'll get to object oriented programming in HISE Script function createInstance(valueToUse) { var prototype = { create: function() { // Access properties of the "class" object with this Console.print(this.value); }, value: valueToUse // store the "constructor argument" as "class member" }; return prototype; } // And now let's add polymorphism: function createSubClassInstance(valueToUse) { var prototype = createInstance(valueToUse); prototype.create = function() { Console.print(this.value + ": SUBCLASS"); }; return prototype; } // Create two instances of the "class" var x1 = createInstance(90); var x2 = createInstance(120); var x3 = createSubClassInstance(500); // call the method of each instance x1.create(); x2.create(); x3.create();
So just looking at this. I think I get it, and I can see how this would help me. For example here is what I have so far:
function Sampler(id) { var sampler = { connectComponents: function() { this.pad = Content.getComponent("panel_" + this.id); this.sampler = Synth.getChildSynth("sampler_" + this.id); this.processor = Synth.getAudioSampleProcessor("sampler_" + this.id); this.sequencer = undefined; }, populateLayers: function() { for (i = 0; i < layer_count; i++) { this.layers[i] = { 'audiofile': this.processor.getAudioFile(i), 'ui_parameters': {}, 'loop_panel': Content.getComponent("loopdragger_" + this.id), 'waveform_panel': Content.getComponent("waveform_" + this.id), }; } }, connectCallbacks: function() { this.pad.setFileDropCallback("Drop Only", "*.wav", load_sample); }, id: id, layers: {}, }; return sampler; }
It'll get more interesting when I actually write a function to check if a component exists, and if it doesn't, create it.
-
@d-healey said in Broadcasters best practices:
I just tried using the broadcaster wizard for the first time. I selected
ComponentVisibility
in the second screen, this is what it gave meconst var showAboutBroadcaster = Engine.createBroadcaster({ "id": "showAboutBroadcaster", "args": ["component", "isVisible"], "tags": [] }); // attach to event Type showAboutBroadcaster.attachToComponentProperties(["pnlAboutContainer"], "Temp"); // attach first listener showAboutBroadcaster.addComponentPropertyListener(["pnlAboutContainer"], ["visible"], "temp", function(index, component, isVisible){ return isVisible; });
This gives an error
argument amount mismatch: 2, Expected: 3
I changed it to
attachToComponentVisibility
and the issue is resolved.Any ideas about this one Christoph? Is it a bug or did I use the wrong settings in the wizard?
-
@d-healey your function prototype is correct, now just make the arguments for the broadcaster match, i. e. add index to the args
-
@aaronventure This is auto-generated by the broadcaster wizard - and it doesn't work, therefore I think it's a bug. It should be using attachToComponentVisibility, but it isn't.
-
@d-healey ah gotcha
-
-
This is confusing
I had no idea what was wanted here, but it's a string (must have quotes)
I tried to add multiple events to the EQ broadcaster and the output was
"BandAdded, BandRemoved, BandSelected"
which doesn't work. It should be["BandAdded", "BandRemoved", "BandSelected"]
-
@d-healey said in Broadcasters best practices:
I had no idea what was wanted here, but it's a string (must have quotes)
You can pass any object into the addCallback() function which will be assigned as this object in the executed function:
const var list = [1, 2, 3]; bc.addCallback(list, "something", function() { for(n in this) Console.print(n); // 1, 2, 3 });
In this case you would just enter
list
into the This Object field.The other issues you mentioned are fixed now.
-
@Christoph-Hart Ah ok that makes sense, thanks
-
@d-healey said in Broadcasters best practices:
@Christoph-Hart Ah ok that makes sense, thanks
does this mean you are investigating Broadcasters with a view to doing a video on it? (fingers crossed here...)
-
@Lindon I've been using them since they were a thing. I'll make a broadcaster video for this weekend