How to exit TextListener?

I have extensive mainframe coding skills but am new to Lua and Corona (and the whole non-mainframe environments).   I have searched and tried extensively on how to get passed my issue.  

I have an option to allow the user to create a new game.   If the user pushes the New Game button from Create.Lua then it executed the “buildgame.lua” code below.   It then prompts the user to enter a name.   This works fine.  But then I execute a external Lua program called “buildhome.lua”.    This has complicated logic that dynamically creates a universe using many random functions to create a unique universe that is different each time.    This logic works fine.  It randomly positioning stars and planets, on a huge galaxy map.   However, once I execute this external lua code and return back to “buildgame.lua” it doesn’t know what to do.    The scenes no longer work and I am stuck in the TextListener function.   I have tried to remove the newTextField and this doesn’t work.   I final decided to just jump to a new lua program by forcing the composer.remove and composer.gotoScene thinking it would get my scenes working again.  But I still have junk left over from my “buildhome” scenes.   Even the newTextField is still there.  

What am I doing wrong?      Below the code is the output from corona to show the process it takes.

Below is my code:

[lua]
 



– buildgame.lua


local widget = require( “widget” )       --Require Widget library

local composer = require( “composer” )      --Require Composer

local myData = require( “scripts.mydata” )     --Require Global Saves

local scene = composer.newScene()

local function textListener(event)
 if (event.phase == “began”) then

  print (“Begin editing”, event.target.text)
 elseif (event.phase == “ended” or event.phase == “submitted”) then

  native.setKeyboardFocus(nil)
  myData.newgame = string.sub(event.target.text, 1, 15)

  if namedesc ~= nil then
   namedesc:removeSelf()
    namedesc = nil
  end

  if usernameField ~= nil then
   usernameField:removeSelf()
    usernameField = nil
  end

  if usernameGroup ~= nil then
    usernameGroup:removeSelf()
    usernameGroup = nil
  end

  errmsg = display.newText( “Building Star Map”, 625, 1900, “fonts/nasalization free”, 55)  
     errmsg.anchorX = 0
     errmsg:setFillColor( 145/255, 231/255, 255/255 )

  local buildhome = require (“scripts.buildhome”)

  composer.removeScene( “buildgame” )
  composer.gotoScene( “scripts.showmap”, “fade”, 800 )

 elseif (event.phase == “editing”) then
  print (event.phase)

  local valid_letter = false
  if ((event.newCharacters >= “a”) and (event.newCharacters <= “z”)) or 
           ((event.newCharacters >= “A”) and (event.newCharacters <= “Z”)) then
           valid_letter = true
        else
         errval = display.newText( “Only letters a-z are allowed - please remove”, 225, 1400, “fonts/nasalization free”, 85) 
         errval.anchorX = 0
         errval:setFillColor( 145/255, 231/255, 255/255 )
        end

        local txt = event.text           
        if(string.len(txt)>15)then
            txt=string.sub(txt, 1, 15)
            print("txt: ", txt)
            errsiz = display.newText( “Name can be 1 to 15 characters - please shorten”, 325, 1200, “fonts/nasalization free”, 85) 
         errsiz.anchorX = 0
         errsiz:setFillColor( 145/255, 231/255, 255/255 )
     else
      myData.text=txt
        end
    end
end

function onEventListener( event )       --When user taps button this is called
 print( “Going to showmap” )
 composer.removeScene( “buildgame” )
 composer.gotoScene( “scripts.buildgame”, “fade”, 800 )  --Fade and go to Load
end

function scene:create( event )              --Function to create the scene
 print( “buildgame created” )
 local sceneGroup = self.view

 local background = display.newImageRect( “images/starfield.jpg”, 2732, 2048 )   --2732, 2048
 background.x = display.contentCenterX
 background.y = display.contentCenterY
 local nebula = display.newImageRect( “images/Nebula1.png”, 2732, 2048 )   --2732, 2048
 nebula.x = display.contentCenterX
 nebula.y = display.contentCenterY
 sceneGroup:insert( background )
 sceneGroup:insert( nebula)

 local usernameGroup = self.view

 local namedesc = display.newText( "User Name: ", 800, 1000, “fonts/nasalization free”, 55)  
    namedesc.anchorX = 0
 namedesc:setFillColor( 145/255, 231/255, 255/255 )

 local usernameField = native.newTextField( 1400, 1000, 500, 85 )
 usernameField.font = native.newFont( native.systemFontBold, 55 )
 usernameField.text = “”
 usernameField:setTextColor( 0.0, 0.0, 0.0 )
 usernameField:addEventListener( “userInput”, textListener )

 usernameGroup:insert( namedesc )
 usernameGroup:insert( usernameField )

