Break out of inner loop

No out of bound or sanity checks yet but for some reason I can’t get this to work. Appears to me that the break command in this bit of code is jumping out of the outer [i]for[i] loop, as well as the inner one.

To test you will need a song with at least 2 sequences.

rns = renoise.song  
  
 local function jump(jsq, mode)  
 if mode == "edit" then  
 local start = 1  
 local jpat = 1  
 for i = 1, jsq do  
 for j = jpat, rns().transport.song_length.sequence do  
 if rns().sequencer:sequence_is_start_of_section(j) == true then jpat=j break end   
 end  
 end  
 local pos = rns().transport.edit_pos  
 pos.sequence = jpat  
 rns().transport.edit_pos = pos  
 end  
 end  
  
 jump(2, "edit")  

Hopefully somebody can see something simply wrong in my workings…

Could you describe a bit more about what you’re trying to do exactly? What is the intended result of calling your jump() function?

You’re obviously moving the edit position to the start of a section in the sequence, but what’s the purpose of the outer loop running twice via jsq = 2?

For what it’s worth, adding a few trace statements to print out the intermediate values will reveal exactly what is going, and makes it a lot easier to debug.

A quick mod to your code:

rns = renoise.song  
  
local function jump(jsq, mode)  
 if mode == "edit" then  
 local start = 1  
 local jpat = 1  
 for i = 1, jsq do  
 print('Outer loop: i = ' .. i)  
 for j = jpat, rns().transport.song_length.sequence do  
 print('Inner loop: j = ' .. j)  
 if rns().sequencer:sequence_is_start_of_section(j) then   
 jpat = j   
 print('Start of section: jpat = ' .. jpat)  
 break   
 end   
 end  
 end  
 local pos = rns().transport.edit_pos  
 pos.sequence = jpat  
 rns().transport.edit_pos = pos  
 end  
end  
  
jump(2, "edit")  

Output when run on a song with a few patterns and a section as the first sequence position:

  
Outer loop: i = 1  
Inner loop: j = 1  
Start of section: jpat = 1  
Outer loop: i = 2  
Inner loop: j = 1  
Start of section: jpat = 1  
  

As you can see, the outer loop runs twice, so the break is not affecting it.

The outer loop, with jsq selects which Section to jump to, assuming the first is 1, second is 2 and so on.

So outer loop, do until reach required section.
Inner loop, do from last position until find a start_of_selection then break back to outer loop.
Take sequence position from inner loop and move edit position to it.

Been trying with an even simpler, LUA only (no API function) example and still not getting the behaviour I expect but it’s not that it’s jumping out of both loops, but somehow seems to return to the beginning at the end. I’m sure I will work through this…

  
  
  
  
function jump_to_next_section()  
local rns = renoise.song  
  
 local function jump(jsq, mode)  
 if mode == "edit" then  
 local pos = rns().transport.edit_pos  
 local start = 1  
 local jpat = pos.sequence  
 for i = 1, jsq do  
 for j = jpat, rns().transport.song_length.sequence do  
 if rns().sequencer:sequence_is_start_of_section(j) == true then   
 print("break 1")  
 jpat=j   
 break   
  
 end   
 print("j:"..tostring(j))  
 end  
 print("i:"..tostring(i))  
 end  
 print("break 2")  
 pos.sequence = jpat  
 rns().transport.edit_pos = pos  
 end  
 end  
  
 jump(2, "edit")  
end  

Looks working to me…

j:1
j:2
j:3
break 1
i:1
break 1
i:2
break 2

Since you ask for a jump 2, jsq will be 2 and the for next will not do more cycles.

Got it!

As I was setting the start point to the value of the last success each subsequent time around was obviously going to start on the pattern which had just met the requirements. Needed a +1 in there (and -1 later.)

rns = renoise.song  
  
 local function jump(jsq, mode)  
 if mode == "edit" then  
 local start = 1  
 local jpat = 1  
 for i = 1, jsq do  
 for j = jpat, rns().transport.song_length.sequence do  
 if rns().sequencer:sequence_is_start_of_section(j) == true then jpat=j+1 break end   
 end  
 end  
 local pos = rns().transport.edit_pos  
 pos.sequence = jpat-1  
 rns().transport.edit_pos = pos  
 end  
 end  
  
 jump(2, "edit")  

Knew it would be something simple! ;)

Have you tried something like “jpat = j+1” since if you say jpat = j, it will be right on the start of the same section in the next round (yet is is a start of a section)

If all you need to do is jump to the given section by its index, then there’s no need for both outer and inner loops. You can simplify it to something like this:

  
local function jump_to_section(section)  
  
 local song = renoise.song()  
 local section_count = 0  
  
 for i = 1, song.transport.song_length.sequence do  
  
 if song.sequencer:sequence_is_start_of_section(i) then  
  
 section_count = section_count + 1  
  
 if section_count == section then  
  
 local edit_pos = song.transport.edit_pos  
 edit_pos.sequence = i  
 song.transport.edit_pos = edit_pos  
  
 -- Success.  
 renoise.app():show_status('Found section ' .. section .. ' at sequence ' .. i)  
 return true  
  
 end  
 end  
 end  
  
 -- Failure.  
 renoise.app():show_status('Section ' .. section .. ' was not found in the sequence.')  
 return false  
  
end  
  
jump_to_section(2)  
  

But you actually just mentioned a selection now in your reply. Was that a typo for section, or do you also intend to jump to a specific sequence based on what is selected in the sequencer, or matrix, or something else?

Thanks but realised just before seeing you basically pointing out the same above.

In the end went slightly different to my edit above and initiate jpat=0 and use j=jpat+1 for the loop’s starting point.

That’s works as well dBlue and makes perfect sense (surprised I didn’t go that way initially but got the double-loop in my mind) but both look to be likely as efficient as each other now I’ve worked out my silly mistake.