Can't see why enterscene is running twice with my code Any suggestions ?

When I run my app with this scene in it the “function scene:enterScene(event)” runs twice. I’m not seeing why it runs twice. Any ideas ?

thanks …

[code]
local storyboard = require(“storyboard”)
local scene = storyboard.newScene()

local widget = require"widget"

– BEGINNING OF YOUR IMPLEMENTATION

local backgroudImage, memLabel, sortByButton

local function goToMainMenu(self, event)
if event.phase == “began” then
storyboard.gotoScene(false, “mainmenu”, “fade”, 400)
return true
end
end

local function setSortButton(self, event)
print(“Entering SetSortbutton”)
sortByButton = ui.newButton {
default = “sortby”…_G.jobsSortBy…".png"
}
sortByButton.x, sortByButton.y = (100), 50
sortByButton.touch = changeSortOrder
end

local function changeSortOrder(self, event)
if event.phase == “began” then
if _G.jobsSortBy == “position” then
_G.jobsSortBy = “company”
else
_G.jobsSortBy = “position”
end
setSortButton()
end
end

– Called when the scene’s view does not exist:
function scene:createScene(event)
local screenGroup = self.view

backgroundImage = display.newImage(“aojtbackground.png”)
screenGroup:insert(backgroundImage)

local listOptions = {
top = 70,
height = 360,
maskFile = “listmask.png”
}

local list = widget.newTableView(listOptions)
screenGroup:insert(list)

for row in db:nrows("select * from jobs order by "…_G.jobsSortBy) do
local rowHeight, rowColor, lineColor, isCategory

– onRender listener for the tableView
local function onRowRender(event)
local listRow = event.target
local rowGroup = event.view

local rowContent = display.newRetinaText(row.company … " - " … row.contact, 12, 0, native.systemFont, 14)
rowContent:setReferencePoint(display.CenterLeftReferencePoint)
rowContent.y = listRow.height * 0.5
rowContent.x = 15
rowContent:setTextColor(0)
rowGroup:insert(rowContent)
end

local function onRowTouch(event)
if event.phase == “release” then
_G.jobsIndex = row.company
storyboard.gotoScene(“jobsdetail”, “fade”, 400)
end
end

rowColor = { 230, 255, 255, 255 }

list:insertRow{
id = row.company,
height = 32,
rowColor = rowColor,
onRender = onRowRender,
onEvent = onRowTouch
}
end

– *****************
goBackButton = ui.newButton{
default = “backarrow.png”
}
goBackButton.x = 30
goBackButton.y = 20
goBackButton.touch = goToMainMenu
screenGroup:insert(goBackButton)

title = display.newText(“AOJT - Jobs”, 0, 0, native.systemFont, _G.titleFont)
title:setTextColor(0)
title:setReferencePoint(display.CenterReferencePoint)
title.x, title.y = display.contentWidth * 0.5, 20
screenGroup:insert(title)

addNew = display.newText(“Add NEW”, 0, 0, native.systemFont, 14)
addNew:setTextColor(0)
addNew:setReferencePoint(display.CenterLeftReferencePoint)
addNew.x, addNew.y = (3 * niceMargin) + 220, 50
screenGroup:insert(addNew)
end

– Called immediately after scene has moved onscreen:
function scene:enterScene(event)
print(“enter scene”)
setSortButton()
end

– Called when scene is about to move offscreen:
function scene:exitScene()
sortByButton:removeSelf()
end

– Called prior to the removal of scene’s “view” (display group)
function scene:destroyScene(event)
end


– END OF YOUR IMPLEMENTATION

scene:addEventListener(“createScene”, scene)
scene:addEventListener(“enterScene”, scene)
scene:addEventListener(“exitScene”, scene)
scene:addEventListener(“destroyScene”, scene)

return scene
[/code] [import]uid: 101604 topic_id: 31441 reply_id: 331441[/import]

where is your code that calls this scene? [import]uid: 19626 topic_id: 31441 reply_id: 125672[/import]

Thank you for looking - the first code posted is called “jobs.lua”. This piece that calls it is “mainmenu.lua”.

[code]

local storyboard = require( “storyboard” )
local scene = storyboard.newScene()


– BEGINNING OF YOUR IMPLEMENTATION

local backgroundImage, memLabel

local function gotoJobs( self, event )
if event.phase == “began” then
storyboard.gotoScene( “jobs”, “fade”, 400 )
return true
end
end

local function gotoIt( self, event) – this is the auto one.
storyboard.gotoScene(“jobs”, “fade”, 200 )
end

local function gotoPhoneCalls( self, event )
if event.phase == “began” then
storyboard.gotoScene( “phonecalls”, “fade”, 400 )
return true
end
end

local function gotoInterviews( self, event )
if event.phase == “began” then
storyboard.gotoScene( “interviews”, “fade”, 400 )
return true
end
end