end

function scene:show( event )

 local phase = event.phase
 
 if phase == “will” then

  print(“buildgame will show.”)

  display.setDefault( “background”, 0.0, 0.0, 0.0 )

  
 elseif phase == “did” then

  print(“buildgame did show.”)

 end

end

function scene:hide( event )

 local phase = event.phase
 
 if phase == “will” then

  print(“buildgame will hide.”)

 elseif phase == “did” then

  print(“buildgame did hide.”)

 end
 
end

function scene:destroy( event )

 print( “Destroying buildgame’s view!” )

end


scene:addEventListener( “create”, scene )
scene:addEventListener( “show”, scene )
scene:addEventListener( “hide”, scene )
scene:addEventListener( “destroy”, scene )


return scene

[/lua]

Corona Output:

New Game
Destroying create’s view!
create will hide.
buildgame created
buildgame will show.
Begin editing 
create did hide.
buildgame did show.
Destroying create’s view!
editing   (typed J)
editing   (typed o)
editing   (typed h)
editing   (typed n)
buildhome myData.newgame:  John    (name of new game to be created)
buildgame will hide.
showmap created
showmap will hide.
showmap did hide.
showmap will show.
showmap will show.
showmap did show.
buildgame did hide.
showmap did show.
Destroying buildgame’s view!

What “junk” has been left over? When you mean you are stuck in the TextListener, do you mean that when you enter a name it does not let you through?

Also, please use the code formatter when copying code over. It will make your code more understandable. It is the symbol that looks like two opposite-facing brackets.

I made a couple minor modifications to the code to show where and how I get stuck inside the textListener function once it executes the external function.

 

 

[lua]


– buildgame.lua


 

local widget = require( “widget” )                                                                                 --Require Widget library

 

local composer = require( “composer” )                                                                       --Require Composer

 

local myData = require( “scripts.mydata” )                                                        --Require Global Saves

 

local scene = composer.newScene()

 

local function textListener(event)

            if (event.phase == “began”) then

                        – user begins editing textField

                        print (“Begin editing”, event.target.text)

            elseif (event.phase == “ended” or event.phase == “submitted”) then

 

                        print(“event phase :”, event.phase)

 

                        --print ("scene: ", scene)

 

                        --[[if namedesc ~= nil then

                                    namedesc:removeSelf()

                                    namedesc = nil

                        end

 

                        if usernameField ~= nil then

                                    usernameField:removeSelf()

                                    usernameField = nil

                        end

 

                        if usernameGroup ~= nil then

                                    usernameGroup:removeSelf()

                                    usernameGroup = nil

                        end]]

 

                        --errmsg = display.newText( “Building Star Map”, 625, 1900, “fonts/nasalization free”, 55)    

                        --errmsg.anchorX = 0

                --errmsg:setFillColor( 145/255, 231/255, 255/255 )

                if event.phase == “submitted” then

 

                                    native.setKeyboardFocus(nil)

                                    myData.newgame = string.sub(event.target.text, 1, 15)

                                    --print(“Final Text:”, myData.newgame, event.phase)

                        print (“start buildhome”)

               

                                    local buildhome = require (“scripts.buildhome”)

 

                                    print (“end buildhome”)

                        end

 

                        --composer.removeScene( “buildgame” )

                        --composer.gotoScene( “scripts.showmap”, “fade”, 800 )

 

 

            elseif (event.phase == “editing”) then

                        print (event.phase)

 

                        local valid_letter = false

                        if ((event.newCharacters >= “a”) and (event.newCharacters <= “z”)) or 

           ((event.newCharacters >= “A”) and (event.newCharacters <= “Z”)) then

           valid_letter = true

        else

                        errval = display.newText( “Only letters a-z are allowed - please remove”, 225, 1400, “fonts/nasalization free”, 85)   

                            errval.anchorX = 0

                    errval:setFillColor( 145/255, 231/255, 255/255 )

                    sceneGroup:insert( errval)

            end

 

        local txt = event.text           

        if(string.len(txt)>15)then

            txt=string.sub(txt, 1, 15)

            print("txt: ", txt)

            errsiz = display.newText( “Name can be 1 to 15 characters - please shorten”, 325, 1200, “fonts/nasalization free”, 85)   

                            errsiz.anchorX = 0

                    errsiz:setFillColor( 145/255, 231/255, 255/255 )

                    sceneGroup:insert( errsiz)

                else

                        myData.text=txt

        end

            end

