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.
    • d.healeyD
      d.healey
      last edited by

      Got any tips on merging several UI scripts into one without variable names clashing? I'm thinking namespaces might play a role and includes but haven't yet worked out the best way to combine them when some variable names will be the same and they are all making use of the same basic callbacks.

      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 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

                                23

                                Online

                                1.8k

                                Users

                                12.0k

                                Topics

                                104.5k

                                Posts