Passing key in function

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
Before you make a thread asking for help, read this.
Post Reply
knuxyl
Citizen
Posts: 52
Joined: Sat Aug 13, 2016 4:40 am

Passing key in function

Post by knuxyl »

So I have a very complex/optimized idea of dealing with stacks for drawing and inputs but I've hit a barrier.

I have declared a function like this

Code: Select all

function ui:input()
    do stuff
end
And then I have that stored into a table

Code: Select all

function stack:push()
    table.insert(stack.input, function() ui:input() end)
end
Now the problem I am running into is this code below

Code: Select all

function love.keypressed(key)
	stack.input[#stack.input](key)
end
It is returning key as nil when the function is executed. I tried passing self as the first argument but that did not work either.

My goal is to have a dynamic way of calling different inputs and draws without filling my code with if's. I've got the draw functions down perfect, I'm just stuck with this. I've read there might be a problem with dot and colon notation for the functions but passing self didn't work.

Any ideas or a better way of handling stacks? Thanks!
User avatar
pgimeno
Party member
Posts: 3550
Joined: Sun Oct 18, 2015 2:58 pm

Re: Passing key in function

Post by pgimeno »

knuxyl wrote: Sat Mar 07, 2020 7:51 am

Code: Select all

function stack:push()
    table.insert(stack.input, function() ui:input() end)
end
Now the problem I am running into is this code below

Code: Select all

function love.keypressed(key)
	stack.input[#stack.input](key)
end
If it doesn't specify any arguments, every argument you pass will be ignored. Maybe you want this instead?

Code: Select all

function stack:push()
    table.insert(stack.input, function(...) ui:input(...) end)
end
I'm not sure how you intend to distinguish types of input, though. Perhaps you could pass the name of the triggering event, like this:

Code: Select all

function love.keypressed(...)
	stack.input[#stack.input]("keypressed", ...)
end
knuxyl
Citizen
Posts: 52
Joined: Sat Aug 13, 2016 4:40 am

Re: Passing key in function

Post by knuxyl »

Adding the ... in function() and ui:input() seems to have fixed the issue. What exactly does this do? Is this just a placeholder letting lua know it should have an argument or do the 3 dots actually mean something? Thanks!
User avatar
pgimeno
Party member
Posts: 3550
Joined: Sun Oct 18, 2015 2:58 pm

Re: Passing key in function

Post by pgimeno »

knuxyl wrote: Sat Mar 07, 2020 1:16 pm Adding the ... in function() and ui:input() seems to have fixed the issue. What exactly does this do? Is this just a placeholder letting lua know it should have an argument or do the 3 dots actually mean something? Thanks!
When used in a function declaration, it indicates that it accepts a variable number of arguments. It can only be additionally used within functions that have ... in the function declaration, and in that case, it means a tuple of all of the arguments passed. For example (using this distinction between arguments and parameters):

Code: Select all

-- function with two arguments
function x(a, b)
  print(a, b)
end

-- Function declaration with no parameters
function y()
  -- we can't use "..." here because it's not in the declaration
  x()  -- call function x with no arguments
  -- when a function is called with fewer arguments than parameters,
  -- the missing parameters are set to nil, so this is equivalent
  -- to: x(nil, nil)
end

-- Function declaration with variable number of arguments
function z(...)
  -- we can use "..." here because we're in a function declared with "..."
  x(...)  -- passes all arguments we were passed as arguments of function x
end

-- "..." is illegal at this point because we're not inside a function declaration

x(1, 2)  -- prints 1, 2
y(1, 2)  -- we can do this, but since the declaration says that y() has no parameters,
         -- the 1 and 2 are lost, and this prints nil, nil
z(1, 2)  -- prints 1, 2
knuxyl
Citizen
Posts: 52
Joined: Sat Aug 13, 2016 4:40 am

Re: Passing key in function

Post by knuxyl »

pgimeno wrote: Sat Mar 07, 2020 3:45 pm
knuxyl wrote: Sat Mar 07, 2020 1:16 pm Adding the ... in function() and ui:input() seems to have fixed the issue. What exactly does this do? Is this just a placeholder letting lua know it should have an argument or do the 3 dots actually mean something? Thanks!
When used in a function declaration, it indicates that it accepts a variable number of arguments. It can only be additionally used within functions that have ... in the function declaration, and in that case, it means a tuple of all of the arguments passed. For example (using this distinction between arguments and parameters):

Code: Select all

-- function with two arguments
function x(a, b)
  print(a, b)
end

-- Function declaration with no parameters
function y()
  -- we can't use "..." here because it's not in the declaration
  x()  -- call function x with no arguments
  -- when a function is called with fewer arguments than parameters,
  -- the missing parameters are set to nil, so this is equivalent
  -- to: x(nil, nil)
end

-- Function declaration with variable number of arguments
function z(...)
  -- we can use "..." here because we're in a function declared with "..."
  x(...)  -- passes all arguments we were passed as arguments of function x
end

-- "..." is illegal at this point because we're not inside a function declaration

x(1, 2)  -- prints 1, 2
y(1, 2)  -- we can do this, but since the declaration says that y() has no parameters,
         -- the 1 and 2 are lost, and this prints nil, nil
z(1, 2)  -- prints 1, 2
Perfect, thanks so much for your help! One more question, if ... is more than one variable, then is it stored as a table? like to reference the second variable in the passed arguments, would it be like this

Code: Select all

function something(...)
   x = ...
   print(x[2])
end
User avatar
pgimeno
Party member
Posts: 3550
Joined: Sun Oct 18, 2015 2:58 pm

Re: Passing key in function

Post by pgimeno »

knuxyl wrote: Sat Mar 07, 2020 10:24 pm Perfect, thanks so much for your help! One more question, if ... is more than one variable, then is it stored as a table? like to reference the second variable in the passed arguments, would it be like this

Code: Select all

function something(...)
   x = ...
   print(x[2])
end
No, it's a tuple, not a table. However, you can pass a tuple to a table constructor and then you can do what you want. Tuples are just multiple values, and they are handled specially.

Code: Select all

function something(...)
  local a, b = ...  -- sets a to the first element and b to the second, ignores the rest
  local x = {...}   -- constructs a table with all arguments
  print(x[2])       -- prints the second argument (taking it from the table)
  print(b)          -- prints the same
  local c = select(2, ...)
  print(c)          -- prints the same
end
select() is a system function that takes an index (or the string "#") and returns all arguments starting in that position (or the number of arguments):

Code: Select all

  print(select(2, "a", "b", "c"))    -- prints:  b    c
  print(select(3, "a", "b", "c"))    -- prints:  c
  print(select("#", "a", "b", "c"))  -- prints:  3
When you pass it '...', each element in the tuple is passed as an additional argument, and select() returns the argument at the index you want.
knuxyl
Citizen
Posts: 52
Joined: Sat Aug 13, 2016 4:40 am

Re: Passing key in function

Post by knuxyl »

Ok I'll look into that later, now my problem is my functions that are stored in the stack are not properly returning values.

lets say i have this

Code: Select all

function ui:menu(var)
    pseudo create menu var
    return false
end

Code: Select all

function stack:push(fun)
    table.insert(stack.fun, fun)
end
love.load

Code: Select all

stack:push(function() ui:menu(main) end)
and in love.update

Code: Select all

for i in ipairs(stack.fun) do
    check = stack.fun[i]()
    print(check)
end
love.draw is only drawing the canvas

From my understanding, since the menu creation function is being stored in the stack and called in love.update, check should be storing the returned variable, but it's not, it's returning nil. I need it to return a boolean to check whether it should be rendered again or not. I'm using a canvas to limit the amount of code being processed every tick and this would stop unnecessary code from running.

I've never really worked with return from functions before.
MrFariator
Party member
Posts: 512
Joined: Wed Oct 05, 2016 11:53 am

Re: Passing key in function

Post by MrFariator »

You need to do this one little change:

Code: Select all

stack:push(function() return ui:menu(main) end) -- note the 'return' here
However, keep in mind that this will create a function every single time this particular line of code is run, which may or may not be ideal depending on how often this is run, or how you manage the 'stack'.

Additionally, if ui:menu() were to return multiple values, then in your loop you'd have to assign those individually:

Code: Select all

for i in ipairs(stack.fun) do
    check1,check2,check3 = stack.fun[i]()
    print(check1,check2,check3)
end
But if you only want to print the return values, wrapping the function call in a print works:

Code: Select all

local function func2 ()
  return 1,2,3
end
local function func1 ()
  return func2()
end
local val = func1()
print(val)     -- prints 1
print(func1()) -- prints 1 2 3
knuxyl
Citizen
Posts: 52
Joined: Sat Aug 13, 2016 4:40 am

Re: Passing key in function

Post by knuxyl »

Pefect!!! Yeah I have most functions turn off right after they are ran, inside the for loop i do a check on stack.exe to see if it's true or false, if true ill run the code. my push functions only are ran when needed, everything else is handed by the returned boolean. Thanks so much!!!
Post Reply

Who is online

Users browsing this forum: No registered users and 214 guests