HISE Logo Forum
    • Categories
    • Register
    • Login

    Merging scripts

    Scheduled Pinned Locked Moved Scripting
    14 Posts 2 Posters 2.7k Views
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • Christoph HartC
      Christoph Hart
      last edited by Christoph Hart

      Yeah, namespaces are the obvious solution if simple variable renaming doesn't do the job (eg. add a short prefix with an underscore, something like main_volumeSliderand adv_volumeSlider or whatever).

      If you want to merge the code for the callbacks, the best way would be to extract the callback codes into inline functions and call these in the callback:

      namespace FirstScript
      {
          inline function onNoteOnCallback() {};
      };
      
      namespace SecondScript
      {
          inline function onNoteOnCallback() {};
      };
      
      function onNoteOn()
      {
          FirstScript.onNoteOnCallback();
          SecondScript.onNoteOnCallback();
      }
      

      Be aware that the standard var type does not support namespaces, so if you don't use const vars or regs, you'll definitely need to rename your variables.

      BTW, you can select a variable and press Ctrl+D to select the next occurences just like in Sublime Text 3. I added this feature for quick variable renaming:

      alt text

      And you can edit the whole script in a popup editor by right clicking on the script processor header and choose (Open Script in Popup Window).

      1 Reply Last reply Reply Quote 0
      • d.healeyD
        d.healey
        last edited by d.healey

        Thanks Christoph! Yes I'm doing all my main editing in Sublime but I find the built in editor really useful for debugging and the CTRL+D has been very handy.

        I was thinking I could make a "tab" class and for each tab create an object that contains all the script code in inline functions - haven't quite worked out exactly how I'll do this yet - and then call the functions in each callback as you suggested. I'm assuming though that by placing all the code for each tab in an object it will create a fair amount of inefficiency since it has to resolve the object first, is my thinking on this correct?

        Libre Wave - Freedom respecting instruments and effects
        My Patreon - HISE tutorials
        YouTube Channel - Public HISE tutorials

        1 Reply Last reply Reply Quote 0
        • Christoph HartC
          Christoph Hart
          last edited by

          The resolving is not the problem (it's a little bit slower, but shouldn't be the bottleneck here), but you can't use inline functions as member objects. And you really shouldn't use standard functions inside the audio thread.

          I'll see if I can at least use inline functions as variables. Then you can do something like this:

          
          inline function f1()
          {
              Console.print(1);
          };
          
          inline function f2()
          {
              Console.print(2);
          };
          
          const var functionList = [f1, f2];
          
          functionList[0](); // 1
          
          1 Reply Last reply Reply Quote 1
          • d.healeyD
            d.healey
            last edited by

            What about some kind of pre-processor addition that resolves the content of a "pseudo" variable that holds the inline function?

            Libre Wave - Freedom respecting instruments and effects
            My Patreon - HISE tutorials
            YouTube Channel - Public HISE tutorials

            1 Reply Last reply Reply Quote 0
            • Christoph HartC
              Christoph Hart
              last edited by

              Can you give an example how this could be used to solve the problem?

              This would definitely be the most easiest solution and I wanted to add more preprocessor stuff anyway...

              1 Reply Last reply Reply Quote 0
              • d.healeyD
                d.healey
                last edited by

                I was inspired by the way the macro system works with the KSP extended language, basically doing a text substitution at compile time. Since my post I've been playing around with some ideas and actually I don't think such a setup would solve this issue.

                Am I right in thinking that when an inline function is called HISE just replaces the call with the contents of the function and handles all the parameters using external variables? If so would it be possible to have HISE recognize when an inline function is stored in a variable and treat the use of that variable as if it was just a call to the inline function?

                Libre Wave - Freedom respecting instruments and effects
                My Patreon - HISE tutorials
                YouTube Channel - Public HISE tutorials

                1 Reply Last reply Reply Quote 0
                • Christoph HartC
                  Christoph Hart
                  last edited by

                  It's a little more complicated than just a replacement of the function body (because this wouldn't allow return values). Basically its a stripped down version of the standard function call with preallocated parameter slots (currently 5).

                  I'll have to dig around to check how to store inline functions in variables, but it is pretty easy to break stuff there so I have to be careful...

                  1 Reply Last reply Reply Quote 0
                  • d.healeyD
                    d.healey
                    last edited by

                    Cool, I'll play around some more with merging scripts

                    Libre Wave - Freedom respecting instruments and effects
                    My Patreon - HISE tutorials
                    YouTube Channel - Public HISE tutorials

                    1 Reply Last reply Reply Quote 0
                    • Christoph HartC
                      Christoph Hart
                      last edited by

                      Alright, you can now do this:

                      inline function get1() { return 1; };
                      inline function get2() { return 2; };
                      inline function get3() { return 3; };
                      
                      const var obj = {
                        "f1": get1,
                        "f2": get2,
                        "f3": get3
                      };
                      
                      const var array = [get1, get2, get3];
                      
                      // Access via object property
                      for(f in obj) obj[f]();
                      
                      // Access via array
                      for(f in array) f();
                      
                      

                      You still need to define inline functions before you store them into a variable, but now it should work with iterators, arrays etc. Also it is remarkably slower (ca. 30%) than the "native" inline function call (however still faster and more predictable than the standard function call), so I'd advice to just use it when you absolutely need it.

                      1 Reply Last reply Reply Quote 0
                      • d.healeyD
                        d.healey
                        last edited by

                        Great, this will definitely come in handy!

                        Libre Wave - Freedom respecting instruments and effects
                        My Patreon - HISE tutorials
                        YouTube Channel - Public HISE tutorials

                        1 Reply Last reply Reply Quote 0
                        • d.healeyD
                          d.healey
                          last edited by d.healey

                          I found a little issue while merging my scripts, if two GUI controls on different tabs have the same ID they are not namespaced.

                          As I understand it we only need to know the ID of a control when using the JSON notation to set attributes, the rest of the time it doesn't matter what the ID is because we can always use .get("id") on the variable to retrieve it if it's needed. Since I'm creating all of my controls and setting their attributes using helper functions I have no need to know their IDs, so I was thinking is there a way we could call a function to give controls a unique control ID when they are created. Something like this:

                          const var myButton = Content.addButton(Content.getUniqueControlId(), 0, 0);

                          This would guarantee that every control had a unique ID and would prevent collisions when trying to merge multiple scripts.

                          Libre Wave - Freedom respecting instruments and effects
                          My Patreon - HISE tutorials
                          YouTube Channel - Public HISE tutorials

                          1 Reply Last reply Reply Quote 0
                          • Christoph HartC
                            Christoph Hart
                            last edited by

                            The IDs are also used to store data and resolve the widgets on countless situations so it's pretty mandatory to have them unique.

                            You could write your random ID generating function directly in Javascript:

                            inline function createUniqueString()
                            {
                            	local s = String.fromCharCode(Math.randInt(65, 90));
                            	s += String.fromCharCode(Math.randInt(97, 122));
                            	s += String.fromCharCode(Math.randInt(97, 122));
                            	s += String.fromCharCode(Math.randInt(97, 122));
                            	s += String.fromCharCode(Math.randInt(97, 122));
                            	s += String.fromCharCode(Math.randInt(97, 122));
                            	s += String.fromCharCode(Math.randInt(97, 122));
                            	s += String.fromCharCode(Math.randInt(97, 122));
                            	
                            	return s;
                            }
                            

                            Although it assigns different IDs to the widget each time the script is compiled, and this prevents the widget values to be persistent (the IDs are also used to store the values in the preset).

                            What you need to do is to generate a deterministic string in your UI factory class. The most simple example would be a internal counter in your UIFactory that appends the number to the ID:

                            namespace UIFactory
                            {
                            	reg _counter = 1;
                            	
                            	inline function createKnob(x, y)
                            	{
                            		local knob = Content.addKnob("Knob" + _counter++, x, y);
                            		
                            		return knob;
                            	};
                            };
                            
                            const var k1 = UIFactory.createKnob(0, 0);
                            const var k2 = UIFactory.createKnob(130, 0);
                            
                            1 Reply Last reply Reply Quote 1
                            • d.healeyD
                              d.healey
                              last edited by

                              Oh now why didn't I think of that! That's the perfect solution, thanks again!

                              Libre Wave - Freedom respecting instruments and effects
                              My Patreon - HISE tutorials
                              YouTube Channel - Public HISE tutorials

                              1 Reply Last reply Reply Quote 0
                              • First post
                                Last post

                              26

                              Online

                              1.8k

                              Users

                              12.0k

                              Topics

                              104.5k

                              Posts