Passing a delay of 0 to LLTimers:every is allowed, but weird
in progress
Frio Belmonte
Feels like a bit of a pitfall to begin with: we used to turn timers off with delay 0, not that there is any reason not to interpret delay 0 as "call the timer as soon as possible" but it's not consistent with the old logic.
However, it also does not work properly: try this script:
local count = 0
local stime = 0
function timer()
count += 1
ll.SetLinkPrimitiveParamsFast(LINK_THIS, {PRIM_TEXT, tostring(count), vector(1, 1, 1), 1})
if count >= 100 then -- never reached at 0.0 delay, will be reached at 0.001
ll.OwnerSay(`finished in {os.clock()-stime} s`)
LLTimers:off(timer)
end
end
function LLEvents.touch_start() -- disable this event and the count reaches higher, but not 100
ll.OwnerSay(`current count = {count}`)
end
stime = os.clock()
-- set delay to 0.001 (or anything sub-server frame) to have functional
-- "call as soon as possible" rate
LLTimers:every(0.0, timer)
The count will never reach 100 and terminate in my tests, it's like the timer gets jammed. Using a delay of 0.001 (or anything > 0 but sub-frame) will achieve the expected "as soon as possible" timing. Also disabling the touch event lets the timer count higher (still not 100), so there's some dependency on the event system on the whole there.
Log In
H
Harold Linden
marked this post as
in progress
Thanks for sending this in! If I had to guess, the scheduler in the simulator _really_ doesn't like work getting scheduled for the _current_ frame rather than a later one. I'll force it to execute on the next server frame for now until I can fix things, as LSL will always punt to a later server frame, even if that's not desirable.
H
Harold Linden
Also I had a division by zero in the multitimer scheduler, so that didn't help things... We'll have a fix for this in an upcoming server release, thanks again!
WolfGang Senizen
I think it might be nice to have an
LLTimers:immediate(...)
as an alias for
LLTimers:once(0,...)
And raise an error if you try and set a timer through
once
or every
for 0
in general, as 0
is not actually possible anyway.H
Harold Linden
WolfGang Senizen: JS used to have that in the form of
setImmediate(...)
but it was done away with and setTimeout(0, ...)
is now recommended. I'm trying to stay roughly symmetrical with what more popular APIs doSuzannaLinn Resident
Some more testing with it, in this case it counts to 79, the timer seems to be still in place but not timing:
timing = (function()
local count = 0
return function(expected, interval)
count += 1
print(count, expected, interval, ll.GetTime())
end
end)()
LLEvents:on("touch_start", function()
print(table.concat(LLEvents:eventNames(),", "))
print(LLTimers)
end)
LLTimers:every(0, timing)
-- >
1 0.0006240000000161672 0 0.2891920000000141
.....
79 0.0006240000000161672 0 2.022262000000012
[touching]
-- > touch_start, timer
-- > LLTimers{timers=1}
----------
Adding another timer when touching makes it worse:
timing = (function()
local count = 0
return function(expected, interval)
count += 1
print(count, expected, interval, ll.GetTime())
end
end)()
LLEvents:on("touch_start", function()
print(table.concat(LLEvents:eventNames(),", "))
print(LLTimers)
LLTimers:every(1, timing) -- added line
end)
LLTimers:every(0, timing)
(same printing than before)
(no print from timer 1 second)
["Reset" the script in the editor]
(nothing)
After about 30 seconds it logs me out and when I log back in the box with the script has disappeared.