I’d like to have an event happening every 1/4 second. os.time turns over once a second. os.clock is subsecond but is described as “CPU time”. Is it that, or is it elapsed time? If it’s CPU time, is the a way to get wall clock fractional seconds?
Thanks!
@RonJeffries Use tween delay to execute a function every .25 seconds.
viewer.mode=STANDARD
function setup()
start=true
count=0
end
function draw()
background(0)
if start then
start=false
count=count+1
tween.delay(.25,run)
end
end
function run()
print(count)
start=true
end
@dave1707 That’s not 1/4s on the wall clock though. That’s every 1/4s since the program started, and it will also gradually drift as it runs at it has to wait for the next frame before updating.
@RonJeffries If I’ve understood you correctly, here’s some code that I have to achieve that end. It combines os.date()
, which is wall time accurate to the second, with ElapsedTime
, which is millisecond accurate but counts since the start of the program.
Basically, we try to get an accurate reading on ElapsedTime
when os.date()
clicks over from one second to the next. This then allows us to use ElapsedTime
to calculate the current millisecond reading and thus provide an accurate timestamp.
The difficulty is that we can only examine our “clocks” each frame. This makes it complicated as we can’t tell exactly when os.date()
clicks over from one second to the next.
I actually wrote this up for the Big Lockdown Math-Off (scroll down half way, also ignore the results of the vote!).
Here’s the code. We want to note the exact ElapsedTime
when os.date()
ticks over from one second to the next. All we can actually say is that it happened between one frame and the next which gives us an upper and lower limit on the millisecond reading. By continually readjusting, we can zero in on the actual reading.
Here’s some code:
local __l = 0
local __h = 1
local __psec
local __pet
function Now()
local t = os.date("*t")
local et = ElapsedTime
if __psec ~= nil and t.sec ~= __psec then
local a,b = __pet - math.floor(__pet), et - math.floor(__pet)
if b - a < .5 then
if __l + 1 < b then
a,b = a-1, b-1
end
__l = math.max(__l,a)
__h = math.max(__h,b)
end
end
lower = __l
higher = __h
__pet = et
__psec = t.sec
et = et - (__l + __h)/2
local time = {}
time.msec = (et - math.floor(et))*1000
time.sec = t.sec
time.min = t.min
time.hour = t.hour
time.yday = t.yday
return time
end
@LoopSpace Looking at the first post, @RonJeffries didn’t say how exact he wanted it to be over a long of a period of time. That’s why I just chose tween delay. If it needs to be almost exact over a long period (according to the wall clock), I think this code will work. It uses the socket “gettime” function which I think is pretty accurate to several decimal places.
The time interval can be changed in the call to checkDuration(). This code prints the gettime every .25 seconds.
viewer.mode=STANDARD
function setup()
s=require("socket")
st=s:gettime()
c=0
end
function draw()
background(0)
checkDuration(.25)
end
function checkDuration(d)
local i=s:gettime()-st
if i>c then
c=c+d
xx()
end
end
function xx()
print(s:gettime())
end
and i completely forgot ElapsedTime, which really ought to be mentioned in the time tab of the docs. 
@LoopSpace neat … far more than i needed. and res, @dave1707, maybe tween delay will be better. thanks for reminder. i think my head was empty today.
ElapsedTime isn’t that reliable if the FPS starts to drop. Here’s an example. Slide the slider and see what happens to the ElapsedTime that’s displayed.
viewer.mode=STANDARD
function setup()
parameter.integer("delay",1,10000)
end
function draw()
background(0)
for z=1,delay*10000 do
a=math.sqrt(z)
end
text(ElapsedTime,WIDTH/2,HEIGHT/2)
end
hm, weird. tweens are easy enough, i guess i’ll go that way.
Here’s an example of executing different functions at different time intervals.
viewer.mode=STANDARD
function setup()
t1=checkDelay(.3)
t2=checkDelay(.5)
t3=checkDelay(1)
end
function draw()
background(0)
if t1:test() then
print(".3 ",t1.s:gettime())
end
if t2:test() then
print(".5 ",t2.s:gettime())
end
if t3:test() then
print("1.0 ",t3.s:gettime())
end
end
checkDelay=class()
function checkDelay:init(int)
self.s=require("socket")
self.start=self.s:gettime()
self.val=0
self.interval=int
end
function checkDelay:test()
if self.s:gettime()-self.start>self.val then
self.val=self.val+self.interval
return true
end
return false
end