end

 

function onEventListener( event )                                                                               --When user taps button this is called

            print( “Going to showmap” )

            composer.removeScene( “buildgame” )

            composer.gotoScene( “scripts.buildgame”, “fade”, 800 )         --Fade and go to Load

end

 

function scene:create( event )                                                                     --Function to create the scene

            print( “buildgame created” )

            local sceneGroup = self.view

 

            local background = nil

            local background = display.newImageRect( “images/starfield.jpg”, 2732, 2048 )   --2732, 2048

            background.x = display.contentCenterX

            background.y = display.contentCenterY

            local nebula = display.newImageRect( “images/Nebula1.png”, 2732, 2048 )   --2732, 2048

            nebula.x = display.contentCenterX

            nebula.y = display.contentCenterY

            sceneGroup:insert( background )

            sceneGroup:insert( nebula)

 

            local usernameGroup = self.view

 

            local namedesc = display.newText( "User Name: ", 800, 1000, “fonts/nasalization free”, 55)

            namedesc.anchorX = 0

            namedesc:setFillColor( 145/255, 231/255, 255/255 )

 

            local usernameField = native.newTextField( 1400, 1000, 500, 85 )

            usernameField.font = native.newFont( native.systemFontBold, 55 )

            usernameField.text = “”

            usernameField:setTextColor( 0.0, 0.0, 0.0 )

            usernameField:addEventListener( “userInput”, textListener )

 

            usernameGroup:insert( namedesc )

            usernameGroup:insert( usernameField )

 

end

 

function scene:show( event )

 

            local phase = event.phase

           

            if phase == “will” then

 

                        – Called when the scene is still off screen and is about to move on screen.

 

                        print(“buildgame will show.”)

 

                        display.setDefault( “background”, 0.0, 0.0, 0.0 )

 

                       

            elseif phase == “did” then

 

                        – Called when the scene is now on screen

 

                        –

                        – INSERT code here to make the scene come alive

                        – e.g. start timers, begin animation, play audio, etc.

 

                        print(“buildgame did show.”)

 

            end

 

end

 

function scene:hide( event )

 

            local phase = event.phase

           

            if phase == “will” then

 

                        – Called when the scene is on screen and is about to move off screen.

                        –

                        – INSERT code here to pause the scene

                        – e.g. stop timers, stop animation, unload sounds, etc.)

 

                        print(“buildgame will hide.”)

 

            elseif phase == “did” then

 

                        – Called when the scene is now off screen.

 

                        print(“buildgame did hide.”)

 

            end

           

end

 

function scene:destroy( event )

 

            print( “Destroying buildgame’s view!” )

 

end

 


 

– Add event listeners for all of the scene events we want to get called for!

https://docs.coronalabs.com/api/type/EventListener/addEventListener.html

https://docs.coronalabs.com/api/event/scene/index.html

scene:addEventListener( “create”, scene )

scene:addEventListener( “show”, scene )

scene:addEventListener( “hide”, scene )

scene:addEventListener( “destroy”, scene )

 


 

– Finally, we return the scene that we just defined so composer can

– make use of it.

return scene

[/lua]

 

 

The video can be seen here: https://John566.tinytake.com/sf/MTI1ODE4Nl80NzQ0MDA0

 

 

It takes a few seconds to build the random starmap.   There are lots of checks/double checks etc. so this one-time execution takes a few seconds.   It is actually generating a map that is 1000 by 1000 sectors.   And has 500 stars and 1500 planets.   Each star can have between 0-10 planets.   There will be several alien races that are strategically a certain distance from the home star.   And each star must also be a certain distance from other stars.  So there is a lot of checking, double checking, etc. to set the x, y coordinates and then plot them on the map.   But this is only a one-time function when a new game is created.   Also the function saves the image to a jpg that will be available for viewing/scrolling vs rebuilding the map each time.  

 

23 sec into the video buildhome function completes.  So for this instance it took 11 seconds to build the Universe.  But I cant do anything when it returns.   If I click anywhere on the screen it does nothing.   I realize I have no listeners on except the textListener.   But how do get back to scene management and remove the text Listener.   How do I get from textListener to onEventListener?

 

Thank you in advance for any assistance.  

 

In order to move to the next part, do you need to press the enter key, or any other button, you could invoke a keyListener.

