Suggestion: Joystick:isDown() to accept strings/nil

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
User avatar
retrotails
Party member
Posts: 212
Joined: Wed Apr 18, 2012 12:37 am

Suggestion: Joystick:isDown() to accept strings/nil

Post by retrotails »

Suggestion: Joystick:isDown() should return false instead of crashing if you input something other then a number.
I have an input library that has a generic "isDown()" function, and the user can ask for either a button number, a keyboard string, or a string that matches a js number.

As such, I don't feel like sanitizing input.

Code: Select all

function isDown(key)
    if love.keyboard.isDown(key) or settings.joysticks[1]:isDown(settings.controllerconfig[key]) then
        return true
    else
        return false
    end
end
If settings.controllerconfig[key] doesn't exist or isn't a number, it'll crash.

The solution (for now) is something like this

Code: Select all

function isDown(key)
    if type(settings.controllerconfig[key]) == "string" then
        if love.keyboard.isDown(key) then
            return true
        end
    elseif type(settings.controllerconfig[key]) == "number" then
        if love.keyboard.isDown(tostring(key)) or settings.joysticks[1]:isDown(settings.controllerconfig[key]) then
            return true
        end
    end
    return false
end
I suppose the same should go for love.keyboard.isDown().
User avatar
slime
Solid Snayke
Posts: 3144
Joined: Mon Aug 23, 2010 6:45 am
Location: Nova Scotia, Canada
Contact:

Re: Suggestion: Joystick:isDown() to accept strings/nil

Post by slime »

The error produced when you pass in a non-number to Joystick:isDown is there to tell you that you're doing something wrong. What if someone wrote code assuming Joystick:isDown took a [wiki]GamepadButton[/wiki] instead of a joystick button index? That's clearly a mistake and the programmer should learn about their mistake as early as possible.

You should write your input library to clearly differentiate internally between joystick binds and keyboard binds (rather than just checking the base type of the bind variable), and then you won't have this problem.
What if, in the future, you want to use the Gamepad API (rather than the more low level Joystick API)? [wiki]Joystick:isGamepadDown[/wiki] takes strings like "a", "x", etc. which are also valid key presses, so your current method of differentiating will not work anyway.
User avatar
retrotails
Party member
Posts: 212
Joined: Wed Apr 18, 2012 12:37 am

Re: Suggestion: Joystick:isDown() to accept strings/nil

Post by retrotails »

slime wrote:The error produced when you pass in a non-number to Joystick:isDown is there to tell you that you're doing something wrong. What if someone wrote code assuming Joystick:isDown took a [wiki]GamepadButton[/wiki] instead of a joystick button index? That's clearly a mistake and the programmer should learn about their mistake as early as possible.

You should write your input library to clearly differentiate internally between joystick binds and keyboard binds (rather than just checking the base type of the bind variable), and then you won't have this problem.
What if, in the future, you want to use the Gamepad API (rather than the more low level Joystick API)? [wiki]Joystick:isGamepadDown[/wiki] takes strings like "a", "x", etc. which are also valid key presses, so your current method of differentiating will not work anyway.
I should clarify:

Code: Select all

    if love.keyboard.isDown(key) then
        return true
    elseif settings.joysticks[1]:isDown(controllerconfig[key]) then
        return true
    end
It first checks to see if the key, lets say 1, is down. Then it checks to see if the button "controllerconfig[1]" is pressed on the controller - that will return 7 because the configuration exists for that, and return true if button 7 is pressed. But if controllerconfig[1] doesn't exist, it will crash because it's trying to check for a null value.
I can see what you mean about strings, and now I can completely understand why you need js:isDown('string') to crash. But maybe nul should return false. I do understand that it's as simple as

Code: Select all

    if love.keyboard.isDown(key) then
        return true
    elseif settings.controllerconfig[key] then
        if settings.joysticks[1]:isDown(settings.controllerconfig[key]) then
            return true
        end
    end
but I don't see any reason why crashing on nul could help debugging.
User avatar
Robin
The Omniscient
Posts: 6506
Joined: Fri Feb 20, 2009 4:29 pm
Location: The Netherlands
Contact:

Re: Suggestion: Joystick:isDown() to accept strings/nil

Post by Robin »

retrotails wrote:but I don't see any reason why crashing on nul could help debugging.
Because you know there's a variable initialization missing. Going on, ignoring things like that, that's how you get bugs that are nearly impossible to diagnose and fix.
Help us help you: attach a .love.
User avatar
retrotails
Party member
Posts: 212
Joined: Wed Apr 18, 2012 12:37 am

Re: Suggestion: Joystick:isDown() to accept strings/nil

Post by retrotails »

Robin wrote:
retrotails wrote:but I don't see any reason why crashing on nul could help debugging.
Because you know there's a variable initialization missing. Going on, ignoring things like that, that's how you get bugs that are nearly impossible to diagnose and fix.
What variable?
User avatar
Kingdaro
Party member
Posts: 395
Joined: Sun Jul 18, 2010 3:08 am

Re: Suggestion: Joystick:isDown() to accept strings/nil

Post by Kingdaro »

As in,

Code: Select all

myButton = 1

-- ... tons of code .. --

if joystick:isDown(mybutton) then -- woah look at that typo!
   attack()
end
and if it didn't crash, you would scan your code for hours, wondering why your player isn't attacking and constantly missing that typo that isn't very obvious.
Palmar
Prole
Posts: 23
Joined: Thu Dec 13, 2012 3:54 pm

Re: Suggestion: Joystick:isDown() to accept strings/nil

Post by Palmar »

My solution:

Code: Select all

function jDown(k)
	-- Translator
	local tran = {}        -- Buttons dictionary
	tran["a"] = 1; tran["b"] = 2; tran["y"] = 3; tran["x"] = 4; tran["start"] = 9 
	local b = tran[k]
	if #j > 0 then         -- "j" is my joystick constructor
		if j[1]:isGamepadDown(k) or j[1]:isDown(b) then 
			return true
		end	
	end
end
Post Reply

Who is online

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