Timed callback

General discussion about LÖVE, Lua, game development, puns, and unicorns.
Post Reply
aidalgol
Prole
Posts: 19
Joined: Tue Feb 07, 2012 7:53 pm
Location: New Zealand
Contact:

Timed callback

Post by aidalgol »

Is there a way to say "call this function after n seconds"? And if not, where in the LÖVE code should I start looking to implement this?
User avatar
kikito
Inner party member
Posts: 3153
Joined: Sat Oct 03, 2009 5:22 pm
Location: Madrid, Spain
Contact:

Re: Timed callback

Post by kikito »

I believe cron.lua is the simplest way to do it:

Code: Select all

local cron = require 'cron'

x = 0
function love.update(dt)
  cron.update(dt) -- you *must* call cron.update inside love.update()
  ...
end

...
cron.after(3, function()
  x = 1 -- set x to 1 after 3 seconds
end)
...
When I write def I mean function.
User avatar
miko
Party member
Posts: 410
Joined: Fri Nov 26, 2010 2:25 pm
Location: PL

Re: Timed callback

Post by miko »

aidalgol wrote:Is there a way to say "call this function after n seconds"? And if not, where in the LÖVE code should I start looking to implement this?
Try this:

Code: Select all

function delay(t, fn)
  local t={fn=fn, ts=GAMETIME+t}
  table.insert(EVENTS, t)
  table.sort(EVENTS, function(a, b) return a.ts<b.ts end)
end

function updateEvents(dt)
  GAMETIME=GAMETIME+dt
  while #EVENTS>0 and EVENTS[1].ts<=GAMETIME do
    local t=table.remove(EVENTS, 1)
    t.fn()
  end
end

function love.load()
  status='waiting'
  GAMETIME=0
  EVENTS={}
  delay(5, function() status='fired 5' end)
  delay(15, function() status='fired 15' end)
  delay(10, function() status='fired 10' end)
end

function love.draw()
  love.graphics.print(status, 1, 1)
end

function love.update(dt)
  updateEvents(dt)
end
My lovely code lives at GitHub: http://github.com/miko/Love2d-samples
aidalgol
Prole
Posts: 19
Joined: Tue Feb 07, 2012 7:53 pm
Location: New Zealand
Contact:

Re: Timed callback

Post by aidalgol »

[quote="kikito"]I believe cron.lua is the simplest way to do it:

Yeah, that looks like exactly what I want. Thanks!
coffee
Party member
Posts: 1206
Joined: Wed Nov 02, 2011 9:07 pm

Re: Timed callback

Post by coffee »

miko wrote: Try this:

Code: Select all

...
Thank you for sharing miko your minimal timer. I never had opportunity till now of use kikito's library that seems also awesome. There isn't no problems/limitations "arg" something big as call a entire function with multiple args or is advisable assign function to a var first?
User avatar
Robin
The Omniscient
Posts: 6506
Joined: Fri Feb 20, 2009 4:29 pm
Location: The Netherlands
Contact:

Re: Timed callback

Post by Robin »

coffee wrote:Thank you for sharing miko your minimal timer. I never had opportunity till now of use kikito's library that seems also awesome. There isn't no problems/limitations "arg" something big as call a entire function with multiple args or is advisable assign function to a var first?
Nope. Lua doesn't work the way you seem to think it works. It's like what C++ calls "by reference". The reason it looks like "by value" in some cases, is that numbers and strings are immutable in Lua.
So passing a function as argument has the same performance (both memory and time) as passing a string, a number or a table.
Help us help you: attach a .love.
User avatar
kikito
Inner party member
Posts: 3153
Joined: Sat Oct 03, 2009 5:22 pm
Location: Madrid, Spain
Contact:

Re: Timed callback

Post by kikito »

Robin wrote:
coffee wrote:Thank you for sharing miko your minimal timer. I never had opportunity till now of use kikito's library that seems also awesome. There isn't no problems/limitations "arg" something big as call a entire function with multiple args or is advisable assign function to a var first?
Nope. Lua doesn't work the way you seem to think it works. It's like what C++ calls "by reference". The reason it looks like "by value" in some cases, is that numbers and strings are immutable in Lua.
So passing a function as argument has the same performance (both memory and time) as passing a string, a number or a table.
If you are going to use the function only once or twice, as robin says, the two pieces of code below are the equivalent.

Code: Select all

-- creating the function in advance
local f = function()
  <dosomething>
end
cron.after(5, f)
-- creating the function directly in the call
cron.after(5, function() <dosomething> end)
Creating functions is not free; it has a cost. Invoking them also has a cost. But if you are going to need to invoke the same function several times, it is cheaper to create it only once, and invoke it several times, than to create and invoke it every time.

So if you are going to use the same callback several times, it's better to move it to a variable:

Code: Select all

-- this creates 1 function, and invokes it 100 times
local f = function()
  <dosomething>
end
for i=1,100 cron.after(5, f) end

-- this creates 100 equal functions, invoking each one one time
for i=1,100
  cron.after(5, function() <dosomething> end)
end
It's the same idea as with any other value, really. If you are going to need it more than once, store it in a variable so you don't have to calculate it again. But if you are using it only once, storing it in a variable might just make the code longer and clumsier.

It's also worth nothing that in some occasions functions look the same, but they are not - they might be different closures each time; the variables they access/modify are named the same, but are different values in memory.

Finally, just reminding that if you want to repeat something periodically, you can use cron.every . No need to "craft" your own periodical function using cron.after (although it is an interesting exercise).
When I write def I mean function.
coffee
Party member
Posts: 1206
Joined: Wed Nov 02, 2011 9:07 pm

Re: Timed callback

Post by coffee »

kikito, robin, thank you both both for enlarging my horizon and the advices about this question. I started to had more idea of doing separated tables with timers for each "activity" (one for animations, other for messages etc) but probably I will revise my objective and do a general one calling functions to deal with all time work. Following your advices I will try avoid making mistakes. kikito, I will end probably using cron for others later projects but for now and for learning it's really important to learn and know how to code with time.
Post Reply

Who is online

Users browsing this forum: Bing [Bot] and 54 guests