Page 1 of 1

Core Love functions as pointers

Posted: Thu Feb 07, 2013 4:31 am
by Garan
Something I realized is that since Lua supports making pointers to functions, you could change the function that things like love.mousepressed, love.update, love.draw etc. are referring to. Normally people will just define them with the standard "function love.update(dt) ... end". But what if instead, you had two SEPARATE functions? For example, say you have a function menuUpdate and gameUpdate. When you would open the menu, all you have to do is say "love.update = menuUpdate". Returning to the normal game is as simple as saying "love.update = gameUpdate". This removes the need to have a long, encompassing "if" statement that only allows the game to proceed if it isn't paused.

Re: Core Love functions as pointers

Posted: Thu Feb 07, 2013 6:42 am
by Inny
So, in Lua we don't say "pointers" because the notion is off. Almost everything in Lua is a 1st class object, so the "pointers to functions" can really be though of simply as the Function object, and love.graphics.setMode is just where the Function object is being stored at the moment. But, as you've already followed through on the thought, yes you can replace love.draw and love.update dynamically.

Personally, I don't think you should do that. The short reason is that debugging may be difficult. If you crash, the game will say you crashed in love.update, but won't tell you *which* of the possible functions it crashed in.

Re: Core Love functions as pointers

Posted: Thu Feb 07, 2013 8:17 am
by miko
Garan wrote: Normally people will just define them with the standard "function love.update(dt) ... end". But what if instead, you had two SEPARATE functions? For example, say you have a function menuUpdate and gameUpdate. When you would open the menu, all you have to do is say "love.update = menuUpdate". Returning to the normal game is as simple as saying "love.update = gameUpdate". This removes the need to have a long, encompassing "if" statement that only allows the game to proceed if it isn't paused.
Why not use gamestate then?
Anyways, you can do it like:

Code: Select all

local myupdate
function love.update(dt)
  myupdate(dt)
end

myupdate=menuUpdate
....
myupdate=gameUpdate


Re: Core Love functions as pointers

Posted: Thu Feb 07, 2013 10:32 am
by Jasoco
To expand on that, here's what I do.

Each game state gets its own file like so. For instance the "game" itself would be something like:

Code: Select all

game = {}

function game:update(dt)

end

function game:draw()

end

function game:keypressed(key, unicode)

end

--And so on with the other love.functions. Note the colons...
Then in your main.lua you just use this...

Code: Select all

function love.load()
    currentState = game
end

function love.update(dt)
    currentState:update(dt)
end

function love.draw()
    currentState:draw()
end

function love.keypressed(key, unicode)
    currentState:draw(key, unicode)
end

...
By using the colons you can use variables that belong to each state and refer to them as "self". For instance: self.score instead of game.score or just score.

This is just a simple example.

Re: Core Love functions as pointers

Posted: Thu Feb 07, 2013 12:12 pm
by Robin
As others have pointed out, functions are first class objects in Lua, and as such it doesn't need nor have a concept of function pointers.

Code: Select all

function foo()
end
is the same as

Code: Select all

foo = function()
end
But what you want to do is repeatedly change the binding of love.update and love.draw during the game. I have done so in a few games, but I wouldn't recommend it in general. Not because of the debugging thing (gamestates have the exact same non-problem (non-problem because you still have traceback that says the line number something has occurred)), but because you often have some boilerplate code that you want to run in love.update or love.draw. And such boilerplate is easier to add when you have something like Jasoco showed than if you re-bind love.update and love.draw (because then you need to duplicate that code over each implementation of those functions, at the very least as a function call).

Re: Core Love functions as pointers

Posted: Fri Feb 08, 2013 1:35 am
by Garan
So when I said "making pointers to functions" I understood that saying

Code: Select all

function foo()

end
was equivalent to saying

Code: Select all

foo = function()

end
This was actually what gave me this idea. I was thinking that "foo" is working as a pointer to the function it is created with, and saying "bar = foo" would make "bar" point to the same function.

Re: Core Love functions as pointers

Posted: Fri Feb 08, 2013 8:07 am
by T-Bone
The word "pointer" doesn't fit Lua that well. While it's probably implemented in C/C++ as pointers, it's nothing you should care about when writing Lua. The way you use it in Lua is more similar to what Java calls "references" (not the same as C/C++ references), so perhaps that's a better term?

Re: Core Love functions as pointers

Posted: Fri Feb 08, 2013 2:28 pm
by bartbes
Anyway, typically this is done at a later stage, as in, like jasoco said, one of the benefits is a better stack trace in errors, for instance, but yes, this is not impossible, hard, or new.

Pick what you like and do it! One of the things about lua and love is that you're given the tools to do (just about) everything, and it is only your imagination (and motivation) that's limiting you.
(Though another really nice advantage about the typical way of gamestates (jasoco's) is that there's only one variable to change.)

EDIT: Oh, and in general a switch/case statement as in other languages, and even more complex if/elseif trees can be represented with table indexing in lua, you'll rarely see large ifs in idiomatic code.