Stumped on Order of execution (yeah, another :removeSelf() question)

Presumably, this code should work:

[code]function group:close()
– Disable touch
group.state = false

– Slide out the object
group.transition = transition.to(group, { y = group.y + group.height, time = 200, onComplete = function()
– On complete, do this stuff
display.getCurrentStage():setFocus(nil)
group:removeSelf()
group = nil – ???
end} )
end[/code]

Basically, slide out, remove itself, and then nil out the data so that group ~= true. However, adding the nil line into the onComplete gives the error that group is nil as of the first command (group.state). This would strike me as completely out of order so I’m just wondering how Corona is interpreting the code and (presumably) where I’m making the order mistake.

[import]uid: 41884 topic_id: 32789 reply_id: 332789[/import]

I think the problem is that you are trying to set the group to nil inside of a function that the group itself called, I would try doing it somewhere else. [import]uid: 181948 topic_id: 32789 reply_id: 130394[/import]

I think the problem is that you are trying to set the group to nil inside of a function that the group itself called, I would try doing it somewhere else. [import]uid: 181948 topic_id: 32789 reply_id: 130394[/import]

No luck. If I move the onComplete function outside (creating a named variable function), like so:

[code]local function closeup(target)
– Release focus
display.getCurrentStage():setFocus(nil)

– Delete the panel
target:removeSelf()
target = nil
end

– and then in the transition use an enclosure to specify the target, like this…
group.transition = transition.to(group, { y = group.y + group.height, time = 200, onComplete = function() closeup(group) end})[/code]

…The error changes, but only because group ~= nil after this code runs. So again, if anyone has an idea of how to gracefully remove+nil an object internally I’d love to hear it! :slight_smile: [import]uid: 41884 topic_id: 32789 reply_id: 130399[/import]

No luck. If I move the onComplete function outside (creating a named variable function), like so:

[code]local function closeup(target)
– Release focus
display.getCurrentStage():setFocus(nil)

– Delete the panel
target:removeSelf()
target = nil
end

– and then in the transition use an enclosure to specify the target, like this…
group.transition = transition.to(group, { y = group.y + group.height, time = 200, onComplete = function() closeup(group) end})[/code]

…The error changes, but only because group ~= nil after this code runs. So again, if anyone has an idea of how to gracefully remove+nil an object internally I’d love to hear it! :slight_smile: [import]uid: 41884 topic_id: 32789 reply_id: 130399[/import]

Hmm sorry that didn’t work.

You could also try removing 'group.transition = ’

transition.to doesn’t have to be set to a variable, and doing so may be causing your problem. It may not, but it’s worth a shot.

-Treb [import]uid: 181948 topic_id: 32789 reply_id: 130402[/import]

Hmm sorry that didn’t work.

You could also try removing 'group.transition = ’

transition.to doesn’t have to be set to a variable, and doing so may be causing your problem. It may not, but it’s worth a shot.

-Treb [import]uid: 181948 topic_id: 32789 reply_id: 130402[/import]

@richard9, I could be wrong, but I have a feeling that your closeup function is fired the moment group.transition is fired (instead of onComplete event.)

This is based on my observation that when I want to assign a function to the onRelease property of a widget button, for example, if I do something like [text]myButton.onRelease = myFunction()[/text], it just fires the moment the function is assigned to the onRelease property (instead of myFunction firing upon tapping on the button.) [Edit] However, if I do [text]myButton.onRelease = myFunction[/text], it works as expected. Not sure if it makes sense to you, but…

Well, even though it looks a bit roundabout way of doing things, if I were you, here’s what I might try. (I haven’t checked if this works, so it may not work at all, but still, I thought… just maybe…)

local closeup {}  
function closeup.now()  
 -- Release focus  
 display.getCurrentStage():setFocus(nil)  
   
 -- Delete the panel  
 display.remove( closeup.target )   
 closeup.target = nil  
end  
   
closeup.target = group  
group.transition = transition.to(group, { y = group.y + group.height, time = 200, onComplete =closeup.now })  

Let me know how it goes if you decide to give it a shot.

Naomi [import]uid: 67217 topic_id: 32789 reply_id: 130406[/import]

@richard9, I could be wrong, but I have a feeling that your closeup function is fired the moment group.transition is fired (instead of onComplete event.)

This is based on my observation that when I want to assign a function to the onRelease property of a widget button, for example, if I do something like [text]myButton.onRelease = myFunction()[/text], it just fires the moment the function is assigned to the onRelease property (instead of myFunction firing upon tapping on the button.) [Edit] However, if I do [text]myButton.onRelease = myFunction[/text], it works as expected. Not sure if it makes sense to you, but…

Well, even though it looks a bit roundabout way of doing things, if I were you, here’s what I might try. (I haven’t checked if this works, so it may not work at all, but still, I thought… just maybe…)

local closeup {}  
function closeup.now()  
 -- Release focus  
 display.getCurrentStage():setFocus(nil)  
   
 -- Delete the panel  
 display.remove( closeup.target )   
 closeup.target = nil  