–[[
local function gotoReports( self, event )
if event.phase == “began” then
storyboard.gotoScene( “reports”, “fade”, 400 )
return true
end
end

local function exitApp(event)
os.exit()
end
]]–

function scene:createScene( event )
local screenGroup = self.view

local buttonSpacing = 60

backgroundImage = display.newImage( “aojtbackground.png” )
screenGroup:insert( backgroundImage )

local title = display.newText(“All Out Job Tracker”, 5,0, nil, 32)
title:setReferencePoint( display.CenterReferencePoint )
title.x = display.contentWidth / 2
title.y = 50
title:setTextColor(0,0,0)
screenGroup:insert(title)

jobsButton = ui.newButton {
default = “jobsbutton.png”
}
jobsButton.x = display.contentWidth * 0.5
jobsButton.y = 150
jobsButton.width = 220
jobsButton.touch = gotoJobs
screenGroup:insert(jobsButton)

interviewsButton = ui.newButton {
default = “interviewsbutton.png”
}
interviewsButton.x = display.contentWidth * 0.5
interviewsButton.y = jobsButton.y + buttonSpacing
interviewsButton.width = 220
interviewsButton.touch = gotoInterviews
screenGroup:insert(interviewsButton)

phonecallsButton = ui.newButton {
default = “phonecallsbutton.png”
}
phonecallsButton.x = display.contentWidth * 0.5
phonecallsButton.y = interviewsButton.y + buttonSpacing
phonecallsButton.width = 220
phonecallsButton.touch = gotoPhoneCalls
screenGroup:insert(phonecallsButton)

–[[
reportsButton = ui.newButton {
default = “reportsbutton.png”
}
reportsButton.x = display.contentWidth * 0.5
reportsButton.y = phonecallsButton.y + buttonSpacing
reportsButton.width = 220
reportsButton.touch = gotoReports
screenGroup:insert(reportsButton)
]]–

exitButton = ui.newButton {
default = “exitbutton.png”
}
exitButton.x = display.contentWidth * 0.5
exitButton.y = phonecallsButton.y + buttonSpacing
exitButton.width = 220
exitButton.touch = exitApp
screenGroup:insert(exitButton)

end

– Called immediately after scene has moved onscreen:
function scene:enterScene( event )
if _G.zdebugAuto then
local memTimer = timer.performWithDelay( 500, gotoIt, 1 )
end
end

– Called when scene is about to move offscreen:
function scene:exitScene( event )
end

– Called prior to the removal of scene’s “view” (display group)
function scene:destroyScene( event )
end


– END OF YOUR IMPLEMENTATION

scene:addEventListener( “createScene”, scene )
scene:addEventListener( “enterScene”, scene )
scene:addEventListener( “exitScene”, scene )
scene:addEventListener( “destroyScene”, scene )


return scene
[/code] [import]uid: 101604 topic_id: 31441 reply_id: 125733[/import]

I think the problem is in how you’re using ui.newButton…

The code for that button adds its own touch handler and you’re adding your own touch handler.

The ui.lua code that I have expects a parameter called onRelease=yourbuttonhandler, something like:

 jobsButton = ui.newButton {  
 default = "jobsbutton.png",  
 onRelease = gotoJobs  
 }  

You would then remove the line:

 jobsButton.touch = gotoJobs  

because ui.newButton is doing that for you. I suspect you would also need to modify your function on button press too:

local function gotoJobs( self, event )  
 if event.phase == "release" then  
 storyboard.gotoScene( "jobs", "fade", 400 )  
 end  
 return true -- notice I moved this....  
end  

The ui.newButton module is looking for touch events. On the began event, it shows the alternate graphic for the button down state (that you’re not using… it is optional) and then on the “ended” phase of the touch event, it calls your onRelease function but event.phase is now “release” rather than “ended”. So you can’t check for began and ended.

Finally, the return true needs to be outside the if statement, right before the end, if not the other event states that are generated will end up propgating to whatever is underneath the button (likely your background).
[import]uid: 19626 topic_id: 31441 reply_id: 125737[/import]

Thanks - I understand this. I made the changes as you suggested and it then gives the error:

mainmenu.lua:13: attempt to index local ‘event’ (a nil value)

If I comment out the test for the event phase like this it works without error:

local function gotoJobs( self, event)  
 -- if event.phase == "release" then  
 storyboard.gotoScene("jobs", "fade", 200)  
 -- end  
 return true  
end  

Because of the statement “onRelease = gotoJobs” in the ui.newButton declaration, would the test for event.phase not be needed - because it would be set to only be called “on release” ?

And then could the “return true” be removed for the same reason - it’s only called on the “onRelease”?
[import]uid: 101604 topic_id: 31441 reply_id: 125742[/import]

