Timer - a timer expiration lib

Showcase your libraries, tools and other projects that help your fellow love users.
Post Reply
Almia
Prole
Posts: 8
Joined: Mon Aug 05, 2013 7:56 am

Timer - a timer expiration lib

Post by Almia »

Hello :D

I'm a bit newbie in this game engine and lua and I wanted to create a game, though it made it harder for me because of the love.update() function which I have to add functions on my every single lib that needs periodic execution. Because of this I created a small library that allows you to create "timers" that periodically executes or executes delayed functions.

Code:

Code: Select all

--[[

timer.lua by Almia

a library that handles periodic or delayed execution of functions
via virtual timers.

Timers has a minimum of 32 executions per second.
--------------------------------------------

	API
	
	timer.start(timeout, doReset, handler)
		- starts a timer
			*timeout - how often the timer executes handlers
			*doReset - does the timer executes again?
			*handler - the initial handling function that
						is executed every time the timer expires.
	
	timer:pause()
		- pauses the timer
	
	timer:resume()
		- resumes the timer
		
	timer:setTimeout(timeout)
		- changes/sets the timer's timeout
		
	timer.update(dt)
		- must be put inside the love.update, also having the love.update's dt
]]--
MIN_TIMEOUT = 0.031250000 -- 32 frames
timer = {}
timer.__index = timer
local timers = {}

function timer.start(timeout, doReset, handler)
	if type(timeout) == "number" then
		if timeout <= MIN_TIMEOUT then
			timeout = MIN_TIMEOUT
		end
	else
		timeout = MIN_TIMEOUT
	end
	
	local new = {active = true,
				 timeout = timeout,
				 doReset = doReset,
				 handler = handler,
				 prev = love.timer.getTime()}
	table.insert(timers, new)
	setmetatable(new, timer)
	return new
end

function timer:pause()
	self.active = false
end

function timer:resume()
	self.active = true
end

function timer:setTimeout(timeout)
	if timeout <= MIN_TIMEOUT then
		timeout = MIN_TIMEOUT
	end
	if self.active then
		self.prev = love.timer.getTime()
	end
	self.timeout = timeout
end

function timer.update()
	dt = love.timer.getTime()
	for k, t in ipairs(timers) do
		if t.active then
			if dt - t.prev >= t.timeout then
				t.handler()
				if t.doReset then
					t.prev = dt
				else
					t.pause()
				end
			end
		end
	end
end
Sample code:

Code: Select all

require "timer"
function love.load()
	local t = 0.031250000
	text = {}
	for i = 1,32 do
		text[i] = 0
		timer.start(t, true, function ()
			text[i] = text[i] + 1
		end)
		t = t + MIN_TIMEOUT
	end
end

function love.update()
	timer.update()
end

function love.draw()
	local y = 0
	local yg = 600/32
	for i = 1, 32 do
		love.graphics.print((33 - i).." frames : "..text[i], 100, y)
		y  = y + yg
	end
end
If you have any suggestions, I would appreciate it :D

[edit]
Update 1.1
- Merged .start with .new
- Timers now handles only single functions
- added .resume function
- (Misc) improved demo
Attachments
TimerTest.love
(1.18 KiB) Downloaded 187 times
Last edited by Almia on Sun Jun 28, 2015 3:18 am, edited 1 time in total.
User avatar
airstruck
Party member
Posts: 650
Joined: Thu Jun 04, 2015 7:11 pm
Location: Not being time thief.

Re: Timer - a timer expiration lib

Post by airstruck »

Looks pretty good. A few thoughts:
  • Use "local" to declare local variables so they don't pollute the global scope.
  • Some identifiers use camelCase and others use snake_case, try to be consistent.
  • The name "timer_stack" seems a little stange, it doesn't really have stack-like qualities. Just "timers" might be better.
  • If you pass dt to the update function, you can probably get rid of love.timer.getTime(), making the code framework-agnostic.
  • Having multiple callbacks associated with individual timers seems odd, it doesn't seem like that should be the timer's responsibility.
  • Having two separate steps to create and start timers feels a little cumbersome. Starting them on creation could simplify the API.
  • If you like having two steps anyway, consider moving the parameters from "start" into "new." Those feel more like initialization parameters.
Almia
Prole
Posts: 8
Joined: Mon Aug 05, 2013 7:56 am

Re: Timer - a timer expiration lib

Post by Almia »

Thank you :D

I have updated all of it except for the "dt" thing. It seems that it doesn't work because all of the timers doesn't tick or maybe i'm just missing something that i didn't know with the "dt" (perhaps the value "dt" contains)
User avatar
T-Bone
Inner party member
Posts: 1492
Joined: Thu Jun 09, 2011 9:03 am

Re: Timer - a timer expiration lib

Post by T-Bone »

The variable name "dt" is typically used for delta-time (the time between the previous frame and the current one). You seem to use it for the time since the "epoch" instead, which is probably the source of the confusion.
User avatar
airstruck
Party member
Posts: 650
Joined: Thu Jun 04, 2015 7:11 pm
Location: Not being time thief.

Re: Timer - a timer expiration lib

Post by airstruck »

T-Bone wrote:You seem to use it for the time since the "epoch" instead, which is probably the source of the confusion.
I don't think it was there in the first version. Sorry for the confusion, I meant you could pass the dt parameter from love.update on to timer.update, then you wouldn't need getTime.

Code: Select all

function love.update (dt)
   timer.update(dt)
end
Almia
Prole
Posts: 8
Joined: Mon Aug 05, 2013 7:56 am

Re: Timer - a timer expiration lib

Post by Almia »

That's what i did. Though i think dt returns the time between the last update and the current update, whereas Timer uses the time since the program is run.
User avatar
T-Bone
Inner party member
Posts: 1492
Joined: Thu Jun 09, 2011 9:03 am

Re: Timer - a timer expiration lib

Post by T-Bone »

time thief wrote:
T-Bone wrote:You seem to use it for the time since the "epoch" instead, which is probably the source of the confusion.
I don't think it was there in the first version. Sorry for the confusion, I meant you could pass the dt parameter from love.update on to timer.update, then you wouldn't need getTime.

Code: Select all

function love.update (dt)
   timer.update(dt)
end
My post was directed to OP, not you. But yeah :)



What I was specifically refering to was this line:

Code: Select all

dt = love.timer.getTime()
According to the documentation, getTime returns the time since the epoch, not a time difference.
Post Reply

Who is online

Users browsing this forum: No registered users and 5 guests