Accessing parameter reference outside the function call
-
nope that makes no difference.
-
@Christoph-Hart this works tho...its a hack but :
const PWLock = Content.getComponent("PitchWheelLock"); inline function onPitchWheelAmountControl(component, value) { pos = thePitchWheelAmountControls.indexOf(component); thePitchWheelModulators[pos].setIntensity(value*-1); if (PWLock.getValue() == 1) { for(i= 0; i< TOTAL_NUM_VOICES; i++) { if(thePitchWheelAmountControls[i] == component) continue; thePitchWheelAmountControls[i].setValue(value); //thePitchWheelAmountControls[i].changed(); thePitchWheelModulators[i].setIntensity(value*-1); }; }; };
-
@Lindon OK, I've investigated it a bit and actually the current behaviour is "correct" in the sense that inline functions do not allow recursion (and recursive function calls are almost always a bad idea, unless you write compilers or other abstract mechanisms).
There are some limitations for the usage of inline functions:
- no constructor (if your function definition is a prototype)
- no recursion
The reason for this rule is that a inline function cannot allocate a scope so it can be used in a realtime context, however calling a function recursively without having it's own "dynamic" scope is a recipe for disaster because it can overwrite any local values including loop indexes and so on.
In your example the recursion is hidden behind the call to
changed
which itself causesonPitchWheelAmountControl
to be executed with the first component inthePitchWheelAmountControls
. This setspos
to zero and will cause the loop to run again, this time with another index, so my failsafe continue statement will not work and the only thing that will break the cycle is indeed commenting out thechanged()
call to prevent the recursion happening in the first place.I'm not sure what made this code run in the past and why it isn't working now. One thing could be the redesign of the scope of local variables to not leak into the global namespace and made the anonymous variable definition in for statements use the local storage type. This is a good thing as this was messing with the outer function index if you call a inline function in a loop and have the outer loop index also named
i
like any sane programmer does.inline function inner() { for(i = 0; i < 100; i++) { Console.print(i); } } // some 2000 lines later inline function outerFunction() { for(i = 0; i < 5; i++) inner(); }
I've added a recursion check that tries to analyse the stack trace and throws an error message so that at least it won't crash HISE but you definitely have to rework the way you handled this callback (just call
setIntensity()
for each modulator in the loop instead ofchanged()
, this is the only thing you're doing besides causing the apocalyptic recursion machine. -
@Christoph-Hart yep - understood. I would normally never do this sort of thing, I was (however) under the impression that the UI control callbacks had a mechanism to stop this happening - I have no idea where I got this idea from -- early documentation?? My dumb mis-read ...as you say in this (and all subsequent ) situations like this I will execute the "actual" processes I want to see happen - rather than using the convenience of calling .changed() on sibling controls...
-
To be honest I vaguely remember that I've already added a recursion check specifically to the
changed
call but that is like 5-6 years ago.I would normally never do this sort of thing
I understand, a friend of yours wrote that code, classic Lindon :)
-
@Christoph-Hart said in Accessing parameter reference outside the function call:
To be honest I vaguely remember that I've already added a recursion check specifically to the
changed
call but that is like 5-6 years ago.I would normally never do this sort of thing
I understand, a friend of yours wrote that code, classic Lindon :)
"Friend"? wot you think I have friends?.... I just have t-shirts.
-
I remember the recursion check too and relied on it for some stuff, sure I mentioned it in a video.
-
I just did a test and this problem was introduced in the last few days with all the faust commits, prior to that there was no issue because of HISE's recursion protection. A build from October 8th works.
Apparently some guy called Christoph was going to introduce a stack based way of handling this to make it more robust ;) https://forum.hise.audio/topic/797/panel-changed-recursion/3
-
Can you make an example snippet that works on October 8th?
-
HiseSnippet 1090.3oc0WssaiSDFdbR8plvwE1G.q8prhkJ6cKEPqVUSyATfdHhjsKRbwxjwiSFkwyXrGWZDZk3MfK4VdT3QYEOAbCWC+isisCMMsMpKG7EQY9OMe+msGDIIz3XYDxnwn4gTjwaZNbtPMs8TLSf52QS374pDkLhg4nClGhiiodHCi5etVBiFagRe988O.ywBBsjDBcpjQnGxBXpRpCb+RFm2C6QGwBpH8tt8IRQaIWl.notoMJDSlgmPOFqEqlIx3Nc8X.PFpvJZLxXqCjdyGNU98hL4OkEyFyo5CNngfgxH2Sx8zHVSE0dJi6MXgWGi.qLnLFTOKFbOyiXdrB5kwh2MkgUoFUiGF0VFd0WBdNUgmcE3sBHYTARakAo6ZNjDwBUkbz34ML6KTzHeLD1qBkLYQ07qY1VBRHT6DfmQ6EAGJzn0d11OzB94AOoYSHzGqrNCGYMSL115oVKzaBU0VFDJEvgV2Wy79Z4YBNSPs7SDDESJrjBMKsRQRdKxBMdHXRdB8AM+glM.Ab1IlpNUSoUF8mjSlLEKlP8ZADdIX80c4ZSjeOswb9XnHo0R29EbGm04NNWt63bUti8pcG6qs63rF2woh6j8TAcGKUzSDsRARyW1z5uyx2ek7xMImFsR15Fxn0oXKQRvXZT0vfVPnJc4ReyKuzuZmIIKtTQPonufoNIjJtr9UTdvDZSpkiJPTUZSxam2jLjy7nQHFzKbGScBAkh27YM+R3S+s8QWWccVgtOqeGrBqaTyAC.vPZjho8ciNzyfodYssML6PimojgonMO0CV9pv64EyE+0wtyKOvcCXddb5.YLSmZJGe9p8UzyUKFobsuJmJW02FeSuJHAcwQUvPRoWBGqVdxodcQNCs0pNtRORR.2x7pqSd8LN8cxvno4g8NIGXv+rJPryUCrdQzuKgJHUHtsqdeV+xXj6O49b7YTeYTPdgPg5GRm.WTUJinP1B15Rpt5bXfTplxDSVdK48bOTJC6Jvfq6U0HClhi088v3jkLCX1QxivwvP+1bIYVUlsShUxfE.McG6PEMLs313aL2a2cfG+OP+6m1F94wmb6bFcCxsNqO2V6ZV+89oo4h7oNg+uUIXiBXBuKQ4D4TX9dYufQI0qQ83yhoivovnLy1WbFLOpZEBBUZziSmhWv6GetaV01xkZL2NTebBOaCWNc2l+bW2aszG5Fk8JZ79eS16Q+GK68p+X6u3e9r2cMGvTjoqd3esUDUPnasbG5huc+aY102mRTk.bKyde8qmWkG8UxDELD+HrJhAaZMgj2P3CbHT31EBJW+xRF0z42ry15yoCtoBuzC+I7jyzQe1HmoyBln.LIR9BRVAhtdc6TJ.lDoe5TCyizmsJdUFSS6crQv5c1KHDs6+gvh7Uqyi1.cd7FnytafNezFnydafNe7FnymrVcziI9L3apCxZG.BC5ls00nX0tQczeAG5GLiB
-
@d-healey Hmm, I see so the trivial example you've posted was catched by the existing recursion protection whose existence I forgot, but the example of Lindon's "friend" found a nasty way to bypass that protection somehow so I needed to pull out more heavier weapons which now break every recursive
changed()
call.So I would recommend to remove the new error message for now and then spent an evening with a glass of red wine and the poster child of beautiful code that is Lindon's snippet to find a better solution.
-
@Christoph-Hart Sounds like a good evening :)
-
@Christoph-Hart my work here is done...or more correctly my "friend's work"