Skip to content

Instantly share code, notes, and snippets.

@ColonelThirtyTwo
Created October 28, 2012 14:39
Show Gist options
  • Save ColonelThirtyTwo/3968771 to your computer and use it in GitHub Desktop.
Save ColonelThirtyTwo/3968771 to your computer and use it in GitHub Desktop.
Replacement timer library for gmod13
--- Improved timers module. Checks arguments more effectively, and doesn't mess up if one of the timers errors.
-- To use, just drop in lua/autorun/
--print("Improved timers loading...")
if SERVER then AddCSLuaFile() end
local timers = {}
local function xpcall_callback(err)
return debug.traceback(tostring(err),2)
end
function timer.Create(name, delay, reps, func)
if not name then
error("Invalid timer name: "..tostring(name),2)
end
if type(delay) ~= "number" or delay < 0 then
error("Invalid timer delay: "..tostring(delay),2)
end
if type(reps) ~= "number" or reps < 0 or math.floor(reps) ~= reps then
error("Invalid timer reps: "..tostring(reps),2)
end
if type(func) ~= "function" and not (debug.getmetatable(func) and debug.getmetatable(func).__call) then
error("Invalid timer function: "..tostring(func),2)
end
timers[name] = {
name = name,
delay = delay,
reps = reps == 0 and -1 or reps,
func = func,
on = false,
lastExec = 0,
}
timer.Start(name)
end
function timer.Start(name)
local t = timers[name]
if not t then
error("Tried to start nonexistant timer: "..tostring(name),2)
end
t.on = true
t.timeDiff = nil
t.lastExec = CurTime()
return true
end
function timer.Stop(name)
local t = timers[name]
if not t then return false end
t.on = false
t.timeDiff = nil
return true
end
function timer.Pause(name)
local t = timers[name]
if not t then return false end
t.on = false
t.timeDiff = CurTime() - t.lastExec
return true
end
function timer.UnPause(name)
local t = timers[name]
if not t or not t.timeDiff then
error("Tried to unpause nonexistant timer: "..tostring(name),2)
end
if not t.timeDiff then
error("Tried to unpause nonpaused timer: "..tostring(name),2)
end
t.on = true
t.lastExec = CurTime() - t.timeDiff
t.timeDiff = nil
return true
end
function timer.Adjust(name, delay, reps, func)
local t = timers[name]
if not t or not t.timeDiff then
error("Tried to adjust nonexistant timer: "..tostring(name),2)
end
if type(delay) ~= "number" or delay < 0 then
error("Invalid timer delay: "..tostring(delay),2)
end
if type(reps) ~= "number" or reps < 0 or math.floor(reps) ~= reps then
error("Invalid timer reps: "..tostring(reps),2)
end
t.delay = delay
t.reps = reps
if func then
if type(func) ~= "function" and not (debug.getmetatable(func) and debug.getmetatable(func).__call) then
error("Invalid timer function: "..tostring(func),2)
end
t.func = func
end
return true
end
function timer.Destroy(name)
timers[name] = nil
end
timer.Remove = timer.Destroy
function timer.Simple(delay, func)
if type(delay) ~= "number" or delay < 0 then
error("Invalid timer delay: "..tostring(delay),2)
end
if type(func) ~= "function" and not (debug.getmetatable(func) and debug.getmetatable(func).__call) then
error("Invalid timer function: "..tostring(func),2)
end
local name = {}
timers[name] = {
name = name,
delay = delay,
reps = 1,
func = func,
on = false,
lastExec = 0,
}
timer.Start(name)
end
function timer.Check()
local t = CurTime()
for name,tmr in pairs(timers) do
if tmr.lastExec + tmr.delay <= t then
local ok, err = xpcall(tmr.func, xpcall_callback)
if not ok then
ErrorNoHalt(err)
timers[name] = nil
else
tmr.lastExec = t
tmr.reps = tmr.reps - 1
if tmr.reps == 0 then
timers[name] = nil
end
end
end
end
end
hook.Add("Think", "CheckTimers", timer.Check)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment