View Single Post
Old 09-20-2018, 09:27 AM   #21
mespotine
Human being with feelings
 
mespotine's Avatar
 
Join Date: May 2017
Location: Leipzig, Germany
Posts: 744
Default

Some basics:
Defer-loops are an alternative to while/for-loops. While and for loops, when running too long, "block" the GUI of Reaper at some point.
To overcome this, you can use defer-loops.
It will end the script, when reaching the defer-function, so Reaper can do the other tasks(other running scripts, updating GUI, etc) and return to your script, restarting it at the function you gave to the defer-function.
e.g. reaper.defer(main) will restart executing the script the next time from the function main().

The following code updates a counter and displays it into Reaper-Console-window, by running main().

Code:
Counter=0

function main()
   reaper.ClearConsole()
   reaper.ShowConsoleMsg(Counter)
   Counter=Counter+1

  -- now, we do the defering/looping
   reaper.defer(main)
end

main()

Some additional things:
defer-scripts are run about 30 times a second, so the execution of the main-function is never more often than 30 times. If you want to execute the code in the main function more often, you need to put it into a for-loop:

Code:
Counter=0

function main()
  for i=0, 10 do -- now we add to variable Counter 10 times more often per 
                 -- second,
                 -- means 300 times, as opposed to 30 times in the example 
                 -- before
    reaper.ClearConsole()
    reaper.ShowConsoleMsg(Counter)
    Counter=Counter+1

    -- now, we do the deferring/looping
    reaper.defer(main)
  end
end

main()
You can also use while-loops to never run the loop longer than a specific time. Use reaper.time_precise() to define a starting and endtime.


Another thing is, the first time the script is executed, it will run completely, until the end. From the second time onward, it will run only the deferred function.

Code:
Counter=0

function main()
  for i=0, 10 do -- now we add to variable Counter 10 times more often per 
                 -- second,
                 -- means 300 times, as opposed to 30 times in the example 
                 -- before
    reaper.ClearConsole()
    reaper.ShowConsoleMsg(Counter)
    Counter=Counter+1

    -- now, we do the deferring/looping
    reaper.defer(main)
  end
end

main()

reaper.MB("This Messagebox is shown only in the first run of the script!","",0)
Last thing is:
With every defer-cycle, the variables and returned values by functions will be updated. So with every defer-cycle, reaper.GetPlayPosition() will return the updated position of the playcursor.
These will be updated once, before going into the deferred-function. So the values stay the same, until they are updated the next defer-cycle.

Code:
function main()
   reaper.ClearConsole()
   reaper.ShowConsoleMsg(reaper.GetPlayPosition().."\n")
   for i=0, 10000 do end  
   reaper.ShowConsoleMsg(reaper.GetPlayPosition()) -- shows the same playposition as the ShowConsoleMsg() before, 
                                                   -- even if playposition has changed during the for-loop.
   
   -- now, we do the deferring/looping
   reaper.defer(main)
end

main()
PS:
When you want to run the defer-script only a limited number of times, use an if in the defer-line

Code:
Counter=0

function main()
   reaper.ClearConsole()
   reaper.ShowConsoleMsg(Counter)
   Counter=Counter+1

  -- now, we do the defering/looping
   if Counter<100 then reaper.defer(main) end -- will defer, until Counter is 100
end

main()

Last edited by mespotine; 11-12-2018 at 03:06 AM.
mespotine is offline   Reply With Quote