How do I fix my string issue? - lua

local background = display.newImage("black.png", 0, 0)
local submit = display.newImage("submit.png")
submit.x = display.contentWidth/2
submit.y = display.contentHeight-100
local nameInstructions = display.newText("Enter your name", 10, 50, native.systemFont, 24)
local usersName = native.newTextField(10, 100, 350, 50)
usersName.inputType = "default"
local function keyboardListener (event)
native.setKeyboardFocus(nil)
end
background:addEventListener("tap", keyboardListener)
local function reverseName(event)
reverseUsersName = string.reverse(usersName)
end
submit:addEventListener("tap", reverseName)
local reverse = display.newText(reverseUsersName)
reverse.x = display.contentWidth/2
reverse.y = display.contentHeight/2
Every time that I run this using my Corona SDK thing, I get this:
Bad argument #-1 to 'newText' (string expected, got nil)
stack traceback:
[C]: ?
[C]: in function 'newText'
...Corona Projects/Assignment 4.3/main.lua/src/main.lua:24: in main chunk

reverseName is in the local function reverseName(event), but this function is called once u press or tap on the submit . But here local reverse = display.newText(reverseUsersName), is called before you tap on the sumbit . That is why its giving you error.

The only place that reverseUsersName, accessed on line 24, is set, is inside the function reverseName(event). In this function, reverseUsersName is a global so after the function is run once, that variable will be accessible from other parts of your script, but until then, it does not exist.
Now in line 22 you've registered reverseName as event listener for "tap" events, but events are only generated after your script has been executed once (and in between calls to your script callbacks like reverseName and keyboardListener are callbacks), so when you create the display text just after, the variable does not yet exist.
So what you would have to do is update the text of the reverse display item in your reverseName listener so that every time you click on the button, the reversed name becomes visible. And because of that, you would have to declare your reverse variable above reverseName function so that it is available as an upvalue (read the Corona getting started docs, they are excellent and discuss this subtlety) in that function. And presumably you would want to initialize with showing the usersName rather than reverse.
So you would need something like
local reverse = display.newText(usersName)
local function reverseName(event)
reverseUsersName = string.reverse(usersName)
reverse.SetText(reverseUserName)
end
submit:addEventListener("tap", reverseName)
Note that if you want the string being displayed to be reversed every time you press tap, rather than only first time you press it, you will have to use
local function reverseName(event)
reverseUsersName = string.reverse(reverseUsersName)
reverse.SetText(reverseUserName)
end
reverseUsersName = usersName

Check your function reverseName and the text object(reverse) with the following code:
local reverse --[[ Initialize the object with a global scope,
so you can access it anywhere from the page. --]]
local function reverseName(event)
--[[ In the below line, usersName is a table value. It is the reason
of the error. For getting the string from the text field, you
have to provide 'usersName.text' --]]
reverseUsersName = string.reverse(usersName.text)
reverse.text = reverseUsersName -- Assign the text field value to your text object
end
submit:addEventListener("tap", reverseName)
reverse = display.newText("",20,20,nil,20) --see the parameters of display.newText()*
reverse.x = display.contentWidth/2
reverse.y = display.contentHeight/2
*Corona API: display.newText()

Related

Awesome WM adding a keybinding to the Super_L key blocks other key commands from working properly

