|
|
|
01-31-2019, 08:38 AM
|
#1
|
Human being with feelings
Join Date: Jan 2013
Posts: 1,126
|
Wait Until Next Bar to do an action
Hey guys,
I'm sorry for being a newbie, but I'm trying to learn LUA.
I'm trying to find a way to "wait until the end of current measure" before doing something from within the script using some kind of looping function.
Anybody can help me?
Thanks
|
|
|
01-31-2019, 09:18 AM
|
#2
|
Human being with feelings
Join Date: May 2015
Location: Québec, Canada
Posts: 4,937
|
Use reaper.defer to schedule a function to be run later (~33ms). Unlike regular loops which freeze REAPER until they stop, reaper.defer allows the GUI to run in between.
Code:
function onNextMeasure(callback)
local beatsSinceLastMeasure = reaper.TimeMap2_timeToBeats(0, reaper.GetPlayPosition())
if beatsSinceLastMeasure < 0.1 then
-- if we're at (or very near) the start of a measure, call the given function
callback()
else
-- or, if we're not at the start of a measure, check again ~33ms later
reaper.defer(function() onNextMeasure(callback) end)
end
end
onNextMeasure(function()
-- code to run at the next measure here
reaper.ShowConsoleMsg("Hello Next Measure!\n")
end)
Last edited by cfillion; 01-31-2019 at 09:32 AM.
|
|
|
01-31-2019, 11:18 AM
|
#3
|
Human being with feelings
Join Date: Apr 2013
Location: France
Posts: 9,875
|
Or simply put an action in a custom action after SWS: Wait for next bar (if playing) :P (depengind on what function is required of course)
|
|
|
01-31-2019, 12:02 PM
|
#4
|
Human being with feelings
Join Date: Jan 2013
Posts: 1,126
|
Quote:
Originally Posted by X-Raym
Or simply put an action in a custom action after SWS: Wait for next bar (if playing) :P (depengind on what function is required of course)
|
I thought that action was taken out? I can't find it in my action list.
|
|
|
01-31-2019, 12:03 PM
|
#5
|
Human being with feelings
Join Date: Apr 2013
Location: France
Posts: 9,875
|
|
|
|
01-31-2019, 12:06 PM
|
#6
|
Human being with feelings
Join Date: Jan 2013
Posts: 1,126
|
Quote:
Originally Posted by cfillion
Use reaper.defer to schedule a function to be run later (~33ms). Unlike regular loops which freeze REAPER until they stop, reaper.defer allows the GUI to run in between.
|
My only problem is that I need to use this to kill an already defered script. This Crashed Reaper.
If I test it using Reaper's programming window (Hitting CMS-S to run the script) it works. But if I close the Programming window and try to run the script from a key command. Reaper Crashes upon triggering the other Defered Script.
Any idea?
|
|
|
01-31-2019, 12:07 PM
|
#7
|
Human being with feelings
Join Date: Jan 2013
Posts: 1,126
|
Quote:
Originally Posted by X-Raym
|
Yes I do.
|
|
|
01-31-2019, 12:13 PM
|
#8
|
Human being with feelings
Join Date: May 2015
Location: Québec, Canada
Posts: 4,937
|
Quote:
Originally Posted by lexaproductions
Any idea?
|
Sounds like a bug (scripts should not be able to cause crashes)! How are you "killing an already defered script", which version of REAPER are you on, and can you post the crash report?
If you're using "ReaScript: Close all running reaScripts" (action 41898), this bug was fixed some time ago: https://forum.cockos.com/showthread.php?t=186699.
Quote:
Originally Posted by lexaproductions
I thought that action was taken out? I can't find it in my action list.
|
It's only available on Windows.
Last edited by cfillion; 01-31-2019 at 12:32 PM.
|
|
|
01-31-2019, 01:56 PM
|
#9
|
Human being with feelings
Join Date: Jan 2013
Posts: 1,126
|
Quote:
Originally Posted by cfillion
If you're using "ReaScript: Close all running reaScripts" (action 41898), this bug was fixed some time ago:
|
I'm not using that function as I have other scripts running that I don't want to kill at that moment
Quote:
Originally Posted by cfillion
Sounds like a bug (scripts should not be able to cause crashes)!
|
Well that's what I thought, because I'm pretty novice at this and I don't want to compromise Reaper's stability.
Quote:
Originally Posted by cfillion
which version of REAPER are you on,
|
I tried Reaper 5.77 and 5.965, same result
Quote:
Originally Posted by cfillion
How are you "killing an already defered script"
|
I might not have used the right terms when I said "deferred". Here's a full explanation:
I have "Script A" running in the background. It's a window showing the current region in a window.
Then I trigger "Script B" which monitors if "Script A" is running (using GetToggleCommandState), and kills it at the end of current bar. The Way Script A is kill is simple; I just re-instantiate it, and Reaper kills it instead of making a 2nd instance of the script.
The Problem is: When I trigger "Script B", as soon as it kills "Script A", Reaper Crashes. I've confirmed that, if I don't trigger the kill, Reaper doesn't crash.
Quote:
Originally Posted by cfillion
can you post the crash report?
|
Code:
Process: REAPER [29796]
Path: /Volumes/VOLUME/*/ReaLiveDev.app/Contents/MacOS/REAPER
Identifier: com.cockos.reaper
Version: 5.96.500 (5.96.500)
Code Type: X86-64 (Native)
Parent Process: ??? [1]
Responsible: REAPER [29796]
User ID: 501
Date/Time: 2019-01-31 15:37:48.833 -0500
OS Version: Mac OS X 10.11.6 (15G31)
Report Version: 11
Anonymous UUID: 48421833-45CE-0A6E-E670-0E640B1D81D1
Time Awake Since Boot: 770000 seconds
System Integrity Protection: disabled
Crashed Thread: 0 reaper Dispatch queue: com.apple.main-thread
Exception Type: EXC_BAD_ACCESS (SIGSEGV)
Exception Codes: KERN_INVALID_ADDRESS at 0x0000000000000020
Exception Note: EXC_CORPSE_NOTIFY
VM Regions Near 0x20:
-->
__TEXT 0000000100000000-0000000100ad7000 [ 10.8M] r-x/rwx SM=COW /Volumes/VOLUME/*/ReaLiveDev.app/Contents/MacOS/REAPER
Global Trace Buffer (reverse chronological seconds):
12.349460 libextension.dylib 0x00007fff866fa533 tearing down extension request for pid 29799
23.491569 libextension.dylib 0x00007fff866fa533 tearing down extension request for pid 29799
Thread 0 Crashed:: reaper Dispatch queue: com.apple.main-thread
0 com.cockos.reaper 0x00000001006dd41e ReaScript_RunDeferred() + 238
1 com.cockos.reaper 0x00000001000e067b runMiscTimers() + 1947
2 com.cockos.reaper 0x00000001000df446 Main_OnTimer(HWND__*, unsigned long) + 166
3 com.cockos.reaper 0x000000010063ba09 MainProc(HWND__*, unsigned int, unsigned long, long) + 8089
4 ??? 0x5fbfd33000000001 0 + 6899465357266780161
========================================================>
Crash Log Ending
========================================================>
Thread 0 crashed with X86 Thread State (64-bit):
rax: 0x0000000000000000 rbx: 0x000000010b188600 rcx: 0x0000000000000000 rdx: 0x0000000000000000
rdi: 0x0000000108135410 rsi: 0x0000000000000000 rbp: 0x00007fff5fbfbcc0 rsp: 0x00007fff5fbfbc70
r8: 0x000000010b1c2800 r9: 0x000000000000000a r10: 0x0000000000234200 r11: 0x0000000000000000
r12: 0x0000000000000001 r13: 0x0000000000000010 r14: 0x000000010b188608 r15: 0x00000000ffffffff
rip: 0x00000001006dd41e rfl: 0x0000000000010246 cr2: 0x0000000000000020
Logical CPU: 8
Error Code: 0x00000004
Trap Number: 14
Binary Images:
0x100000000 - 0x100ad6ff7 +com.cockos.reaper (5.96.500 - 5.96.500) <9096C7B2-2841-2A61-15BB-E7BFCA4059C4> /Volumes/VOLUME/*/ReaLiveDev.app/Contents/MacOS/REAPER
0x100dc1000 - 0x100df8fff com.apple.audio.midi.CoreMIDI (1.10 - 88) <51E79766-51D8-3A95-A7FD-18E7E11528F3>
|
|
|
02-04-2019, 06:52 AM
|
#10
|
Human being with feelings
Join Date: Jan 2013
Posts: 1,126
|
Hey CF, I was wondering if you had a second to check out my last post?
|
|
|
02-04-2019, 07:24 AM
|
#11
|
Human being with feelings
Join Date: May 2017
Location: Leipzig
Posts: 6,622
|
Which scripts do you run? We could try to recreate the crash to help the devs fixing it, if we'd know the scripts you use...
|
|
|
02-04-2019, 01:32 PM
|
#12
|
Human being with feelings
Join Date: Jan 2013
Posts: 1,126
|
Thanks for replying to this.
The scripts I'm using are here:
https://www.dropbox.com/s/h0nh637jbf...Crash.zip?dl=0
Here are my steps:
1- Start the first Script which is a window showing the current Region. This was inspired by a script XRaym Made.
2- Start Playback
3- Forcing a smooth seek to edit cursor (I have it setup to "2 bars")
4- The Seek is initiated but upon arriving to the next bar and executing CFillion's function, The whole thing crashes. You can see the data in the Cap on in one of my previous posts in this thread.
I hope somebody can help me.
Here's a screen Capture.
Last edited by lexaproductions; 02-04-2019 at 01:44 PM.
Reason: fixing the screen capture link
|
|
|
02-04-2019, 02:52 PM
|
#13
|
Human being with feelings
Join Date: May 2015
Location: Québec, Canada
Posts: 4,937
|
I've reduced it to the following steps and minimal scripts:
- Run Script A.lua:
Code:
function loop() reaper.defer(loop) end
loop()
- Run Script B.lua (with the correct command ID for Script A.lua):
Code:
reaper.defer(function()
local cmd = reaper.NamedCommandLookup("command ID of script A here")
reaper.Main_OnCommand(cmd, 0)
end)
- Select "Terminate instances"
Maybe you could message the main script to terminate itself using a temporary extstate instead of re-running it?
Last edited by cfillion; 02-04-2019 at 03:40 PM.
|
|
|
02-04-2019, 02:58 PM
|
#14
|
Human being with feelings
Join Date: Jan 2013
Posts: 1,126
|
I'm glad I'm not crazy.
Now I have to understand how to use extstate
I'll file a bug report on the Forum, thanks
|
|
|
02-04-2019, 03:08 PM
|
#15
|
Human being with feelings
Join Date: May 2015
Location: Québec, Canada
Posts: 4,937
|
Code:
function runRegionWindow()
if reaper.HasExtState('lexa_Name of the script', 'exit') then
reaper.DeleteExtState('lexa_Name of the script', 'exit', false);
return
end
-- rest of the code...
end
Code:
onNextMeasure(function()
reaper.SetExtState('lexa_Name of the script', 'exit', '', false)
end)
|
|
|
02-05-2019, 06:19 AM
|
#16
|
Human being with feelings
Join Date: Jan 2013
Posts: 1,126
|
Thanks a lot.
It works great
|
|
|
02-20-2019, 06:53 PM
|
#17
|
Human being with feelings
Join Date: Jan 2013
Posts: 1,126
|
I have to fix a small bug though.
If I terminate the script this way, then How should I re-instantiate it?
Because Now I have to instantiate it twice to restart it?
|
|
|
02-20-2019, 09:24 PM
|
#18
|
Human being with feelings
Join Date: May 2015
Location: Québec, Canada
Posts: 4,937
|
That should not be the case. Maybe the script doesn't stop when told to or the ExtState is not deleted? (More info needed)
|
|
|
02-21-2019, 06:06 AM
|
#19
|
Human being with feelings
Join Date: Jan 2013
Posts: 1,126
|
Ok Thanks for the insight. It was my mistake, As the name of the script, I only wrote
Code:
Realive_RegionWindow
but I had to prefix with "Script: " and add the extension as well.
Code:
Script: Realive_RegionWindow.lua
Now it seems to be working.
Thanks a lot for the help. I'm learning everyday slowly but surely.
|
|
|
02-22-2019, 08:20 PM
|
#20
|
Administrator
Join Date: Jan 2005
Location: NYC
Posts: 15,721
|
Quote:
Originally Posted by cfillion
I've reduced it to the following steps and minimal scripts:
- Run Script A.lua:
Code:
function loop() reaper.defer(loop) end
loop()
- Run Script B.lua (with the correct command ID for Script A.lua):
Code:
reaper.defer(function()
local cmd = reaper.NamedCommandLookup("command ID of script A here")
reaper.Main_OnCommand(cmd, 0)
end)
- Select "Terminate instances"
Maybe you could message the main script to terminate itself using a temporary extstate instead of re-running it?
|
Thanks, I think I've duplicated this and am working on a fix.
|
|
|
03-09-2019, 07:19 PM
|
#21
|
Human being with feelings
Join Date: Jan 2013
Posts: 1,126
|
Quote:
Originally Posted by cfillion
Use reaper.defer to schedule a function to be run later (~33ms). Unlike regular loops which freeze REAPER until they stop, reaper.defer allows the GUI to run in between.
[code]function onNextMeasure(callback)
local beatsSinceLastMeasure = reaper.TimeMap2_timeToBeats(0, reaper.GetPlayPosition())
if beatsSinceLastMeasure < 0.1 then
-- if we're at (or very near) the start of a measure, call the given function
callback()
else
-- or, if we're not at the start of a measure, check again ~33ms later
reaper.defer(function() onNextMeasure(callback) end)
end
end
|
Hey CFillion, I realized a bug in the function: If playback is stopped while the function in in the defer loop, it never ends as it never reaches "beatsSinceLastMeasure < 0.1"
I tried this, but it did't work:
Code:
function onNextMeasure(callback)
local beatsSinceLastMeasure = reaper.TimeMap2_timeToBeats(0, reaper.GetPlayPosition())
if playState ~= 0 then
if beatsSinceLastMeasure < 0.3 then -- if we're at (or very near) the start of a measure, call the given function
callback()
else -- or, if we're not at the start of a measure, check again ~33ms later
reaper.defer(function() onNextMeasure(callback) end)
Msg("BeatsSinceLastMeasure: "..beatsSinceLastMeasure)
end
else
callback()
end
end
Also, if I retrigger the script while the "onNextMeasure" function is in the defer loop, the loop stops thus once again never reaches the condition to execute the callback function. You have an idea for both conditions?
|
|
|
03-11-2019, 08:48 AM
|
#22
|
Human being with feelings
Join Date: May 2015
Location: Québec, Canada
Posts: 4,937
|
Quote:
Originally Posted by lexaproductions
Hey CFillion, I realized a bug in the function: If playback is stopped while the function in in the defer loop, it never ends as it never reaches "beatsSinceLastMeasure < 0.1"
|
You could check the playback state (reaper.GetPlayState()&1==0) and either do nothing or invoke the callback function when stopped.
Quote:
Originally Posted by lexaproductions
Also, if I retrigger the script while the "onNextMeasure" function is in the defer loop, the loop stops thus once again never reaches the condition to execute the callback function. You have an idea for both conditions?
|
Is this because the script is set to "Terminate instances" if launched while it's running?
|
|
|
03-11-2019, 09:18 AM
|
#23
|
Human being with feelings
Join Date: Jan 2013
Posts: 1,126
|
Quote:
Originally Posted by cfillion
You could check the playback state (reaper.GetPlayState()&1==0) and either do nothing or invoke the callback function when stopped.
|
Well that's what I tried to do but if you can see in my last example, the way I did it does not work...
Quote:
Originally Posted by cfillion
Is this because the script is set to "Terminate instances" if launched while it's running?
|
I believe so. But I can't find where to reset it. Where do we change the Terminate instances settings?
|
|
|
03-11-2019, 09:25 AM
|
#24
|
Human being with feelings
Join Date: May 2015
Location: Québec, Canada
Posts: 4,937
|
Quote:
Originally Posted by lexaproductions
Well that's what I tried to do but if you can see in my last example, the way I did it does not work...
|
The playState variable does not appear to be defined (or if it is elsewhere in the script, it's not being updated in the loop).
Code:
function onNextMeasure(callback)
local beatsSinceLastMeasure = reaper.TimeMap2_timeToBeats(0, reaper.GetPlayPosition())
if beatsSinceLastMeasure < 0.1 then
-- if we're at (or very near) the start of a measure, call the given function
callback()
else if reaper.GetPlayState()&1 == 1 -- only if the project is playing
-- or, if we're not at the start of a measure, check again ~33ms later
reaper.defer(function() onNextMeasure(callback) end)
end
end
onNextMeasure(function()
-- code to run at the next measure here
reaper.ShowConsoleMsg("Hello Next Measure!\n")
end)
Quote:
Originally Posted by lexaproductions
I believe so. But I can't find where to reset it. Where do we change the Terminate instances settings?
|
Remove and re-import the script in the action list.
|
|
|
03-11-2019, 09:51 AM
|
#25
|
Human being with feelings
Join Date: Jan 2013
Posts: 1,126
|
playState is defined elsewhere. From what I can tell it works. I'll investigate thanks
|
|
|
03-11-2019, 02:18 PM
|
#26
|
Human being with feelings
Join Date: Jan 2013
Posts: 1,126
|
Quote:
Originally Posted by cfillion
You could check the playback state (reaper.GetPlayState()&1==0) and either do nothing or invoke the callback function when stopped.
Is this because the script is set to "Terminate instances" if launched while it's running?
|
Yes it seems to be. But I have no other choice then set it to "Terminate instances" no?
|
|
|
10-07-2020, 07:11 AM
|
#27
|
Human being with feelings
Join Date: Jan 2013
Posts: 1,126
|
Bringing back this function as I always wanted to make this more precise and simpler,
I came up with this. CFillion, what do you think?
Code:
function on_NextMeasure(outfunction, timingAdjust)
local _,curBar = reaper.TimeMap2_timeToBeats(0, reaper.GetPlayPosition())
-- Polling loop function
local function on_NextMeasure_Loop(outfunction, timingAdjust)
if reaper.GetPlayState() == 0 then return end -- if stopped while running abort without doing anything.
for i = 0, 10000 do -- to poll at 0.03ms precision
local _, msr = reaper.TimeMap2_timeToBeats(0, reaper.GetPlayPosition()+timingAdjust) -- added 100ms as timing adjust
if curBar ~= msr then -- if the measure number changed...
outfunction()
return
end
end
reaper.defer(function() on_NextMeasure_Loop(outfunction, timingAdjust) end)
end
-- Call polling loop function
on_NextMeasure_Loop(outfunction, timingAdjust)
end
|
|
|
10-07-2020, 08:03 AM
|
#28
|
Human being with feelings
Join Date: May 2015
Location: Québec, Canada
Posts: 4,937
|
Code:
for i = 0, 10000 do
reaper.GetPlayPosition() remains the same for all 10,001 iterations (because it freezes the main thread).
|
|
|
10-07-2020, 09:51 AM
|
#29
|
Human being with feelings
Join Date: May 2017
Location: Leipzig
Posts: 6,622
|
Quote:
Originally Posted by lexaproductions
Bringing back this function as I always wanted to make this more precise and simpler,
I came up with this. CFillion, what do you think?
Code:
function on_NextMeasure(outfunction, timingAdjust)
local _,curBar = reaper.TimeMap2_timeToBeats(0, reaper.GetPlayPosition())
-- Polling loop function
local function on_NextMeasure_Loop(outfunction, timingAdjust)
if reaper.GetPlayState() == 0 then return end -- if stopped while running abort without doing anything.
for i = 0, 10000 do -- to poll at 0.03ms precision
local _, msr = reaper.TimeMap2_timeToBeats(0, reaper.GetPlayPosition()+timingAdjust) -- added 100ms as timing adjust
if curBar ~= msr then -- if the measure number changed...
outfunction()
return
end
end
reaper.defer(function() on_NextMeasure_Loop(outfunction, timingAdjust) end)
end
-- Call polling loop function
on_NextMeasure_Loop(outfunction, timingAdjust)
end
|
All Get-functions of Reaper update their states only when
a) you changed the state programmatically
b) at start of a script
c) at the beginning of each defer-cycle
So defer is still your only option.
But that does not prevent you from having greater precision.
Usually deferred function are run about 30 times per second. Now here's the thing: you can have multiple deferred functions in one script.
The next example will run about 30/second:
Code:
A=0
function main()
A=A+1
reaper.ClearConsole()
reaper.ShowConsoleMsg(A)
reaper.defer(main)
end
main()
It will count up the global variable A with each defer-cycle and show it in the console.
Now, let's see, what happens when we start main() twice:
Code:
A=0
function main()
A=A+1
reaper.ClearConsole()
reaper.ShowConsoleMsg(A)
reaper.defer(main)
end
main()
main() -- let's start it another time
You will see, it will count up not only 30 times/second but 60 times/second.
You can go on with it. Start main() three times and it will count up 90 times per second.
The reason is, because you started main(which is deferred) three times, Reaper runs main as three instances as deferred. Each main() is looped as its own instance, who can access the global variable A and therefor count up with each loop.
You can run main() a fourth time and Reaper will fun four instances of main as deferred, and so on.
The great thing about this is, that you can speed up things that way. Usually you could only do it 30times/second but by running multiple instances of the deferred main-function, you can have (number_of_main_instance*30times)/second-iterations.
AND, as I pointed out earlier: the get-functions of Reaper will be updated with each defer-cycle which means: you can get the current time-position more often than only 30/second with this approach.
So let's modify the code from above to do that:
Code:
function main()
playposition=reaper.GetPlayPosition()
reaper.ShowConsoleMsg(playposition.."\n")
reaper.defer(main)
end
main()
This will show the current playposition in the console. It will update it 30 time/second.
Code:
function main()
playposition=reaper.GetPlayPosition()
reaper.ShowConsoleMsg(playposition.."\n")
reaper.defer(main)
end
main()
main() -- run the main-function as a second defer-instance
When we run main two times, the console will show the playposition 60 times/second. And each one shown will be different and not block Reaper's GUI(unlike your democode that tried to achieve this with a for-loop).
You can run the main-loop for 1024-times and create therefor 1024 instances of the function. Though I think, running main() 10 times should be enough precision, with 300 times per second, as more instances may eat too many resources slowing down the instances at some point. So test out the balance between number of defer-main()-instances running vs needed computing resources.
Rule of thumb: if you have the feeling of Reaper's GUI becoming sluggish, laggy or not precisely reacting, you should start fewer instances of your check-function.
That being said: try to solve it as a defer-looped-function and then run this defer-function multiple times and you'll get greater check-precision.
Last edited by Meo-Ada Mespotine; 10-07-2020 at 09:56 AM.
|
|
|
10-07-2020, 10:16 AM
|
#30
|
Human being with feelings
Join Date: May 2015
Location: Québec, Canada
Posts: 4,937
|
Deferred functions are run from the same global timer no matter how many of them are queued. It does not increase resolution.
Code:
i = 0
t = reaper.time_precise()
function callback()
i = i + 1
new_t = reaper.time_precise()
diff = new_t - t
t = new_t
reaper.ShowConsoleMsg(string.format('%fms since the previous call\n', diff * 1000))
if i <= 3*3 then
reaper.defer(callback)
end
end
reaper.defer(callback)
reaper.defer(callback)
reaper.defer(callback)
Code:
23.468971ms since the previous call
0.524998ms since the previous call
0.306129ms since the previous call
29.727936ms since the previous call
0.660896ms since the previous call
0.554085ms since the previous call
28.505087ms since the previous call
0.995874ms since the previous call
0.833035ms since the previous call
28.582096ms since the previous call
1.338005ms since the previous call
1.116991ms since the previous call
Last edited by cfillion; 10-07-2020 at 10:29 AM.
|
|
|
10-07-2020, 10:38 AM
|
#31
|
Human being with feelings
Join Date: May 2017
Location: Leipzig
Posts: 6,622
|
I'm not sure, how your benchmark-function is supposed to work, but I think that reaper.time_precise() is not a good example, as this function is the only one that gets updated all the time, even during script-run.
To see the effect, you would need to take a function, that gets only updated with each defer-cycle, like GetPlayPosition or something like that.
Edit: I have multiple features in Ultraschall-API working with this effect circumventing the Gui-block-problem.
Edit2: I think I forgot to mention another thing: the first run of the (not yet deferred)-main-function will NOT benefit from it.
The precision will only benefit from the first time it has been deferred(second run onward).
This could maybe explain some of the effects shown in your code, that is probably influenced by the stop-variable i.
Last edited by Meo-Ada Mespotine; 10-07-2020 at 10:51 AM.
|
|
|
10-07-2020, 10:49 AM
|
#32
|
Human being with feelings
Join Date: May 2015
Location: Québec, Canada
Posts: 4,937
|
It was meant to demonstrate that all calls to reaper.defer go into the same queue served by a single global timer, which then executes all of them synchronously (so the main thread cannot update in-between).
With GetPlayPosition:
Code:
33.976854
33.976854
33.976854
34.008854
34.008854
34.008854
34.040854
34.040854
34.040854
34.072854
34.072854
34.072854
34.104854
34.104854
34.104854
In other words, these two blocks are equivalent:
Code:
reaper.defer(callback)
reaper.defer(callback)
reaper.defer(callback)
reaper.defer(function()
callback()
callback()
callback()
end)
Last edited by cfillion; 10-07-2020 at 10:56 AM.
|
|
|
10-07-2020, 10:52 AM
|
#33
|
Human being with feelings
Join Date: May 2017
Location: Leipzig
Posts: 6,622
|
Just in case, this got swept under:
Quote:
Originally Posted by Meo-Ada Mespotine
Edit2: I think I forgot to mention another thing: the first run of the (not yet deferred)-main-function will NOT benefit from it.
The precision will only benefit from the first time it has been deferred(second run onward).
This could maybe explain some of the effects shown in your code, that is probably influenced by the stop-variable i.
|
It's so normal to me, that I simply forgot to mention that...
|
|
|
10-07-2020, 11:03 AM
|
#34
|
Human being with feelings
Join Date: May 2017
Location: Leipzig
Posts: 6,622
|
@cfillion
Ok, I can confirm you're right.
Code:
reaper.ClearConsole()
OldPos=0
A=0
NumberOfInstances_and_WaitTilShowing=5
function main()
A=A+1
local NewPos=reaper.GetPlayPosition()
if A>NumberOfInstances_and_WaitTilShowing then
reaper.ShowConsoleMsg(NewPos.."\n")
end
OldPos=NewPos
if A<NumberOfInstances_and_WaitTilShowing*120 then
reaper.defer(main)
end
end
for i=1, NumberOfInstances_and_WaitTilShowing do
main()
end
If my assumption would be correct, every shown time would be different, but instead is shown NumberOfInstances_and_WaitTilShowing -times (in this code 5 times).
So it seems like Reaper updates its states only after every "full-gui-and-defer-script-turnaround", while it seems to be more flexible in other regards(Lua's file-io for instance).
Thnx for pointing this out...
@lexaproductions
I was wrong, no greater precision possible. I wonder, if using gmem being fed by a JSFX could be a possible workaround, but this would be hacky if at all possible.
|
|
|
10-07-2020, 01:58 PM
|
#35
|
Human being with feelings
Join Date: Jan 2013
Posts: 1,126
|
Thanks fro taking the time to answer my questions guys. I really appreciate it.
I could've sworn using this function felt tighter. Might be placebo effect hehe.
Back to the drawing board.
|
|
|
10-07-2020, 03:57 PM
|
#36
|
Human being with feelings
Join Date: Jan 2013
Posts: 1,126
|
But hearing you guys talk about
still being updated would that work?
Code:
function on_NextMeasure(outfunction)
local timingAdjust = 0
local _, msr = reaper.TimeMap2_timeToBeats(0, reaper.GetPlayPosition())
local barSt, barEnd = reaper.TimeMap_GetMeasureInfo(0, msr)
local barEnd_precise = barEnd-position+reaper.time_precise()
local _,curBar = reaper.TimeMap2_timeToBeats(0, reaper.GetPlayPosition())
-- Polling loop function
local function on_NextMeasure_Loop(outfunction, timingAdjust)
if reaper.GetPlayState() == 0 then return end -- if stopped while running abort without doing anything.
for i = 0, 10 do
local t = reaper.time_precise()
if t >=barEnd_precise then -- if the measure number changed...
outfunction()
return
end
end
reaper.defer(function() on_NextMeasure_Loop(outfunction, timingAdjust) end)
end
-- Call polling loop function
on_NextMeasure_Loop(outfunction, timingAdjust)
end
|
|
|
10-07-2020, 05:37 PM
|
#37
|
Human being with feelings
Join Date: May 2017
Location: Leipzig
Posts: 6,622
|
Quote:
Originally Posted by lexaproductions
But hearing you guys
|
...and girls
Quote:
talk about
still being updated would that work?
Code:
function on_NextMeasure(outfunction)
local timingAdjust = 0
local _, msr = reaper.TimeMap2_timeToBeats(0, reaper.GetPlayPosition())
local barSt, barEnd = reaper.TimeMap_GetMeasureInfo(0, msr)
local barEnd_precise = barEnd-position+reaper.time_precise()
local _,curBar = reaper.TimeMap2_timeToBeats(0, reaper.GetPlayPosition())
-- Polling loop function
local function on_NextMeasure_Loop(outfunction, timingAdjust)
if reaper.GetPlayState() == 0 then return end -- if stopped while running abort without doing anything.
for i = 0, 10 do
local t = reaper.time_precise()
if t >=barEnd_precise then -- if the measure number changed...
outfunction()
return
end
end
reaper.defer(function() on_NextMeasure_Loop(outfunction, timingAdjust) end)
end
-- Call polling loop function
on_NextMeasure_Loop(outfunction, timingAdjust)
end
|
No, as the other Api-functions still don't return updated values. And for-loops always block Reaper's Gui after some time, no matter what. Time_precise will not be helpful for your needs.
|
|
|
10-07-2020, 07:51 PM
|
#38
|
Human being with feelings
Join Date: Jan 2013
Posts: 1,126
|
Quote:
Originally Posted by Meo-Ada Mespotine
...and girls
|
Thanks Miss.
|
|
|
Thread Tools |
|
Display Modes |
Linear Mode
|
Posting Rules
|
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
HTML code is Off
|
|
|
All times are GMT -7. The time now is 06:50 AM.
|