No.   I just felt it was cleaner if the scene manager was invoked instead of forcing removescene and then gotoscene immediately after returning from the module.    Also, is there a way to unrequire the module so it gets reloaded brand new?   I have tried setting package.loaded.buildhome = nil but that doesn’t seem to help.

Thanks again

Look at this article on external modules, they cover removal of them:

https://coronalabs.com/blog/2012/08/28/how-external-modules-work-in-corona/

Also, try creating a submit button to force the gotoScene(), it is better than having the error.

Thanks   works now

You were able to remove the module?

Yes.   This function below did what i needed.

[Lua]

local function unrequire(m)

    package.loaded[m] = nil

    _G[m] = nil

end

    local buildhome = require (“scripts.buildhome”)
    unrequire( “scripts.buildhome” )

[/lua]

What “junk” has been left over? When you mean you are stuck in the TextListener, do you mean that when you enter a name it does not let you through?

Also, please use the code formatter when copying code over. It will make your code more understandable. It is the symbol that looks like two opposite-facing brackets.

I made a couple minor modifications to the code to show where and how I get stuck inside the textListener function once it executes the external function.

 

 

[lua]


– buildgame.lua


 

local widget = require( “widget” )                                                                                 --Require Widget library

 

local composer = require( “composer” )                                                                       --Require Composer

 

local myData = require( “scripts.mydata” )                                                        --Require Global Saves

 

local scene = composer.newScene()

 

local function textListener(event)

            if (event.phase == “began”) then

                        – user begins editing textField

                        print (“Begin editing”, event.target.text)

            elseif (event.phase == “ended” or event.phase == “submitted”) then

 

                        print(“event phase :”, event.phase)

 

                        --print ("scene: ", scene)

 

                        --[[if namedesc ~= nil then

                                    namedesc:removeSelf()

                                    namedesc = nil

                        end

 

                        if usernameField ~= nil then

                                    usernameField:removeSelf()

                                    usernameField = nil

                        end

 

                        if usernameGroup ~= nil then

                                    usernameGroup:removeSelf()

                                    usernameGroup = nil

                        end]]

 

                        --errmsg = display.newText( “Building Star Map”, 625, 1900, “fonts/nasalization free”, 55)    

                        --errmsg.anchorX = 0

                --errmsg:setFillColor( 145/255, 231/255, 255/255 )

                if event.phase == “submitted” then

 

                                    native.setKeyboardFocus(nil)

                                    myData.newgame = string.sub(event.target.text, 1, 15)

                                    --print(“Final Text:”, myData.newgame, event.phase)

                        print (“start buildhome”)

               

                                    local buildhome = require (“scripts.buildhome”)

 

                                    print (“end buildhome”)

                        end

 

                        --composer.removeScene( “buildgame” )

                        --composer.gotoScene( “scripts.showmap”, “fade”, 800 )

 

 

            elseif (event.phase == “editing”) then

                        print (event.phase)

 

                        local valid_letter = false

                        if ((event.newCharacters >= “a”) and (event.newCharacters <= “z”)) or 

           ((event.newCharacters >= “A”) and (event.newCharacters <= “Z”)) then

           valid_letter = true

        else

                        errval = display.newText( “Only letters a-z are allowed - please remove”, 225, 1400, “fonts/nasalization free”, 85)   

                            errval.anchorX = 0

                    errval:setFillColor( 145/255, 231/255, 255/255 )

                    sceneGroup:insert( errval)

            end

 

        local txt = event.text           

        if(string.len(txt)>15)then

            txt=string.sub(txt, 1, 15)

            print("txt: ", txt)

            errsiz = display.newText( “Name can be 1 to 15 characters - please shorten”, 325, 1200, “fonts/nasalization free”, 85)   

                            errsiz.anchorX = 0

                    errsiz:setFillColor( 145/255, 231/255, 255/255 )

                    sceneGroup:insert( errsiz)

                else

                        myData.text=txt

        end

            end

end

 

function onEventListener( event )                                                                               --When user taps button this is called

            print( “Going to showmap” )

            composer.removeScene( “buildgame” )

            composer.gotoScene( “scripts.buildgame”, “fade”, 800 )         --Fade and go to Load

end

 