end  
   
closeup.target = group  
group.transition = transition.to(group, { y = group.y + group.height, time = 200, onComplete =closeup.now })  

Let me know how it goes if you decide to give it a shot.

Naomi [import]uid: 67217 topic_id: 32789 reply_id: 130406[/import]

treb.stewart : Unfortunately, dropping the variable has no effect; group ~= nil either way.

FWIW, assigning transitions to your display objects is a great way to keep track of transitions when exiting a scene; the only problem is just that transitions have to be set to nil after completion (easily accomplished in onComplete)

Naomi : I sort of see what you’re suggesting, which basically is to use a function listener and not a table listener since the latter requires explicit data. In this case it’s a closure so I’m not sure it’s a table, but anyway…

It has the same result as simply calling an outside function, which is that while group.state is no longer questioned, closeup.target ~= nil despite the code you wrote.

Further background : “group”, in this case, is a display group with nested display objects (as sliding panel, such as the overlays you might see when you attempt to reply/forward/print an email in iOS 5. close() drags this panel offscreen and then (hopefully) deletes it. The goal is to nil it out so that later on I can check the variable it’s assigned to and open/close based on whether data is still there, ie:

local function touchButton(event) if event.phase == "ended" and not choosePanel then choosePanel = launchPanel() elseif event.phase == "ended" and choosePanel then choosePanel:close() end end

[import]uid: 41884 topic_id: 32789 reply_id: 130439[/import]

treb.stewart : Unfortunately, dropping the variable has no effect; group ~= nil either way.

FWIW, assigning transitions to your display objects is a great way to keep track of transitions when exiting a scene; the only problem is just that transitions have to be set to nil after completion (easily accomplished in onComplete)

Naomi : I sort of see what you’re suggesting, which basically is to use a function listener and not a table listener since the latter requires explicit data. In this case it’s a closure so I’m not sure it’s a table, but anyway…

It has the same result as simply calling an outside function, which is that while group.state is no longer questioned, closeup.target ~= nil despite the code you wrote.

Further background : “group”, in this case, is a display group with nested display objects (as sliding panel, such as the overlays you might see when you attempt to reply/forward/print an email in iOS 5. close() drags this panel offscreen and then (hopefully) deletes it. The goal is to nil it out so that later on I can check the variable it’s assigned to and open/close based on whether data is still there, ie:

local function touchButton(event) if event.phase == "ended" and not choosePanel then choosePanel = launchPanel() elseif event.phase == "ended" and choosePanel then choosePanel:close() end end

[import]uid: 41884 topic_id: 32789 reply_id: 130439[/import]

@richard9, it is puzzling. I wonder what you see if you do some print-statements. It’s messy business but something like:

local closeup {}  
function closeup.now()  
 print("---------------- INSIDE closeup function ----------------")  
 print("closeup.target = ", closeup.target)  
  
 -- Release focus  
 display.getCurrentStage():setFocus(nil)  
   
 -- Delete the panel  
 display.remove( closeup.target )   
 closeup.target = nil  
  
 print("---------------- AFTER closeup.target is nil'ed ----------------")  
 print("closeup.target = ", closeup.target)  
end  
  
print("-------------- BEFORE group is assigned to closeup.target -----------")  
print("closeup.target = ", closeup.target)  
print("group = ", group)  
  
closeup.target = group  
  
print("-------------- AFTER group is assigned to closeup.target -----------")  
print("closeup.target = ", closeup.target)  
print("group = ", group)  
  
group.transition = transition.to(group, { y = group.y + group.height, time = 200, onComplete =closeup.now })  
  
print("-------------- AFTER group.transition is called -----------")  
print("closeup.target = ", closeup.target)  
print("group = ", group)  

I’m also wondering if you need to remove each elements inside the group before you can remove group and nil it out. I kind of remember reading something about how removing a display group would automatically remove all its children, but maybe it’s not quite working that way?

Naomi [import]uid: 67217 topic_id: 32789 reply_id: 130459[/import]

Since your passing self explicitly you might as well use it :slight_smile:

Also you can add a little check to ensure the object you are trying to manipulate hasn’t already been removed from the stage.

[code]
function group:close()
if self then
– Disable touch
self.state = false

– Slide out the object
self.transition = transition.to(self, { y = self.y + self.height, time = 200, onComplete = function()
– On complete, do this stuff
display.getCurrentStage():setFocus(nil)
self:removeSelf()
self = nil
end} )
end
end
[/code] [import]uid: 84637 topic_id: 32789 reply_id: 130462[/import]

@richard9, it is puzzling. I wonder what you see if you do some print-statements. It’s messy business but something like:

local closeup {}  
function closeup.now()  
 print("---------------- INSIDE closeup function ----------------")  
 print("closeup.target = ", closeup.target)  
  
 -- Release focus  
 display.getCurrentStage():setFocus(nil)  
   
 -- Delete the panel  
 display.remove( closeup.target )   
 closeup.target = nil  
  
 print("---------------- AFTER closeup.target is nil'ed ----------------")  
 print("closeup.target = ", closeup.target)  
end  
  
print("-------------- BEFORE group is assigned to closeup.target -----------")  
print("closeup.target = ", closeup.target)  
print("group = ", group)  
  
closeup.target = group  
  
print("-------------- AFTER group is assigned to closeup.target -----------")  
print("closeup.target = ", closeup.target)  
print("group = ", group)  
  
group.transition = transition.to(group, { y = group.y + group.height, time = 200, onComplete =closeup.now })  
  
print("-------------- AFTER group.transition is called -----------")  
print("closeup.target = ", closeup.target)  
print("group = ", group)  

I’m also wondering if you need to remove each elements inside the group before you can remove group and nil it out. I kind of remember reading something about how removing a display group would automatically remove all its children, but maybe it’s not quite working that way?

Naomi [import]uid: 67217 topic_id: 32789 reply_id: 130459[/import]

Since your passing self explicitly you might as well use it :slight_smile:

Also you can add a little check to ensure the object you are trying to manipulate hasn’t already been removed from the stage.

[code]
function group:close()
if self then
– Disable touch
self.state = false

– Slide out the object
self.transition = transition.to(self, { y = self.y + self.height, time = 200, onComplete = function()
– On complete, do this stuff
display.getCurrentStage():setFocus(nil)
self:removeSelf()
self = nil
end} )
end
end
[/code] [import]uid: 84637 topic_id: 32789 reply_id: 130462[/import]

Danny : But that’s exactly the problem. After running the onComplete code in your example, self is still true. It’s no longer onscreen, but there’s a table in memory so self ~= nil regardless of what was entered in the onComplete function.

(And you’re right, putting in the self code makes it look slightly nicer :slight_smile:

Naomi : Your sample code is going to destroy my mind at this time of day, but I did add some print statements…

[code]-- Assuming this code
local function makePanel()
local group = display.newGroup()
– do stuff, insert objects into group, etc
– add group:close() function
return group
end

local newPanel = makePanel()
[/code]

  1. Prior to the transition line, self = true (a table) – Correct
  2. After the nil line, self = nil – Correct
  3. After group:close() is finished, I use a touch listener on the project background to check the state of the variable used for the function (“newPanel”, in this example) The variable reports back as true (a table) – ??? [import]uid: 41884 topic_id: 32789 reply_id: 130468[/import]

Yeah, self is good. Makes it much simpler, eh? (And sorry about that messy print-statements.) You know, I’m wondering if the makePanel function creates some elements that cannot be inserted to the group, and this particular element is still connected to the newPanel (even though the group itself is removed) … like an image sheet used for an object inserted to the group…

Hmm… but then, makePanel only returns group, so I guess it doesn’t make sense either. How puzzling.

Naomi
[import]uid: 67217 topic_id: 32789 reply_id: 130470[/import]

Danny : But that’s exactly the problem. After running the onComplete code in your example, self is still true. It’s no longer onscreen, but there’s a table in memory so self ~= nil regardless of what was entered in the onComplete function.

(And you’re right, putting in the self code makes it look slightly nicer :slight_smile:

Naomi : Your sample code is going to destroy my mind at this time of day, but I did add some print statements…

[code]-- Assuming this code
local function makePanel()
local group = display.newGroup()
– do stuff, insert objects into group, etc
– add group:close() function
return group
end

local newPanel = makePanel()
[/code]

  1. Prior to the transition line, self = true (a table) – Correct
  2. After the nil line, self = nil – Correct
  3. After group:close() is finished, I use a touch listener on the project background to check the state of the variable used for the function (“newPanel”, in this example) The variable reports back as true (a table) – ??? [import]uid: 41884 topic_id: 32789 reply_id: 130468[/import]

Here you go

local group = display.newGroup()  
  
function group:close()  
 local function clearGroup()  
 group:removeSelf()  
 group = nil  
  
 print( group )  
 end  
  
 -- Slide out the object  
 group.transition = transition.to(group, { y = group.y + group.height, time = 200, onComplete = clearGroup } )  
end  
  
local img = display.newRect( 0, 0, 200, 200 )  
group:insert( img )  
  
group:close()  
  
timer.performWithDelay( 2000, function() print( group ) end )  

Some reading:

http://www.coronalabs.com/blog/2011/07/19/local-variables-lua/
http://stackoverflow.com/questions/8392168/lua-metatable-class-destructor
[import]uid: 84637 topic_id: 32789 reply_id: 130471[/import]

Yeah, self is good. Makes it much simpler, eh? (And sorry about that messy print-statements.) You know, I’m wondering if the makePanel function creates some elements that cannot be inserted to the group, and this particular element is still connected to the newPanel (even though the group itself is removed) … like an image sheet used for an object inserted to the group…

Hmm… but then, makePanel only returns group, so I guess it doesn’t make sense either. How puzzling.

Naomi
[import]uid: 67217 topic_id: 32789 reply_id: 130470[/import]