The reason the event is causing issues is that the uiButton calls it’s event handlers with this signature

callback(event)

But you expect

callback(callerObject, event)

and so, the event parameter from the touch is actually self in your function.

You can drop the self parameter, or if you really need it there is a neat helper function you can use:

local function wrapParam(funcPtr, param)  
 return function(...)  
 return funcPtr(param, ...)  
 end  
end  

It returns a function that has it’s first parameter assigned in advance, allowing you to use it to create callbacks that have extra parameters outside of the event returned by Corona.

Which can be used like:

local callback = wrapParam(onTouch, obj) --This creates a function that calls onTouch( obj, [parameters of function])  
callback(event) --This now calls onTouch(obj, event)  

Edit:
You should be returning true, as per the docs. If you don’t return anything it will default to ‘nil’ or false, meaning that you did not consume the event (and it could be sent to an object underneath). [import]uid: 134101 topic_id: 31441 reply_id: 125743[/import]

Thanks to both of you, I adjusted the code per all the suggestions.

In the meantime I think I’ve found out the answer to my original question - Running Twice - that continued to happen after the above code changes were implemented. I’m currently using CIder v1.4.9 as my editor/project manager. I found that if I edited mainmenu.lua, even if just adding a blank line in, the run twice didn’t happen. Then if I edit it again the run twice is back.

I’m thinking it’s running twice because the print(“enter scene”) statement is printing to the console twice.

BUT - after finding this quirky operation I opened it in Corona Project Manager - and I couldn’t make it happen there. So I’m going with a quirk of Cider for now.

thanks again.
[import]uid: 101604 topic_id: 31441 reply_id: 125748[/import]

Cider does like to double print things.

I haven’t noticed that with Cider, er Glider 1.7, though when I download 924 in a bit it’s going to break those tools since prints will no longer go to STDOUT but be logged to system messages via NS_LOG [import]uid: 19626 topic_id: 31441 reply_id: 125749[/import]

where is your code that calls this scene? [import]uid: 19626 topic_id: 31441 reply_id: 125672[/import]

Thank you for looking - the first code posted is called “jobs.lua”. This piece that calls it is “mainmenu.lua”.

[code]

local storyboard = require( “storyboard” )
local scene = storyboard.newScene()


– BEGINNING OF YOUR IMPLEMENTATION

local backgroundImage, memLabel

local function gotoJobs( self, event )
if event.phase == “began” then
storyboard.gotoScene( “jobs”, “fade”, 400 )
return true
end
end

local function gotoIt( self, event) – this is the auto one.
storyboard.gotoScene(“jobs”, “fade”, 200 )
end

local function gotoPhoneCalls( self, event )
if event.phase == “began” then
storyboard.gotoScene( “phonecalls”, “fade”, 400 )
return true
end
end

local function gotoInterviews( self, event )
if event.phase == “began” then
storyboard.gotoScene( “interviews”, “fade”, 400 )
return true
end
end

–[[
local function gotoReports( self, event )
if event.phase == “began” then
storyboard.gotoScene( “reports”, “fade”, 400 )
return true
end
end

local function exitApp(event)
os.exit()
end
]]–

function scene:createScene( event )
local screenGroup = self.view

local buttonSpacing = 60

backgroundImage = display.newImage( “aojtbackground.png” )
screenGroup:insert( backgroundImage )

local title = display.newText(“All Out Job Tracker”, 5,0, nil, 32)
title:setReferencePoint( display.CenterReferencePoint )
title.x = display.contentWidth / 2
title.y = 50
title:setTextColor(0,0,0)
screenGroup:insert(title)

jobsButton = ui.newButton {
default = “jobsbutton.png”
}
jobsButton.x = display.contentWidth * 0.5
jobsButton.y = 150
jobsButton.width = 220
jobsButton.touch = gotoJobs
screenGroup:insert(jobsButton)

interviewsButton = ui.newButton {
default = “interviewsbutton.png”
}
interviewsButton.x = display.contentWidth * 0.5
interviewsButton.y = jobsButton.y + buttonSpacing
interviewsButton.width = 220
interviewsButton.touch = gotoInterviews
screenGroup:insert(interviewsButton)

phonecallsButton = ui.newButton {
default = “phonecallsbutton.png”
}
phonecallsButton.x = display.contentWidth * 0.5
phonecallsButton.y = interviewsButton.y + buttonSpacing
phonecallsButton.width = 220
phonecallsButton.touch = gotoPhoneCalls
screenGroup:insert(phonecallsButton)

–[[
reportsButton = ui.newButton {
default = “reportsbutton.png”
}
reportsButton.x = display.contentWidth * 0.5
reportsButton.y = phonecallsButton.y + buttonSpacing
reportsButton.width = 220
reportsButton.touch = gotoReports
screenGroup:insert(reportsButton)
]]–