function scene:create( event )                                                                     --Function to create the scene

            print( “buildgame created” )

            local sceneGroup = self.view

 

            local background = nil

            local background = display.newImageRect( “images/starfield.jpg”, 2732, 2048 )   --2732, 2048

            background.x = display.contentCenterX

            background.y = display.contentCenterY

            local nebula = display.newImageRect( “images/Nebula1.png”, 2732, 2048 )   --2732, 2048

            nebula.x = display.contentCenterX

            nebula.y = display.contentCenterY

            sceneGroup:insert( background )

            sceneGroup:insert( nebula)

 

            local usernameGroup = self.view

 

            local namedesc = display.newText( "User Name: ", 800, 1000, “fonts/nasalization free”, 55)

            namedesc.anchorX = 0

            namedesc:setFillColor( 145/255, 231/255, 255/255 )

 

            local usernameField = native.newTextField( 1400, 1000, 500, 85 )

            usernameField.font = native.newFont( native.systemFontBold, 55 )

            usernameField.text = “”

            usernameField:setTextColor( 0.0, 0.0, 0.0 )

            usernameField:addEventListener( “userInput”, textListener )

 

            usernameGroup:insert( namedesc )

            usernameGroup:insert( usernameField )

 

end

 

function scene:show( event )

 

            local phase = event.phase

           

            if phase == “will” then

 

                        – Called when the scene is still off screen and is about to move on screen.

 

                        print(“buildgame will show.”)

 

                        display.setDefault( “background”, 0.0, 0.0, 0.0 )

 

                       

            elseif phase == “did” then

 

                        – Called when the scene is now on screen

 

                        –

                        – INSERT code here to make the scene come alive

                        – e.g. start timers, begin animation, play audio, etc.

 

                        print(“buildgame did show.”)

 

            end

 

end

 

function scene:hide( event )

 

            local phase = event.phase

           

            if phase == “will” then

 

                        – Called when the scene is on screen and is about to move off screen.

                        –

                        – INSERT code here to pause the scene

                        – e.g. stop timers, stop animation, unload sounds, etc.)

 

                        print(“buildgame will hide.”)

 

            elseif phase == “did” then

 

                        – Called when the scene is now off screen.

 

                        print(“buildgame did hide.”)

 

            end

           

end

 

function scene:destroy( event )

 

            print( “Destroying buildgame’s view!” )

 

end

 


 

– Add event listeners for all of the scene events we want to get called for!

https://docs.coronalabs.com/api/type/EventListener/addEventListener.html

https://docs.coronalabs.com/api/event/scene/index.html

scene:addEventListener( “create”, scene )

scene:addEventListener( “show”, scene )

scene:addEventListener( “hide”, scene )

scene:addEventListener( “destroy”, scene )

 


 

– Finally, we return the scene that we just defined so composer can

– make use of it.

return scene

[/lua]

 

 

The video can be seen here: https://John566.tinytake.com/sf/MTI1ODE4Nl80NzQ0MDA0

 

 

It takes a few seconds to build the random starmap.   There are lots of checks/double checks etc. so this one-time execution takes a few seconds.   It is actually generating a map that is 1000 by 1000 sectors.   And has 500 stars and 1500 planets.   Each star can have between 0-10 planets.   There will be several alien races that are strategically a certain distance from the home star.   And each star must also be a certain distance from other stars.  So there is a lot of checking, double checking, etc. to set the x, y coordinates and then plot them on the map.   But this is only a one-time function when a new game is created.   Also the function saves the image to a jpg that will be available for viewing/scrolling vs rebuilding the map each time.  

 

23 sec into the video buildhome function completes.  So for this instance it took 11 seconds to build the Universe.  But I cant do anything when it returns.   If I click anywhere on the screen it does nothing.   I realize I have no listeners on except the textListener.   But how do get back to scene management and remove the text Listener.   How do I get from textListener to onEventListener?

 

Thank you in advance for any assistance.  

 

In order to move to the next part, do you need to press the enter key, or any other button, you could invoke a keyListener.

No.   I just felt it was cleaner if the scene manager was invoked instead of forcing removescene and then gotoscene immediately after returning from the module.    Also, is there a way to unrequire the module so it gets reloaded brand new?   I have tried setting package.loaded.buildhome = nil but that doesn’t seem to help.

Thanks again

Look at this article on external modules, they cover removal of them:

https://coronalabs.com/blog/2012/08/28/how-external-modules-work-in-corona/

Also, try creating a submit button to force the gotoScene(), it is better than having the error.

Thanks   works now

You were able to remove the module?

Yes.   This function below did what i needed.

[Lua]

local function unrequire(m)

    package.loaded[m] = nil

    _G[m] = nil

end

    local buildhome = require (“scripts.buildhome”)
    unrequire( “scripts.buildhome” )

[/lua]