mirror of
https://github.com/koreader/koreader
synced 2024-10-31 21:20:20 +00:00
abba7ba873
In principle, any negative subtraction result should be caused by a logical error.
159 lines
3.5 KiB
Lua
159 lines
3.5 KiB
Lua
--[[--
|
|
A simple module to module to compare and do arithmetic with time values.
|
|
|
|
@usage
|
|
local TimeVal = require("ui/timeval")
|
|
|
|
local tv_start = TimeVal:now()
|
|
-- Do some stuff.
|
|
-- You can add and subtract `TimeVal` objects.
|
|
local tv_duration = TimeVal:now() - tv_start
|
|
-- If you need more precision (like 2.5 s),
|
|
-- you can add the milliseconds to the seconds.
|
|
local tv_duration_seconds_float = tv_duration.sec + tv_duration.usec/1000000
|
|
]]
|
|
|
|
local dbg = require("dbg")
|
|
local util = require("ffi/util")
|
|
|
|
--[[--
|
|
TimeVal object.
|
|
|
|
@table TimeVal
|
|
@int sec floored number of seconds
|
|
@int usec remaining number of milliseconds
|
|
]]
|
|
local TimeVal = {
|
|
sec = 0,
|
|
usec = 0,
|
|
}
|
|
|
|
--[[--
|
|
Creates a new TimeVal object.
|
|
|
|
@usage
|
|
local timev = TimeVal:new{
|
|
sec = 10,
|
|
usec = 10000,
|
|
}
|
|
|
|
@treturn TimeVal
|
|
]]
|
|
function TimeVal:new(from_o)
|
|
local o = from_o or {}
|
|
if o.sec == nil then
|
|
o.sec = 0
|
|
end
|
|
if o.usec == nil then
|
|
o.usec = 0
|
|
elseif o.usec > 1000000 then
|
|
o.sec = o.sec + math.floor(o.usec/1000000)
|
|
o.usec = o.usec % 1000000
|
|
end
|
|
setmetatable(o, self)
|
|
self.__index = self
|
|
return o
|
|
end
|
|
|
|
|
|
function TimeVal:__lt(time_b)
|
|
if self.sec < time_b.sec then
|
|
return true
|
|
elseif self.sec > time_b.sec then
|
|
return false
|
|
else
|
|
-- self.sec == time_b.sec
|
|
if self.usec < time_b.usec then
|
|
return true
|
|
else
|
|
return false
|
|
end
|
|
end
|
|
end
|
|
|
|
function TimeVal:__le(time_b)
|
|
if self.sec < time_b.sec then
|
|
return true
|
|
elseif self.sec > time_b.sec then
|
|
return false
|
|
else
|
|
-- self.sec == time_b.sec
|
|
if self.usec > time_b.usec then
|
|
return false
|
|
else
|
|
return true
|
|
end
|
|
end
|
|
end
|
|
|
|
function TimeVal:__eq(time_b)
|
|
if self.sec == time_b.sec and self.usec == time_b.usec then
|
|
return true
|
|
else
|
|
return false
|
|
end
|
|
end
|
|
|
|
function TimeVal:__sub(time_b)
|
|
local diff = TimeVal:new{}
|
|
|
|
diff.sec = self.sec - time_b.sec
|
|
diff.usec = self.usec - time_b.usec
|
|
|
|
if diff.sec < 0 and diff.usec > 0 then
|
|
diff.sec = diff.sec + 1
|
|
diff.usec = diff.usec - 1000000
|
|
elseif diff.sec > 0 and diff.usec < 0 then
|
|
diff.sec = diff.sec - 1
|
|
diff.usec = diff.usec + 1000000
|
|
end
|
|
|
|
return diff
|
|
end
|
|
|
|
dbg:guard(TimeVal, '__sub',
|
|
function(self, time_b)
|
|
assert(self.sec > time_b.sec or (self.sec == time_b.sec and self.usec >= time_b.usec),
|
|
"Subtract the first timeval from the latest, not vice versa.")
|
|
end)
|
|
|
|
function TimeVal:__add(time_b)
|
|
local sum = TimeVal:new{}
|
|
|
|
sum.sec = self.sec + time_b.sec
|
|
sum.usec = self.usec + time_b.usec
|
|
if sum.usec > 1000000 then
|
|
sum.usec = sum.usec - 1000000
|
|
sum.sec = sum.sec + 1
|
|
end
|
|
|
|
if sum.sec < 0 and sum.usec > 0 then
|
|
sum.sec = sum.sec + 1
|
|
sum.usec = sum.usec - 1000000
|
|
elseif sum.sec > 0 and sum.usec < 0 then
|
|
sum.sec = sum.sec - 1
|
|
sum.usec = sum.usec + 1000000
|
|
end
|
|
|
|
return sum
|
|
end
|
|
|
|
--[[--
|
|
Creates a new TimeVal object based on the current time.
|
|
|
|
@usage
|
|
local TimeVal = require("ui/timeval")
|
|
local tv_start = TimeVal:now()
|
|
-- Do some stuff.
|
|
-- You can add and substract `TimeVal` objects.
|
|
local tv_duration = TimeVal:now() - tv_start
|
|
|
|
@treturn TimeVal
|
|
]]
|
|
function TimeVal:now()
|
|
local sec, usec = util.gettime()
|
|
return TimeVal:new{sec = sec, usec = usec}
|
|
end
|
|
|
|
return TimeVal
|