exitButton = ui.newButton {
default = “exitbutton.png”
}
exitButton.x = display.contentWidth * 0.5
exitButton.y = phonecallsButton.y + buttonSpacing
exitButton.width = 220
exitButton.touch = exitApp
screenGroup:insert(exitButton)

end

– Called immediately after scene has moved onscreen:
function scene:enterScene( event )
if _G.zdebugAuto then
local memTimer = timer.performWithDelay( 500, gotoIt, 1 )
end
end

– Called when scene is about to move offscreen:
function scene:exitScene( event )
end

– Called prior to the removal of scene’s “view” (display group)
function scene:destroyScene( event )
end


– END OF YOUR IMPLEMENTATION

scene:addEventListener( “createScene”, scene )
scene:addEventListener( “enterScene”, scene )
scene:addEventListener( “exitScene”, scene )
scene:addEventListener( “destroyScene”, scene )


return scene
[/code] [import]uid: 101604 topic_id: 31441 reply_id: 125733[/import]

I think the problem is in how you’re using ui.newButton…

The code for that button adds its own touch handler and you’re adding your own touch handler.

The ui.lua code that I have expects a parameter called onRelease=yourbuttonhandler, something like:

 jobsButton = ui.newButton {  
 default = "jobsbutton.png",  
 onRelease = gotoJobs  
 }  

You would then remove the line:

 jobsButton.touch = gotoJobs  

because ui.newButton is doing that for you. I suspect you would also need to modify your function on button press too:

local function gotoJobs( self, event )  
 if event.phase == "release" then  
 storyboard.gotoScene( "jobs", "fade", 400 )  
 end  
 return true -- notice I moved this....  
end  

The ui.newButton module is looking for touch events. On the began event, it shows the alternate graphic for the button down state (that you’re not using… it is optional) and then on the “ended” phase of the touch event, it calls your onRelease function but event.phase is now “release” rather than “ended”. So you can’t check for began and ended.

Finally, the return true needs to be outside the if statement, right before the end, if not the other event states that are generated will end up propgating to whatever is underneath the button (likely your background).
[import]uid: 19626 topic_id: 31441 reply_id: 125737[/import]

Thanks - I understand this. I made the changes as you suggested and it then gives the error:

mainmenu.lua:13: attempt to index local ‘event’ (a nil value)

If I comment out the test for the event phase like this it works without error:

local function gotoJobs( self, event)  
 -- if event.phase == "release" then  
 storyboard.gotoScene("jobs", "fade", 200)  
 -- end  
 return true  
end  

Because of the statement “onRelease = gotoJobs” in the ui.newButton declaration, would the test for event.phase not be needed - because it would be set to only be called “on release” ?

And then could the “return true” be removed for the same reason - it’s only called on the “onRelease”?
[import]uid: 101604 topic_id: 31441 reply_id: 125742[/import]

The reason the event is causing issues is that the uiButton calls it’s event handlers with this signature

callback(event)

But you expect

callback(callerObject, event)

and so, the event parameter from the touch is actually self in your function.

You can drop the self parameter, or if you really need it there is a neat helper function you can use:

local function wrapParam(funcPtr, param)  
 return function(...)  
 return funcPtr(param, ...)  
 end  
end  

It returns a function that has it’s first parameter assigned in advance, allowing you to use it to create callbacks that have extra parameters outside of the event returned by Corona.

Which can be used like:

local callback = wrapParam(onTouch, obj) --This creates a function that calls onTouch( obj, [parameters of function])  
callback(event) --This now calls onTouch(obj, event)  

Edit:
You should be returning true, as per the docs. If you don’t return anything it will default to ‘nil’ or false, meaning that you did not consume the event (and it could be sent to an object underneath). [import]uid: 134101 topic_id: 31441 reply_id: 125743[/import]

Thanks to both of you, I adjusted the code per all the suggestions.

In the meantime I think I’ve found out the answer to my original question - Running Twice - that continued to happen after the above code changes were implemented. I’m currently using CIder v1.4.9 as my editor/project manager. I found that if I edited mainmenu.lua, even if just adding a blank line in, the run twice didn’t happen. Then if I edit it again the run twice is back.

I’m thinking it’s running twice because the print(“enter scene”) statement is printing to the console twice.

BUT - after finding this quirky operation I opened it in Corona Project Manager - and I couldn’t make it happen there. So I’m going with a quirk of Cider for now.

thanks again.
[import]uid: 101604 topic_id: 31441 reply_id: 125748[/import]

Cider does like to double print things.

I haven’t noticed that with Cider, er Glider 1.7, though when I download 924 in a bit it’s going to break those tools since prints will no longer go to STDOUT but be logged to system messages via NS_LOG [import]uid: 19626 topic_id: 31441 reply_id: 125749[/import]