HISE Logo Forum
    • Categories
    • Register
    • Login

    Variable Persistence

    Scheduled Pinned Locked Moved Scripting
    29 Posts 4 Posters 5.5k 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

      I know that the current way to save data with a preset is to use a sliderpack, however I want to save data for a 2D array and it seems I would need to create a sliderpack for each sub-array, is there a more efficient way of doing this?

      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

        You can use any widget to store persistent data (the slider pack is just handy because you can easily view its content) and you can store any variable using Widget.setValue(), so a multi dimension array is a valid widget value.

        Check out this patch:

        HiseSnippet 979.3ocwV88aaaCDlxwBaVaFXsnuz2HxKyFKS0NMsKEECqIoMCdcNwnJva.FFELTTwDglzfjxtdE8+49ev1QIYK4E2s58xDDfLuev6693cG8.shxLFkF48UWsbFC4809QKk1ImMgvknduD48M9CXZC2XYR6ULiEc5xYDigEi7716mcV40nNJ64i+zoDAQRYkhPngJNk8q7obaozAu30bg3bRL6J9zJVezK5QUxyTBUJfn876flQn2RtgcAwYVMezbNagA40w+wGFpus60+wIgvyku4je6niOjEFl75vPxsGx9NPdBU2OZ46N+zvPDMUqgDXH3Nxy26OgGO+WEysJcjkXYvd5epJdYzD0BYdnGxM7qEL2htnH.S4hOWIhcIuSZOokoSHTVE2PmMgKhGrhXMHjW8Akz7d4z7C76yi4qkWktcJvkdTkt8psIjquAj69uC4sBOuJvqdN7tmeDUymYK03v18Kj9IPWtRTs2WyO.NFMV7bhFOfHYB7OhOSIckPgj33LQs1O6y9Gf6.usedP1xPCy1Z+444AnKgHLr1OuYPyfG8H7US3FrfKYX3Ke5Lk1Rj1CvWynjTCH0hWnjeqEDfmstpEqrSX5EbCqY0fXHyY8jCzLXEDIqNsHPMCxZABMVh15JP0s5D9DmtjTI0xURrRdgxxtT1pcv6aFz.fVDraFb+durGdJPMPMKNlXIXtzpvP7w1EJbLrYRCrADAln0jkAMVCngDQJq0nQ8y8N7Fl0EiKRmdM.f1.GM9.HTtmQ.iUwrgLghxsKa0d7XfG+vcfYRhCmAM1Tk6.QqDB2teWs4485zKi4MSTohX7LMjTXRUFdtC73V7D7RUJX..N3.e5LtH6PovQoJ6jIiwsr31AM.LXTBVX1V1JmKtYEWzdTmwv6eOkJvcKYFybPdrWkAPQ9lsHAedsHqNPubFqvv0b2JQNiJ4rpRy3psXVoHZdwekwDJYOI2VFt61WhJ5XbcnEaHXpMq+r4p9SGig3P62W3m+6L1.48P+eI5xKFM53mkU3fckLc6bz3wvv26zsCybTwoBhcyAQtg6EJ.leiVc2fOnP1tr5v+cX5TmOw.0svBelv8d9C3V5jsi2Z++f2hY8M8eURBiZKAac+y+8+qC12An7FUpkKuoOwp4uCtfClkDA2rRY.RjPwh6ROuZtJs70cbqcbSDSF2Y08jEJ65V6Unr6JknoDpV8VZd8o61juLSBfIY1c1M766Vi6tpxzg6ovUbukRcDw2CHe6db3N6wi2YONZm83I6rGOcm83G1YON9evC2+m3jTqZZdaAB8W.+BpyU.
        
        
        1 Reply Last reply Reply Quote 0
        • d.healeyD
          d.healey
          last edited by

          Cool, that's a very clever way of handling it!

          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'm struggling to get this to work with a more complicated example. Here I'm using a slider pack to update an array, the array is then saved whole into a hidden panel. When the project is compiled it should load the saved panel data back into the array to be displayed by the slider pack but this isn't happening. I'm also experiencing a weird graphical glitch (in image below) moving one of the sliders fixes it until the next time I hit compile - this is the latest build.

            0_1476630509232_Capture.JPG

            Here's the HISE snippet (wasn't sure which tags to use to post this).
            HiseSnippet 1215.3ocuV8uSabDDdOfSs1stpopO.a8ecnbE7wOBzPQM.Iz51.XUGghDBktb2d3U47tV6sFhIh2o9n02f1Y18N7YiCItRsVfg8al41u8al41oiVEyyyUZh2W7pQC3Duuzu6Hoo2A8XBIo8yIdek+QrbCWScP6OZ.KOmmP77V7mQ.uZKQre9qeZeVFSFyGCQHmpDw7WJ5KLiQ+im8ahrrCYI7WI5Ww6MdV6Xk7.UlZHvmE8aQFvheK6R9wLzsE7IWI3WmS7Z4u9ZqneazE2r2JS8oqZqa1VivVScreShGp0bo4THbhmu2eCe77eQhvnzcMLCGdl96qRF0sm5ZoaqOUjKtHiiKhHcAN4faKAoHkEyq35gprDTPPOIGzSjkzoTVyIDuk5LVjWzIxeq+QhDwc3iE6u1ZfNNhpxs2BSR4klfxQeHJOldslE87pPukbz6Q9ci0hAlwVPt8MEne.14LRVP66pfVgkj7J0gZkzDXzC4KuSi5G.Kf7vJ4byuvEW1yDDsYKzPi5Wwzz9i1SqYin6RO6b.rX4YsNGQhBoqERWOjtQHcyP5SBoaER2Nj9CgznVUcOZ9bes4y80mO22nz8VfkJeO8OmaEAn7O2PQoX.SxyfPKULPL6fPAMsVZ5hBkN6ZTQCZdkq..Llxxx4SYMmcEusrilCq.WJyIMpu5psSoldbMmJxoC35bQNtozDlgQERzVAgf+SRyTrDpv.VLJqMFdTaTWjRC9t.2NdI2bJKaHOX4Ux3xKM8n6t6tzgxDdpPxSVd4F0eei50RUZZ.ddEvYs0Nve9wxpfh3.rG+Xv6Zn60JkUAJqSuS.JbdpcK7KHa4pL9JCz.ICZ5JqdIvadRS7Peq6b2MSj.uYqC7ZFJbVRD4Cx.GsmaUJcbRrZpwZchLi6wfOkfln0JYmUWkd1u18jisQc9Dc.PaDn0FAOGZR5iNcWzvYkRadsHwzq4SoaE0JzBzy1y.HQqWfLQN8ozRTKe1quZnz58ZEvF9ftha3.TynlfHTRvUqxPD54EBwUnvlSSA9UQLvRB2VfuetQ8GHIBdOUdDSi3NgJfS21yzFJKdWfHrRTPtzlmRGJiMBkjpjGqL7SjAKW+80qU+15SaIMcVlP8Vqxx35YYEu+Q+.gEHG1+BtNzIDErGKyc3PMsU0tW4IvemGXYpM1cnP0F23ZUn7LderACp4tTbEzRY8AeB20u5poKdfKaCGx0EwCI.qitp8ag2sO4MC0+ztYnTSOY.uvw6zxRHzowZXUTq1MC2FCE6p0qbSoR1VJLi2t6ecDonAAuXp3ABtZrWK0n7ZI7nSDvsNeluUFHV4i38m9Xg7Yej2NGR++vgM93ux+bB4928BS.nRFlwLSNV.NpUgAnBchKdwQRj4BynpihMGyJzZlyJLyjymHcejeGgIt2r46ByfuP19+Z9VL4UC+WjlxiMiI6R9G95+siYMGT42UCMB4kGwLZw6fwMOdX+tvbtwbfIRnFFGA0aArAvstEtFUltbYRqxoVKLFgq8JLFUZjzmEqUuI101fy184VDfSR6Dz0fQ4g0znxFFj28gANeSbLJDeOv7YGwZycDqO2QrwbGwlycDOYtiXq4NhsefHvo62anQ020VPH+CPwQ3Z8

            Would it be a difficult thing to add persistence to variables and arrays? perhaps through the use of a couple of functions to enable persistence and to read persistent data? Or what about a dedicated persistence object that we can add to and read from, something like this persistenceObject.myData1 = "Hello"; persistenceObject.myData2 = "world"; persistenceObject.myData3 = []; persistenceObject.myData3 = 123;

            My concern is that with one or two persistent variables adding a panel to hold their data isn't a big deal but on a large project with 10 or more variables that need to be persistent there is going to be a lot of extra code to hold the data, manage it, read it back in to arrays or objects etc. It feels a bit hacky to me using GUI elements to store data.

            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

              Wow, this is a really strange bug - I can reproduce the glitch, but it seems that it only occurs with a rare combination of conditions, so thanks for spotting this.

              However I'd like to stick with the hidden Panel approach - although it feels a bit hacky, it makes the preset structure much more clearer (also User presets are stored by saving only interface values). On a larger scale it does not seem so wrong (your array is connected to interface data somehow so it makes sense to store it on this level).

              The approach of having a dedicated persistent object is not far from the current solution. You can store a JSON object into one Panel which can hold every data you need to be persistent (so if you have 10 variables you definitely don't need 10 hidden Panels).

              PS: The best way to insert HISE snippets would be using a Github-Style Fenced Code Block.

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

                Alright, the GUI glitch is still there, but this snippet has the correct functionality:

                HiseSnippet 1387.3ocuW0uaaaCDmJMBc1adXcXO.b9elRqmhURZSW6BVyGMqdqM0XNHXCAAMLRTwbUlzPhJotE4cZOZ6MX6NRIK4D2t5ArYDmDdeP9i+t6HO1OUExyxToDmO8vIi4DmOycvDod3tCYBIo2dDmO28ErLMOkZEsyjwrrLdDww4V+HJvowxDym+7G1gkvjg7JQDxQJQH+4hQBckzSexOKRR1mEwOTLpl0a7jdgJ4tpDUNfma41kLlE9Z147CXnYK4RtPvuLi3z0c807SecvYucae3yF60e8r9ax886+Le+Cx24x6Yja+riuOILOMkK0GAtSbbc9K3ii6SiDZU5.MSyg4zcGUzjACUWJsK8QhLwYIbbP.Y.fIq3dRfJhYg7ZltuJIBIDzRxtCEIQ8Ko0LBwY49Uj7srj7W49BQjXp7Jx9KLJnUdTmtcVZVHu7LPN38A4J30cdvyoF7V1Bu63NHLULVWoAw1WVH88fNqRxR921lA4yhhNTsepRp8zo47Udbql6BCf3feFW+Lt37gZuf62EUzp4ErT5nIamlxlP2hd7IfvhgG28DTRPG5Zcnq2gtQG586PePG5lcnOrC865PC5V27fEy70VLyWewLeiRy6BZp86q+yIFR.R+yzTjJFyj7Dv0RFCHy9nHu1FMssdgTmYLxndsuvl..JiYIY7qoMicAumreJGFAlTFSZ0b06R2SI+FMUHEZpdHmxLggg7TtQ+p8hQwobpHiNlmlIxPPQiXZF3jwEKfg+SRSTrHp.mNspZ5Z0TDS89ZOKhNmqOhkjy8VwOgKOWOjt0VaQykQ7XgjGsxJsZ9tVMaDqRodHeH.tn6ig+78kYIE9Axt28.qafl2nj1EHse8UBjB62FWAeAZMSkv8GmBfzqsMs64.t4QsQR4Jbee2Us69AIhH37u9vgQTXGEIxFm.la18pXZUntd.zncl3mcZvYwqMpsVLb0UoG+SCd4AFuNYl5DnXCXbsfmAkRiPil5Mrioz1WJhzCa+H5lAc6XDLzTYARBVuPxLQ9GQKkZvy1iT4Ri0qUHVyGOP7VNHpcPafJJA3p0QHl0Tl1DgQYHynJeYuBJ5Bj3ynw.xqQSXJicwwy2a07CDjAquVbFCyHFPtwxnaq6AoMuwSzolWPrtVbLNWFpEJIUIOPo4uT5sRy20rQyqZdcMwwySEFORUII7z4oEuEK8C3lmLezY7zNV5nXO.L5gPogIM4R35P5YbJDffi24Qk0TSmAZHKI4LCYgN964PRlwTJiFpFOASCsEgovUk3k0vLTPFfKXgmECPUlsr35UL.yaPGVfz.+BKSYTrp71FOQ0KTLqgcoVf3VCSUZCaw5M1A37LcC..c1s9oFTdJRALZUQ2TNDODC8PfqdwLHU1C9Lt5S+MUNXNDBOSyJhEFMzKDL54ka.ywJaq8Vo9IOvVvXJd.jY+dCysYAEmDcEbu7r2p27i6V8xL4WNlWX3zL3RQnQUYt0kZxXmiYUhBsm.UqKGkrGb8P0xcyVIHEGagMUTLgfoZSKEsJao.yiHBniga6ZxoHF5f37Gt3wKG+ObyZG5+GFL8Z4fZWZGTW3ImPH2ruIn6MUTdBSOaKcXaxEJfyElooIrcRYlPOodazKPedcmaedyM37QB2631WnCGNe7tzbvKDs+uFuEcM2x8oww7PcEXW1c+e8eaKxK.T9EUtVHO+ELcp3MvSENHez.3MJgb.IRHGFe9fyRXAfcbWbLxLC3xntku3nPY.N1oPYPoRxHVXp5Ug1xFru7OwHAvjz75mFvyvfwzfxBFD2ifGK7pvPjH9V.4y2i0VXOVeg8XiE1i6uvd7fE1iMWXOd3GvC7kYamqUirkEDxeCmbrLqB
                

                Basically you made two mistakes:

                1. The persistent values of interface widgets are initialized after the onInit callback. Internally this happens when you hit Compile:
                • Save all interface values which are set to saveInPreset
                • Clear everything
                • Recompile the script
                • Restore the interface values with the previously saved ones
                • Run the onControl callback for every stored interface widget

                So it makes no sense trying to restore the data in the onInit callback as it will be merciless overwritten by the previously saved ones. Instead you must use the onControl callback of the panel (the value parameter will be the saved object, so you can directly assign it to myArray.

                1. The control callback of a SliderPack has the changed index as value parameter.
                  You can use SliderPack.getSliderIndexAt() to obtain the actual value (if it would be the other way around, there would be no way to get the index of the changed slider, which is useful for stuff like arpeggiators etc.).
                  I admit the number parameter is extremely poorly named (I originally passed the index of the interface widget and not a reference to it and changing it breaks older presets).
                1 Reply Last reply Reply Quote 1
                • d.healeyD
                  d.healey
                  last edited by

                  Thanks for the detailed response, it's good to know we can use one panel for many variables. I'll check out the patch and play around some more with persistent values :)

                  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

                    Based on your pointers I've put together this little module, the only problem is it seems that my public functions can't see my private variables. Is this a HISE thing or some daft JS mistake I've made? I'm thinking I can probably streamline this more and get rid of the persistentStorage object but for now I'd be happy if I can just get it working.

                    var persistentData = (function() {
                    
                    	//Persistent data must be stored in a GUI widget
                    	var persistentStorage = {}; //Object used to read and write data to persistent panel
                    
                    	var persistentPanel = Content.addPanel("persistentPanel", 0, 0); //Hidden GUI widget for storing data
                    	persistentPanel.set("visible", false);
                    	persistentPanel.set("saveInPreset", true);
                    
                    	return 
                    	{
                    		get: function(key)
                    		{
                    			persistentStorage = persistentPanel.getValue();
                    			return persistentStorage[key];
                    		},
                    
                    		set: function(key, value)
                    		{
                    			persistentStorage[key] = value;
                    			persistentPanel.setValue(persistentStorage);
                    		}
                    	};
                    
                    })();

                    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

                      Your code seems to be a bit too complicated - too many brackets :)

                      But you can wrap this up into a class like function like this:

                      /** A wrapper object around a hidden panel.
                      *
                      *	Create it using `new PersistentData()` and call its `set` and `get` methods.
                      */
                      function PersistentData()
                      {
                      	this.panel = Content.addPanel("persistentData", 0, 0);
                      	this.panel.set("visible", false);
                      	this.panel.set("saveInPreset", true);
                      	this.panel.setValue({}); // make sure the panel's value is a object
                      	
                      	this.set = function(key, value)
                      	{
                      		this.panel.getValue()[key] = value;
                      	};
                      	
                      	this.get = function(key)
                      	{
                      		return this.panel.getValue()[key];
                      	};
                      };
                      
                      // Example usage
                      var data = new PersistentData();
                      data.set("test", 5);
                      Console.print(data.get("test"));
                      

                      Notes:

                      • notice the usage of the this keyword, understanding it is crucial for every object oriented approach within Javascript (it will also fix your public / private problem).
                      • you can access the object directly from Panel.getValue(), no need for a temporary object
                      • make sure you use the new operator when creating the object.
                      • this class should only be created once (because the identifier of the panel is hardcoded). If you need more objects, pass a string as argument and use it for the panel name.
                      LindonL 1 Reply Last reply Reply Quote 1
                      • d.healeyD
                        d.healey
                        last edited by

                        Thanks again Christoph - you always have a good solution :)

                        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

                          I've found a small issue with the solution. Check out this example:

                          function myModule()
                          {
                          	this.chicken = "Bird";
                          
                          	this.getChicken = function()
                          	{
                          	    return this.chicken;
                          	};
                          }
                          
                          var module = new myModule();
                          module.chicken = "Dog";
                          Console.print(module.chicken);
                          

                          chicken should be a private member that the user doesn't have direct access to but using the above could makes everything public. In my previous example I was using an iife (hence the extra brackets) which would usually allow private and public members but it wasn't working as I expected in HISE.

                          The other solution I've tried is to declare chicken as var chicken = "Bird" which should make it accessible from within the getChicken function but not from outside of myModule. Is there a solution that would provide both private and public members?

                          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

                            Hmm, do you really need this level of encapsulation? TBH I think Javascript isn't designed for this language paradigm and the solutions are kind of hacky.

                            For >200.000 line projects written in C++ encapsulation is a must but for scripts it seems a bit over the top.

                            Why do you bother about this (is there a special use case that I am not seeing that definetily needs private members?

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

                              I can certainly move on without it, I'm just being pedantic really because I like encapsulation. My main purpose for this is for the framework I'm putting together so I can keep all my namespaces separate and safe. I think as long as I put comments to make sure the classes are used as intended everything should be fine.

                              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

                                This advice gives the most encapsulation for the least complicated implementation IMHO.

                                Possibly the best known way to achieve some form of privacy in JavaScript is to simply prefix all “private” members with “” or something similar. It’s very comfortable to use since it doesn’t add much (or any) complexity to your code, and requires no additional operations or memory at runtime. The obvious downside is that it doesn’t provide any real privacy at all, it only marks the members as “don’t touch that” for any developers working with the code. It’s what I do most of the time, though there is a minor variation that I have been trying out: Instead of prefixing the actual properties, I create a single property called “” which is an object that holds all the other “private” properties. (Let’s call that Method 1b.)

                                (taken from here)

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

                                  I like that idea, nice and simple. Thanks for bringing it to my attention, I shall use it!

                                  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 the glitch is fixed (I didn't find out the exact reason why it did that, but it should not occur again)...

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

                                      Excellent!

                                      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

                                        I remember getting on with this before but I'm working on a little module now and the persistent storage doesn't seem to be working for me. Would you mind taking a look when you have the time? This module is an articulation switcher that seeks out containers that have a midiMuter with the same name as the container and counts them as articulations which can be muted or unmuted.

                                        HiseSnippet 2683.3oc6astbaabEFTRH0j1HMIi+Qm9qsb5jP5KTjV4Vkpq0U6xwVwbDk8zY73IcEvRxMBDfC1ERVwidm5iPej7aP64rKtRAJAYSKmKVw1ivhy4re645GHX5E3ayDB+.iJWe+SlvLpbCy9m3IGs0HJ2yn61FU9DSISHM17jITgf4XToxhOBuWkpKYn94MOXSpK0ylktjgwy841rmvGykoq1a8GycceH0gsOebFo+506Z66skuqeHfiEMaaLgZeHcH6GnnXKXZbDmcrvnRayUtWqfC6bvOuQqje1W8ui1czeSzGWda7xdJALrCCBXdxmCpaTwrx+C9oh4NNboePeIENWvpa56bR+Q9G6o25myE7CbY3EcL5CXRu7C8ccvCO96c8jrfATaVF0L1ZD20oWr6TX.VtWpycQsy8ll6xc3Iqm5j+L0MHoZj0cWYg7PdobPtSVH2tPH2o.3YjAcKoQG.BemPWpLOxvnczM39d4PF5I7Db4IYyF9fB2O2rGWZOpX7tPA3EBTuuwaTv2xbmACX1xTvtj4C+WWsQ5qMih7qatkumDthELOpz+2ktRuxhm2ItTkierz6ikd+JtzqpoHTfkderv6sKbbIfWkylJ+4l8sC3Sjo2Aw1WDs5LPm9lFK7W9ylKeqaUibKx9boKaUxFARtcT5Oo+wX8.KfbTmVsg+6mDnjaDJG4GrJYa5QbGx+jQcYmfquMbPWkrR6ka+sKeu1c9NbMnVhOfybld8m.QdOAH9i58jiVgbWxHobhX0kW93iOt0PuvV9ACW1UKjX4gSbu6Jv9y7ZMRN1s1sVtVsAgd1JP1iEH3Bn1TB.f1nYsWWqpbDWzZB0i4RtOAGL.2sE0woGtTi5SxoR86PZC+o4ZY0qkfIaT+HcPBjX.0UvJRDA8HVWudAL3JPNYPXAh8bpaHqwqOs4ZjkWlLldHiHBCXD4HFQIzWIHGgxP3BBk3evOA050pFYFv.vwH9.23P1I2QKcyZUgCa18ZX7d07EfXuDTSIH.nSWKwdCOi8hLT.SFF3Qls8z1A9SM3Xryqnim3xHgBfoasinADAjuC+NXbO1wmIv.ZAkvBIQIpR2fm.B.hq5nfaVWGbkF06qucckC6Q.dijm3ALpEYric7T+YYoDZAo1JQGAg6j0XzLI+BvXu3knJc2VP7GjpE3enRxHHtCgpwXGfwg.eZxwi7ELR2sIbOa2PGlPEdSUCgdlMSozrPM1XYWTfTTq50nVSg5LVxAbuZzVKfMj.ApnB2zyvFttDn3mOzi4fBPDQRnzHjZaWrnp6nRgzRF87HpDfG8rtYONdgak5WyU0sk+3C72z+UYBFhzhtbl3wyT0GCfVer.U67MEo7yzGiBU+Yar0VfhqzNRQ.+87mfwZ1TPG1iQpHmJUaVQ9wwAHQsA9AjFbXiauFgS96oA1VtLugxQvp291MAO6NT6Qjc6tcWcXDaToz0FxXxmHmHcxp5BT9.Ric7FBKzZLUE+1iMj8pFIa4K3u7Nj5MpStMwF9a8l0ah1p6POenciZuUxJzGEGeuuRFmuVT5ZU01p1WLKCLO49POEetSSRxBjWepJwwwIpyEAOVY7Z95TTZP.8DzbQZ1RW2jI8O2f1bmplw6Plx.bWvdU42JtTn2t3tnUqlqtt0jPwnF1IFLUYnzEzWgRLrmUqn9Nfsxkrf4XckrwQlKIiJ0lNA9Sbfg9fpmBMOqcZtLuG2mP8bHXxYhjmMgpy89dcNDlwnJRR12njgHW2O3KUejCM3MyiGXeRABGCgsIOHtjIwX02lKnv3Nm5MIqdl6xyaxbXFOVICj88Pb7TO8nXL0ISGoVQtFQicgfLLr.wtB2giOfEznoJecCDwx.9vgr.nKjM008.p8g5h.k6wAqYvvbRohJlybYigZ+37VGcJFNAcCIXuCfqZ.c.5nNKXVDghs6xFoO3DhCa.MzUVKI0u0gBzoMKHC15g9gPfjh3VUYhppfvLwPaEFdlGdWTvSyjhLsubv.syDtWlag4gA9ttHFhc0YfX5siAJdF5P9xujTnTQC5I+C.ZHxf.bZWGbPPgwtynuxcreRrSkmjxsIdvBVn4kywGGyJW38BbtkL.WUYDcHVOD79mquIajVcvRh0Q3ozQaU3dVwb7QeBRh3.AcqxyP2ZVTzsJhit0rHoa8NyR2BnoaUyZ1D0sp8Zq2Vp5VkfqtUIIqaMWXqCVw5B4qCRfm4xvX2BoZmwnEPZO1ZWLs8Hig+05LT2sJC2cTw4D6cq4J8cqqT96VyMB74cnoT3st7b3sJOIdqbr30YC.Odq4.Qdq2Il7Vu0T40Gh4DYdq2Z175tYklOebs6UMidbOUa77jSu0UModq4Iqdq2AZ8ntmhcWglqSkHVH2dqYStWm.8tRu258B+9nSWAT70nddRxOtxnD7.SSle23Ahms2dp9Jc0vnTz+TRd5zYNEQ4W4bm9tYY8m58mu79y1c58Oy+zvXIi4Wj2trQ8pVyE9+ZqDgoxmBnyAN2LgnGD37xCZ3oBxoLLQbnYFDcqDdh1TfeSDOuUIpMO5J7v1nN5lqq3CW8f.F8v0z0EJ0x0ebUktQrHhYrd2N34aqnEOSHS2XKgcsdzSjIdITzc6NM0ac03FSIxlWTLNABOSX93H3koeThx4wZeINBU.nT6SgztwTANDB6cmevVFjlwH47ghDe3czoup38DGraZ5iwDG.lE7wit9.fGzhPdAfJh62bFVpLxy7d1pUtWjksl5VFA8855wkOcBK5EzEOD4LqLXP1kRKBytppxn.whWpvWlYDcRCiJKEINHpL5ErF8Vzvmexf6fucu7O6ogx6l88WZLsQ9rHiDyUUYmaj9MSPLsMdyCJqMRIM+1ZiOwD6XUf1e7k4+6vWl+M0P4KL6Kgp8wbugQOz9GxWoeu.lqO0oO+myH1+c8MCA2UP9U+Oqq1pMFCSiysWQGi8XSXTID8yAu816QA9gSlVq27.Utx9A.8SvSj8FO0C+RxIyZjsB7EhAvwQYKQ1a0KLXH5qxririf597qAzxfPuGznA+56UoBrjF06Rmn91BN8WwuqUtuZCf5p1WYxS1jOLiowUxWDmQzji093yHjY2N+jpJexud9FSDAuqal7oyD8ckH45hR6md.3hkCWm67mEltk8mF0xdyPoD5UgMr+TSt5g7iV5hG+TfM9ilC3upuLz9Pbxpn.ibk08ewx0B6BBg+gXL1mio063cDzx.VQ2xeaMy9jUuPPBLzgZ9zUt456AzAApXoK8WW+IvraZP9dIWpyWmxe9NuXvexTCWB1Gk7aiIwK969IwmmqCpn0eP8vtGH+Edb9FlpAhDbR+GJntmenDlfuKEdv6WAyQgQs8A5E1rrCbW.6cputMdMBn9LOm1weE6itYmjoyvM6DeSC6XSAmsneW87AUVj4o930PBltvbe2rozBfDCBIX7tg90gLFGIuD54f05SOho6vnwyLYprK2tmO3LwOzSzMr1Uyg92J6wXpcf+OZqmbhgvqoVA7jdp+e0np4t30jNwiJwjN78C7i11X2g6BocEqw8tzZrxkViu9Rqw2bo03auzZ7cWZM99yQCjK1FgR+w5YEFF+e8fXD6B
                                        

                                        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

                                          I think the problem is that you are storing the initial object in the onInit callback which gets overwritten by any value in the onControl callback of the ScriptPanel.

                                          A better solution is to use a dedicated variable for the object and think of the panel as "restorer" (not as actual container for data). This script might explain this idea:

                                          /** The restorer.
                                          *
                                          *    This panel will restore the storage object in its control callback. If the value is not an object, it won't do anything but use the given storage variable as value (see the onControl callback)
                                          */
                                          const var restorer = Content.addPanel("restorer", 0, 0);
                                          restorer.set("saveInPreset", true);
                                          restorer.set("visible", false);
                                          
                                          /** The data object. This will be overwritten by the onControl callback of the restorer */
                                          reg storage = {};
                                          
                                          /** Checks if a given variable is an object. */
                                          inline function isObject(variable)
                                          {
                                              return typeof(variable) == "object";
                                          };
                                          
                                          const var Knob = Content.addKnob("Knob", 0, 0);
                                          
                                          // Make the knob non persistent for demonstrating purposes
                                          Knob.set("saveInPreset", false);
                                          
                                          
                                          inline function onKnobControl(component, value)
                                          {
                                              // Just use the storage object (ignore the restorer)
                                              storage.a = value;
                                          };
                                          
                                          Knob.setControlCallback(onKnobControl);
                                          
                                          function onNoteOn() {}
                                          function onNoteOff() {}
                                          function onController() {}
                                          function onTimer() {}
                                          function onControl(number, value)
                                          {
                                              if(number == restorer)
                                              {
                                                  // Check in the callback if the value is an object
                                                  // If not, set the value to the storage object
                                                  
                                                  if(isObject(value))
                                                  {
                                                      // Copy the object from the restorer to the storage variable
                                                      storage = value;
                                                      Console.print("Restoring storage");
                                                      
                                                      Console.print("The restored knob value is: " + storage.a);
                                                  }
                                                  else    
                                                  {    
                                                      restorer.setValue(storage);
                                                      Console.print("Initialising restorer");
                                                  }
                                              }
                                          }
                                          
                                          d.healeyD 1 Reply Last reply Reply Quote 0
                                          • d.healeyD
                                            d.healey
                                            last edited by

                                            Thanks Christoph, I think I get it (again). This is what happens when I stop coding in HISE for a month I forget everything

                                            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

                                            50

                                            Online

                                            1.7k

                                            Users

                                            11.7k

                                            Topics

                                            101.8k

                                            Posts