I'm trying to implement some Super-Tab functionality into awesome-wm so that it acts in a similar way to alt tab, going through tags in order of last used rather than just a set order.
However I've run into an issue, which is that binding something to only Super_L will cause other keybinds to not work as before.
For testing right now I just have it set to this
awful.key({}, "Super_L", function () naughty.notify{text = "aaa"} end, function () naughty.notify{text = "bbb"} end)
The issue is that if I have this set, then a key binding like Super-Shift-C (to close the current window) doesn't work, at least not if you press it in that order. It will work if you press it Shift-Super-C.
Is there a reason for this/a way to fix it?
Extra question: Why doesn't the key release function work, when I press Super_L with this awful.key setting you would expect it to show "aaa" when I press, and "bbb" when I release, but only "aaa" shows up.
I'm not super sure what to try, I've been messing around with the key configs and can't figure out what's going on.
Some of the Super key bindings still work, like Super-H to change the size of a window in tiling mode.
There's some way to make your code work, but more generally, this is not the best way to implement Super-Tab. The easier way is to use awful.keygrabber.
awful.keygrabber {
keybindings = {
awful.key {
modifiers = {"Mod4"},
key = "Tab",
on_press = function () naughty.notify{text = "aaa"} end
},
awful.key {
modifiers = {"Mod4", "Shift"},
key = "Tab",
on_press = function () naughty.notify{text = "ccc"} end
},
},
stop_key = "Super_L",
stop_event = "release",
start_callback = function () naughty.notify{text = "ddd"} end,
stop_callback = function () naughty.notify{text = "bbb"} end,
export_keybindings = true,
}
This code (cop pasted from the doc link above) will create 2 keybindings (Super_L+Tab and Super_L+Shift+Tab). However, once one is executed, instead of just calling the callback, it will start to grab all keys. When Super_L is released, it will stop the keygrabber.

Love 2D(Lua) unexpected nil in object

Trying to get my feet wet with LUA and Love2D, and I am having an issue with object instantiation / access in Lua.
Source with the bug can be found here: https://bitbucket.org/dannsee/love_scrollingshooter
I am In my main, I create an object, Enemies
enemies = Enemies:new()
and inside of the enemies object, i create an object to hold peristant values, which I am calling Timers.
timers = Timers:new()
So the enemies 'constructor' method looks (basically) like this
Enemies = {} -- so that Enemies will not be nil when new() is called
timers = {} -- so that timers will be accessible in the class scope
function Enemies:new(enemies)
enemies = enemies or {}
timers = Timers:new()
setmetatable(enemies, self)
self.__index = self
return enemies
end
while the Timers being created are looking as such
Timers = {} -- so that Timers will not be nil when new() is called
function Timers:new(timers)
timers = timers or {
miniBombTimerMax = 0.2,
miniBombTimer = minibombTimerMax
}
setmetatable(timers, self)
self.__index = self
return timers
end
But when I try to refrence one of the timers ( from inside the enemies object) , I am getting a nil value exception.
timers.miniBombTimer -- Produces nil exception
It seems to me that this should both 1. be in scope, since it is an object created inside this class, and is instantiated locally as timers = {} before it is assigned a value, and 2. not nil becuase it is being given a value in the 'constructor'. But it seems there is more going on here that I am not grasping.
I am new to Lua, which may be obvious at this point, but from what I have read about variable scope it seems that this should be valid. I don't understand why the timers are not being created with values.
Careful with your globals! In Lua, it's very easy to accidentally set a global variable when you don't mean to, and it looks like that's exactly what's happening.
function Enemies:new(enemies)
enemies = enemies or {}
timers = Timers:new()
setmetatable(enemies, self)
self.__index = self
return enemies
end
On the third line here, since timers doesn't exist as a local variable here, this value ends up getting put into a global variable called timers instead. If you want to set a property of enemies, you need to mention enemies explicitly:
function Enemies:new(enemies)
enemies = enemies or {}
enemies.timers = Timers:new()
setmetatable(enemies, self)
self.__index = self
return enemies
end
Now, you write:
But when I try to refrence one of the timers ( from inside the enemies object) , I am getting a nil value exception.
Lua doesn't really have any concept of being "inside an object" or "inside a class". In some languages, when you're writing code inside of a class, all of the class's members are in scope and you can refer to them "bare". Lua is not one of those languages; in Lua, if you want to refer to a "class member", you need to use the dot notation, explicitly stating which object you're accessing. (Or you can do the "advanced method", using _ENV.)
By the way...
timers = {} -- so that timers will be accessible in the class scope
From what I see in the question, this line doesn't do much; it just creates a global variable which is never used.
Also, this line in Enemies:new:
self.__index = self
This just sets Enemies.__index every time Enemies:new is called. This is fine, but you may as well just set it once:
function Enemies:new(enemies)
enemies = enemies or {}
enemies.timers = Timers:new()
setmetatable(enemies, self)
return enemies
end
Enemies.__index = Enemies

