Unfortunately Codea’s version of Lua uses 32 bit floats for numbers. So the unix epoch, which is a 32 bit integer, is being converted into a 32 bit float. There’s not enough bits to display a float representation of an integer that large. I’m not too sure how to fix this. What application did you have in mind?
I’ve noticed some strange behavior as well using Lua’s os.time and os.difftime functions. For instance, to get the timing to work correctly, I had to actively print the time to the consol, if I didn’t, it wouldn’t work. Was pretty weird, if I get some time I’ll try to reproduce it.
I ended up using Codea’s EllapsedTime function, it works well. Ended up using it to modify the default frame rate of the draw function.
@jlslate If your message was directed at my comment on modifying the frame rate, I’ll describe the process I used. The idea was pretty simple, after a touch was registered, I wanted the draw() function to wait about 0.1-0.2 seconds before updating the object I was moving. If I didn’t wait, because the draw() function implicitly redraws the scene at about 60 fps, the object would move extremely fast for very short touch input periods. So all I had to do was wrap the code I wanted to “slow down” in an if statement that compared a change in some time to my target (approximately 0.1 seconds). The idea is this:
function setup()
t = 0.1
t1 = 0
end
function draw()
t2 = ElapsedTime
dt = t2 - t1
if dt > t then
code you want to "slow down"
t1 = ElapsedTime
end
end
@traviscarrigan - yes, that was directed at you. Thanks for the code. I’m still trying to figure out the best way to implement the ability to emulate a wait statement in Codea. I have something currently, but I am always looking for something better.
The string of os.date() doesn’t loose anything. This is also true for when it is parsed by “*t”.
This isn’t a complete solution but it can give you the seconds since midnight.
If you compare the seconds since midnight, day of the year, and the year you can do most comparisons. Daylight savings and leap years get a bit strange which is why epoch was created.
Side note, my birthday is a negative number in epoch. Yes, I older than time itself, at least according to UNIX and variants.
@Simeon thank you for the explanation! Thanks too to @traviscarrigan and @Ipda41001 for the code examples.
A while back I coded a “days alive calculator” in Codea subtracting os.time() from os.time() with a parameter table containing a birth date and then dividing the result by 86400 (number of secs in a day) and had no trouble – but for this I was only concerned with having the correct number of days…
What application did you have in mind?
Timers! Hundreds of them! That are saved and recalled for the periods when the app isn’t running.
Actually it is only a vague idea which I first caught a glimpse of while learning about closures and finding I could store os.time() in the non-local variable (at least in iLuaBox which I often use as a sort of scratch pad)…
Daylight savings and leap years get a bit strange which is why epoch was created.
Ah ha. Good to know. So hopefully one day @Simeon will think of a fix for this but in the meantime I’ll try to do a work-around using os.date().
lnum is compatible with lua 5.1.4, but not with 5.2.
5.2 is not quite backwards compatible with 5.1, btw., so stuff written for the current version of codea might not work with a version using 5.2. 5.1 will be around for quite a while longer, considering that luajit is 5.1 only and Mike has not stated any intention to change that, so apart from goto and yieldable pcalls, which nobody here uses anyway there is probably no real reason to upgrade to 5.2.
@jlslate, I have a timer class which I used in the pacman game, implemented using DeltaTime. In pacman various behaviors where triggered after a fixed amount of time (For example, whether ghosts scatter or chase pacman). I’ll see if I can extract the timer class out of that code and post here.
I have one as well in my user interface class, amd also on playlist class. If you look at my codea videos on youtube (won’t give me a link to cut and paste - search for codea and pendulum) then those are done with playlists comtrolled by timers.
function setup()
clock = Clock()
clock:add(2,soundTest,SOUND_BLIT,15)
clock:add(4,soundTest,SOUND_EXPLODE,20)
clock:addPeriodic(.5,1,soundTest,SOUND_HIT,50)
end
function soundTest(type,seed)
sound(type,seed)
end
function draw()
clock:run()
end
-- Clock class definition
Clock = class()
function Clock:init()
self.time = 0
self.callbacks = {}
end
function Clock:add(t,func,...)
table.insert(self.callbacks,{func=func,t=t,args=arg})
end
function Clock:addPeriodic(t,period,func,...)
table.insert(self.callbacks,{func=func,t=t,period=period,args=arg})
end
function Clock:run()
local finalTime = self.time + DeltaTime
while true do
-- find the least timer
local minT = finalTime
local minIdx = nil
for idx,timer in ipairs(self.callbacks) do
if timer.t < minT then
minT = timer.t
minIdx = idx
end
end
if not minIdx then
self.time = finalTime
break
end
self.time = minT
-- execute
local t = self.callbacks[minIdx]
t.func(unpack(t.args))
if t.period then t.t = t.t + t.period
else table.remove(self.callbacks,minIdx) end
end
end
I spent a few hours last night trying to kludge together a ‘closed’ timer function using os.date() instead of os.time() but the affair became rather messy… Eventually I gave up (for the time being…) when I discovered I couldn’t successfully serialize/store the up-value (which was the point of the exercise) using string.dump.
@Simeon should I file a request for a fix for os.time() on the wiki?
Put it on the issue tracker, but I’m not sure how much we can do about it.
It comes down to this: better arithmetic performance, or os.time() working properly.
I would take better performance. From what I’ve read, the iPad’s Cortex-A8 CPU performs best with single-precision floating point numbers, as it can use the NEON unit instead of the VFP.
How about a separate timer that only works in the 24-bit range? From what I saw, DeltaTime and ElapsedTime are only updated whenever draw is called, I also have wanted a timer, mainly for benchmarking purposes… make it a simple thing, just a userdata with 3 methods, start(), stop() and current(), and maybe a way to determine wether it wrapped. Resolution in 1/100th of a second range would be ok for me.
Thanks @Simeon. I understand the trade-off (though the specifics are way over my head…) and totally agree concerning the choice for performance.
May I suggest at least changing the documentation to reflect the fact that the results of os.time() and os.difftime() are somewhat limited in the current Codea implementation? And perhaps what those limits are?
In my own limited testing I find I can use os.time() to return the number of hours since the epoch by dividing by 3600 but minutes and, obviously, seconds, fail.