2014-12-06 16:44:04 +01:00
|
|
|
---------------------------------------------------------------------------
|
2015-02-20 15:45:53 +01:00
|
|
|
--- Timer objects and functions.
|
|
|
|
--
|
2014-12-06 16:44:04 +01:00
|
|
|
-- @author Uli Schlachter
|
|
|
|
-- @copyright 2014 Uli Schlachter
|
|
|
|
-- @release @AWESOME_VERSION@
|
2015-02-20 15:45:53 +01:00
|
|
|
-- @module gears.timer
|
2014-12-06 16:44:04 +01:00
|
|
|
---------------------------------------------------------------------------
|
|
|
|
|
2015-01-11 10:58:49 +01:00
|
|
|
local capi = { awesome = awesome }
|
|
|
|
local ipairs = ipairs
|
2014-12-06 16:44:04 +01:00
|
|
|
local pairs = pairs
|
2015-01-11 10:58:49 +01:00
|
|
|
local setmetatable = setmetatable
|
|
|
|
local table = table
|
2014-12-06 16:44:04 +01:00
|
|
|
local tonumber = tonumber
|
|
|
|
local traceback = debug.traceback
|
2015-01-11 10:58:49 +01:00
|
|
|
local unpack = unpack or table.unpack -- v5.1: unpack, v5.2: table.unpack
|
2014-12-06 16:44:04 +01:00
|
|
|
local glib = require("lgi").GLib
|
|
|
|
local object = require("gears.object")
|
|
|
|
|
|
|
|
--- Timer objects. This type of object is useful when triggering events repeatedly.
|
|
|
|
-- The timer will emit the "timeout" signal every N seconds, N being the timeout
|
|
|
|
-- value.
|
2015-02-15 22:26:47 +01:00
|
|
|
-- @tfield number timeout Interval in seconds to emit the timeout signal.
|
|
|
|
-- Can be any value, including floating point ones
|
|
|
|
-- (e.g. 1.5 seconds).
|
|
|
|
-- @tfield boolean started Read-only boolean field indicating if the timer has been
|
|
|
|
-- started.
|
|
|
|
-- @table timer
|
2014-12-06 16:44:04 +01:00
|
|
|
|
|
|
|
local timer = { mt = {} }
|
|
|
|
|
|
|
|
--- Start the timer.
|
|
|
|
function timer:start()
|
|
|
|
if self.data.source_id ~= nil then
|
|
|
|
print(traceback("timer already started"))
|
|
|
|
return
|
|
|
|
end
|
|
|
|
self.data.source_id = glib.timeout_add(glib.PRIORITY_DEFAULT, self.data.timeout * 1000, function()
|
2015-07-13 21:19:15 +02:00
|
|
|
local success, message = xpcall(function()
|
|
|
|
self:emit_signal("timeout")
|
|
|
|
end, function(err)
|
|
|
|
print(debug.traceback("Error during executing timeout handler: "..tostring(err)))
|
|
|
|
end)
|
2014-12-06 16:44:04 +01:00
|
|
|
return true
|
|
|
|
end)
|
|
|
|
end
|
|
|
|
|
|
|
|
--- Stop the timer.
|
|
|
|
function timer:stop()
|
|
|
|
if self.data.source_id == nil then
|
|
|
|
print(traceback("timer not started"))
|
|
|
|
return
|
|
|
|
end
|
|
|
|
glib.source_remove(self.data.source_id)
|
|
|
|
self.data.source_id = nil
|
|
|
|
end
|
|
|
|
|
|
|
|
--- Restart the timer.
|
|
|
|
function timer:again()
|
|
|
|
if self.data.source_id ~= nil then
|
|
|
|
self:stop()
|
|
|
|
end
|
|
|
|
self:start()
|
|
|
|
end
|
|
|
|
|
|
|
|
local timer_instance_mt = {
|
|
|
|
__index = function(self, property)
|
|
|
|
if property == "timeout" then
|
|
|
|
return self.data.timeout
|
|
|
|
elseif property == "started" then
|
|
|
|
return self.data.source_id ~= nil
|
|
|
|
end
|
|
|
|
|
|
|
|
return timer[property]
|
|
|
|
end,
|
|
|
|
|
|
|
|
__newindex = function(self, property, value)
|
|
|
|
if property == "timeout" then
|
|
|
|
self.data.timeout = tonumber(value)
|
|
|
|
self:emit_signal("property::timeout")
|
|
|
|
end
|
|
|
|
end
|
|
|
|
}
|
|
|
|
|
2015-02-15 22:26:47 +01:00
|
|
|
--- Create a new timer object.
|
|
|
|
-- @tparam table args Arguments.
|
|
|
|
-- @tparam number args.timeout Timeout in seconds (e.g. 1.5).
|
|
|
|
-- @treturn timer
|
|
|
|
timer.new = function(args)
|
2014-12-06 16:44:04 +01:00
|
|
|
local ret = object()
|
|
|
|
|
|
|
|
ret:add_signal("property::timeout")
|
|
|
|
ret:add_signal("timeout")
|
|
|
|
|
|
|
|
ret.data = { timeout = 0 }
|
|
|
|
setmetatable(ret, timer_instance_mt)
|
|
|
|
|
|
|
|
for k, v in pairs(args) do
|
|
|
|
ret[k] = v
|
|
|
|
end
|
|
|
|
|
|
|
|
return ret
|
|
|
|
end
|
|
|
|
|
2015-01-11 10:58:49 +01:00
|
|
|
local delayed_calls = {}
|
|
|
|
capi.awesome.connect_signal("refresh", function()
|
|
|
|
for _, callback in ipairs(delayed_calls) do
|
2015-07-13 21:19:15 +02:00
|
|
|
local success, message = xpcall(function()
|
|
|
|
callback[1](unpack(callback, 2))
|
|
|
|
end, function(err)
|
2015-08-08 13:08:21 +02:00
|
|
|
print(debug.traceback("Error during delayed call: "..tostring(err), 2))
|
2015-07-13 21:19:15 +02:00
|
|
|
end)
|
2015-01-11 10:58:49 +01:00
|
|
|
end
|
|
|
|
delayed_calls = {}
|
|
|
|
end)
|
|
|
|
|
|
|
|
--- Call the given function at the end of the current main loop iteration
|
2015-02-15 22:26:47 +01:00
|
|
|
-- @tparam function callback The function that should be called
|
2015-01-11 10:58:49 +01:00
|
|
|
-- @param ... Arguments to the callback function
|
|
|
|
function timer.delayed_call(callback, ...)
|
|
|
|
assert(type(callback) == "function", "callback must be a function, got: " .. type(callback))
|
|
|
|
table.insert(delayed_calls, { callback, ... })
|
|
|
|
end
|
|
|
|
|
2014-12-06 16:44:04 +01:00
|
|
|
function timer.mt:__call(...)
|
2015-02-15 22:26:47 +01:00
|
|
|
return timer.new(...)
|
2014-12-06 16:44:04 +01:00
|
|
|
end
|
|
|
|
|
|
|
|
return setmetatable(timer, timer.mt)
|
|
|
|
|
|
|
|
-- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80
|