How to set a custom icon of any client for the tasklist in awesomeWM v3.5.6?

if (c.class == "Google-chrome") then
c.icon = capi.image ( "/home/art-attack/.config/awesome/icons/chrome.png" )
end
I tried it but I always got an error i.e attempt to call field 'image' (a nil value)
{ rule = { class = "Google-chrome" },
properties = { icon = beautiful.icon_chrome } },
Then I find another way to use properties icon in awful.rules and it worked but didn't change the icon instead it disabled the icon of that client.
To fix your first attempt, try this:
if c.class == "Google-chrome" then
local icon = gears.surface("path/to/chrome.png")
c.icon = icon._native
icon:finish()
end
The line with icon:finish() is not necessary, but it exists to make sure you do not optimize this code. There is some dark garbage collection avoidance magic in there that you do not want to know, but the short story is: Never use _native unless you already have the surface itself saved in a variable.
if c.class == "Google-chrome" then
local icon = gears.surface("path/to/chrome.png")
return text, bg, bg_image, icon
end
Add this code before
if capi.client.focus == c then

Why attempt to index global (a nil value) Lua?

Actually I'm working from a tutorial and there is some error in that tutorial.
There is the code:
class "Game"( Graphics )
Game.menuScreen = nil
Game.gameScreen = nil
Game.achScreen = nil
Game.screen = nil
-- main
function Game:main()
-- Create the screens and store their links within the class
Game.menuScreen = MainMenu.new()
Game.gameScreen = GameScreen.new()
Game.achScreen = AchScreen.new()
-- Display menuScreen
Game.showScreen( 'menuScreen' )
end
-- showScreen
function Game.showScreen( name )
-- If a screen is being displayed - remove it from the stage
if Game.screen then
Stage.detach( Game.screen )
Game.screen = nil
end
-- Retrieve a screen link by name
local screen = Game[name]
if not screen then
return nil
end
-- If the screen is found - add it to the stage
Stage.attach( screen )
-- Save the displayed screen
Game.screen = screen
return screen
end
It write to me [string "Game.script"]:11: attempt to index global 'MainMenu' (a nil value)
I use Dreemchest Composer and this one is the tutirul: http://dreemchest.com/doc/en/Game%20menu%20and%20screen.html
Actually I remowed the LEVEL select screen from this code, cos I don't want to implement a level selection to my first game in this.
I have a script named MainMenu and it's class's MainMenu, Superclass is soMainMenu.
I have got it, thank you!
I had to create Stage Objects for all menu points to get it work. It's easy but the tutorial may didn't wrote it or I just didn't understand it.

How to use a value in a table inside itself (Lua language)?

I have a lua table like this:
local defaultSize = 14
local field = {
sizeA = defaultSize,
sizeB = sizeA,
}
My intention is to set sizeB to the value of field.sizeA, however the code above does not work. field.sizeB is nil in this case.
How to set sizeB to whatever sizeA is inside the table definition directly?
You could have an init function in table and call that:
local defaultSize = 14
local field = {
init = function (self, size)
self.sizeA = size or defaultSize -- size only if given, otherwise defaultSize
self.sizeB = self.sizeA
end
}
field:init() -- implicit "self" arg is "field", defaultSize will be used
field:init(16) -- size will be 16 rather than 14
print(field.sizeB) -- prints 14
This has the clear advantage of aggregating all initialization of table instance in one place, you can have conditionals etc once your logic gets more complex. You don't have to have init() as member of table, but it is always a good idea to keep dependencies obvious and close together.

Resources