Using a loop in onControl



  • I have a script where I declare some buttons and knobs in a loop. In the onControl callback I also want to use a loop to see which button/knob triggered the callback. For some reason - possibly my stupidity - only the first button/knob is picked up by the loop. Am I missing something obvious?

    <?xml version="1.0" encoding="UTF-8"?>
    
    <Processor Type="ScriptProcessor" ID="Script Processor" Bypassed="0" Script="Content.setHeight(100);&#13;&#10;&#13;&#10;const var buttons = [];&#13;&#10;const var knobs = [];&#13;&#10;&#13;&#10;for (i = 0; i &lt; 5; i++)&#13;&#10;{&#13;&#10;&#9;buttons[i] = Content.addButton(&quot;button &quot;+i, 150*i, 0);&#13;&#10;&#9;knobs[i] = Content.addKnob(&quot;knob &quot;+i, 150*i, 35);&#10;}function onNoteOn()&#10;{&#10;&#9;&#10;}&#10;function onNoteOff()&#10;{&#10;&#9;&#10;}&#10;function onController()&#10;{&#10;&#9;&#10;}&#10;function onTimer()&#10;{&#10;&#9;&#10;}&#10;function onControl(number, value)&#10;{&#10;&#9;for (i = 0; i &lt; buttons.length; i++)&#13;&#10;&#9;{&#13;&#10;&#9;&#9;switch (number)&#13;&#10;&#9;&#9;{&#13;&#10;&#9;&#9;&#9;case buttons[i]:&#13;&#10;&#9;&#9;&#9;&#9;Console.print(&quot;Button &quot; + i);&#13;&#10;&#9;&#9;&#9;break;&#13;&#10;&#9;&#9;&#9;&#13;&#10;&#9;&#9;&#9;case knobs[i]:&#13;&#10;&#9;&#9;&#9;&#9;Console.print(&quot;Knob &quot; + i);&#13;&#10;&#9;&#9;&#9;break;&#9;&#9;&#9;&#10;&#9;&#9;}&#10;&#9;}&#10;}&#10;">
      <EditorStates BodyShown="1" Visible="1" Solo="0" contentShown="1" onInitOpen="0"
                    onNoteOnOpen="0" onNoteOffOpen="0" onControllerOpen="0" onTimerOpen="0"
                    onControlOpen="1"/>
      <ChildProcessors/>
      <Content>
        <Control type="ScriptButton" id="button 0" value="0"/>
        <Control type="ScriptSlider" id="knob 0" value="0"/>
        <Control type="ScriptButton" id="button 1" value="0"/>
        <Control type="ScriptSlider" id="knob 1" value="0"/>
        <Control type="ScriptButton" id="button 2" value="0"/>
        <Control type="ScriptSlider" id="knob 2" value="0"/>
        <Control type="ScriptButton" id="button 3" value="0"/>
        <Control type="ScriptSlider" id="knob 3" value="0"/>
        <Control type="ScriptButton" id="button 4" value="0"/>
        <Control type="ScriptSlider" id="knob 4" value="0"/>
      </Content>
    </Processor>
    


  • All fine here:

    Script Processor: Button 0
    Script Processor: Button 1
    Script Processor: Button 2
    Script Processor: Button 3
    Script Processor: Button 4
    Script Processor: Knob 0
    Script Processor: Knob 1
    Script Processor: Knob 2
    Script Processor: Knob 3
    Script Processor: Knob 4
    

    What's your output?



  • If I click button 0 I get

    Script Processor: Button 0
    Script Processor: Button 1
    Script Processor: Button 2
    Script Processor: Button 3
    Script Processor: Button 4
    

    If I click any of the others I get nothing. The same for the knobs, moving knob0 gives output but the others don't.



  • Ah, I figured it out. The problem is the switch statement. You can only use constants for your case expressions. They get evaluated once at compilation and then the switch statements just compares the condition with the preevaluated case statements to jump directly to the according branch. This brings a drastic performance increase because it skips the evaluation on Javascript, and just compares the values directly in C++. However in your code:

    function onControl(number, value)
    {
    	for (i = 0; i < buttons.length; i++)
    	{
    		switch (number)
    		{
    			case buttons[i]: // not a constant
    				Console.print("Button " + i);
    			break;
    			
    			case knobs[i]:
    				Console.print("Knob " + i);
    			break;			
    		}
    	}
    }
    

    it always compares the switch condition agains the first element of the button array and the knob array. The solution is to use if / else instead:

    function onControl(number, value)
    {
    	for (i = 0; i < buttons.length; i++)
    	{
    		if(buttons[i] == number)
    		{
    			Console.print("Button " + i);
    			break;
    		}	
    		else if (knobs[i] == number)
    		{
    			Console.print("Knob " + i);
    			break;
    		}
    	}
    }
    

    There's a JUCE forum post from a really nice guy that explains this behaviour for further reading 🙂



  • Thanks Christoph, mystery solved 🙂


 

5
Online

353
Users

1.1k
Topics

7.6k
Posts