Jump to content

[TOPIC: topicViewTemplate]
[GLOBAL: userSmallPhoto]
Photo

onComplete method for composer.showOverlay( )?
Started by sporkfin Jan 19 2018 10:38 AM

16 replies to this topic

Best Answer roaminggamer , 19 January 2018 - 12:05 PM

BEWARE my code IS NOT standard.  I always split show and hide events into two functions each:

local composer       = require( "composer" )
local scene          = composer.newScene()

function scene:create( event )
   local sceneGroup = self.view
end

function scene:willShow( event )
   local sceneGroup = self.view
end

function scene:didShow( event )
   local sceneGroup = self.view
end

function scene:willHide( event )
   local sceneGroup = self.view
end

function scene:didHide( event )
   local sceneGroup = self.view
end

function scene:destroy( event )
   local sceneGroup = self.view
end

---------------------------------------------------------------------------------
-- Scene Dispatch Events, Etc. - Generally Do Not Touch Below This Line
---------------------------------------------------------------------------------
-- This code splits the "show" event into two separate events: willShow and didShow
-- for ease of coding above.
function scene:show( event )
   local sceneGroup  = self.view
   local willDid  = event.phase
   if( willDid == "will" ) then
      self:willShow( event )
   elseif( willDid == "did" ) then
      self:didShow( event )
   end
end

-- This code splits the "hide" event into two separate events: willHide and didHide
-- for ease of coding above.
function scene:hide( event )
   local sceneGroup  = self.view
   local willDid  = event.phase
   if( willDid == "will" ) then
      self:willHide( event )
   elseif( willDid == "did" ) then
      self:didHide( event )
   end
end
scene:addEventListener( "create", scene )
scene:addEventListener( "show", scene )
scene:addEventListener( "hide", scene )
scene:addEventListener( "destroy", scene )
---------------------------------------------------------------------------------
return scene

[TOPIC CONTROLS]
This topic has been archived. This means that you cannot reply to this topic.
[/TOPIC CONTROLS]
[modOptionsDropdown]
[/modOptionsDropdown]
[reputationFilter]
[TOPIC: post.html]
#1

sporkfin

[GLOBAL: userInfoPane.html]
sporkfin
  • Contributor

  • 824 posts
  • Corona SDK

I'm looking for a way to determine that my overlay has completed its transition onto the screen.

 

Basically, I want to pause the game when the overlay finishes transitioning.  Right now I just use a timer.performWithDelay( ) with a delay that matches the transition time but it seems like there could exist a more elegant solution - like an onComplete method or something.

 

Any thoughts?



[TOPIC: post.html]
#2

roaminggamer

[GLOBAL: userInfoPane.html]
roaminggamer
  • Corona Geek

  • 7,673 posts
  • Corona SDK

[TOPIC: post.html]
#3

roaminggamer

[GLOBAL: userInfoPane.html]
roaminggamer
  • Corona Geek

  • 7,673 posts
  • Corona SDK

  Best Answer

BEWARE my code IS NOT standard.  I always split show and hide events into two functions each:

local composer       = require( "composer" )
local scene          = composer.newScene()

function scene:create( event )
   local sceneGroup = self.view
end

function scene:willShow( event )
   local sceneGroup = self.view
end

function scene:didShow( event )
   local sceneGroup = self.view
end

function scene:willHide( event )
   local sceneGroup = self.view
end

function scene:didHide( event )
   local sceneGroup = self.view
end

function scene:destroy( event )
   local sceneGroup = self.view
end

---------------------------------------------------------------------------------
-- Scene Dispatch Events, Etc. - Generally Do Not Touch Below This Line
---------------------------------------------------------------------------------
-- This code splits the "show" event into two separate events: willShow and didShow
-- for ease of coding above.
function scene:show( event )
   local sceneGroup  = self.view
   local willDid  = event.phase
   if( willDid == "will" ) then
      self:willShow( event )
   elseif( willDid == "did" ) then
      self:didShow( event )
   end
end

-- This code splits the "hide" event into two separate events: willHide and didHide
-- for ease of coding above.
function scene:hide( event )
   local sceneGroup  = self.view
   local willDid  = event.phase
   if( willDid == "will" ) then
      self:willHide( event )
   elseif( willDid == "did" ) then
      self:didHide( event )
   end
end
scene:addEventListener( "create", scene )
scene:addEventListener( "show", scene )
scene:addEventListener( "hide", scene )
scene:addEventListener( "destroy", scene )
---------------------------------------------------------------------------------
return scene

Edited by roaminggamer, 19 January 2018 - 12:07 PM.


[TOPIC: post.html]
#4

SGS

[GLOBAL: userInfoPane.html]
SGS
  • Corona Geek

  • 2,219 posts
  • Corona SDK

Topical answer... use storyboard.

 

I use it (well a "customised to what I want" version) in all my games as mainly because it posts back overlay "began" and "ended" events to my main scene.  In an OOP world overlays should never know about the calling scene ( an external dev should be able to code an overlay without ever knowing how it is being used).

 

My games have a single scene and everything else is an overlay.

 

Composer is not designed for this schema so I don't use it.



[TOPIC: post.html]
#5

sporkfin

[GLOBAL: userInfoPane.html]
sporkfin
  • Contributor

  • 824 posts
  • Corona SDK

Thanks Ed and Adrian.  I'll give it a shot!

 

@sgs - apparently, storyboard has been deprecated and replaced with composer.  Are you still using storyboard - the API's still work?



[TOPIC: post.html]
#6

roaminggamer

[GLOBAL: userInfoPane.html]
roaminggamer
  • Corona Geek

  • 7,673 posts
  • Corona SDK

@sporkfin,

 

I think the code I gave will solve the issue you have, but you can still get the storyboard.lua file here: https://github.com/coronalabs/framework-storyboard-legacy



[TOPIC: post.html]
#7

sporkfin

[GLOBAL: userInfoPane.html]
sporkfin
  • Contributor

  • 824 posts
  • Corona SDK

@roaminggamer,

 

Your solution worked like a charm!  I was using the standard "will" and "did" phases but could never get them to work properly for this issue.  Your code worked on the first try.  Thanks!



[TOPIC: post.html]
#8

laurasweet8888

[GLOBAL: userInfoPane.html]
laurasweet8888
  • Contributor

  • 125 posts
  • Corona SDK

Topical answer... use storyboard.

 

I use it (well a "customised to what I want" version) in all my games as mainly because it posts back overlay "began" and "ended" events to my main scene.  In an OOP world overlays should never know about the calling scene ( an external dev should be able to code an overlay without ever knowing how it is being used).

 

My games have a single scene and everything else is an overlay.

 

Composer is not designed for this schema so I don't use it.

 

Why can't you just pass a function to the popup and have it run after the "did".  Wouldn't that still maintain your OOP concept?  The popup routine would just run some function if it was there.  function seems like it would be the same as your listener event.  tomato tomato.  



[TOPIC: post.html]
#9

SGS

[GLOBAL: userInfoPane.html]
SGS
  • Corona Geek

  • 2,219 posts
  • Corona SDK

No as it would closely couple the child to the parent. As the child would have to store 2 callbacks (one for began and one for ended).

 

Maybe I should add that I have modified storyboard some 40% to fit what I need (this was still easier then writing a scene manager from scratch).

 

Keeping things real simple.... assume an overlay existed to prompt the user to a yes/no question.  The popup should NOT be responsible for actioning the yes/no (i.e. doing any work) as that is the responsibility of the parent.  Using this design, the same (dumb) overlay merely prompts the user for input and returns to the parent the users response. This single overlay can then be called under many different scenarios as it is ONLY responsible for handling user input.

 

Extending this, the overlay I designed to handle user input can be added to any project (without any modification) and this promotes code reuse.

 

This is one of the main principles of OOP design.



[TOPIC: post.html]
#10

laurasweet8888

[GLOBAL: userInfoPane.html]
laurasweet8888
  • Contributor

  • 125 posts
  • Corona SDK

I agree that the popup shouldn't do the work.  Just send back responses.  But unless it is a dumb yes/no panel you are going to have to pass data to it so it knows what to display.  Passing 2 more fields which doesn't seem that crazy to me.  It would still be a generic popup function as it would just call the function if present.  In your model what happens.  You set a field somewhere and then call a listener which triggers the parent to process the field?   Where is somewhere?  

 

The reason all this interests me is I am using showOverlay for the first time and I don't see an easy way of passing data back to the parent.  I see they have a great way of passing data to the overlay in event.params.   But what is the great way of passing the answers back?   I see some composer global variables.  that seems clunky at best and I see a call back to a function defined to a scene.  Now that is the worst idea I have seen.  Now that ties the overlay to the parent in the worst way.  

 

My current thought is to pass a function in the params that is the callback onComplete of the overlay.  Then when the overlay is done it would call the function and pass the answers back as function parms.  The callback would resume the game and process the answers to the question which was asked.   Does this make any sense?   I feel like everyone has solved these problems long ago and I am just playing catch up all the time.   But composer should have this stuff as part of it so I don't have to make up stuff.   :(  



[TOPIC: post.html]
#11

SGS

[GLOBAL: userInfoPane.html]
SGS
  • Corona Geek

  • 2,219 posts
  • Corona SDK

There are plenty of ways of doing things....  In my case I have a single scene with 20 odd overlays.  In my main scene I have scene:overlayBegan() which is automatically called (by storyboard.lua) and that is responsible for doing everything I need when showing an overlay - things like stopping listeners, etc.

 

When an overlay closes scene:overlayEnded() is again automatically called and handles post overlay processing.  I do have a structure that I fill with data in my overlays and use that to pass data back to my main scene.  

 

This way I only have 2 functions to handle overlays and it keeps it organised and "simple".  No passing functions around or having a call back function for each overlay in my main scene.



[TOPIC: post.html]
#12

davebollinger

[GLOBAL: userInfoPane.html]
davebollinger
  • Corona Geek

  • 1,373 posts
  • Corona SDK

I have modified storyboard some 40% to fit what I need

 

fwiw, i do same - having access to source makes it no-contest vs composer.  (plus i never needed composer-gui anyway)



[TOPIC: post.html]
#13

Rob Miracle

[GLOBAL: userInfoPane.html]
Rob Miracle
  • Moderator

  • 26,697 posts
  • Enterprise

 

The reason all this interests me is I am using showOverlay for the first time and I don't see an easy way of passing data back to the parent.  I see they have a great way of passing data to the overlay in event.params.   But what is the great way of passing the answers back?   I see some composer global variables.  that seems clunky at best and I see a call back to a function defined to a scene.  Now that is the worst idea I have seen.  Now that ties the overlay to the parent in the worst way.  

 

 

@laurasweet8888 we have a great example in the Composer Guide in the Overlay's section:

 

https://docs.coronalabs.com/guide/system/composer/index.html#overlays

 

Basically, you create a function (or functions) in your parent scene and attach it to the scene object:

-- parent scene
function scene:myFunction( myParams )
...
end

Then in your overlay:

function scene:hide( event )
    local sceneGroup = self.view
    local phase = event.phase
    local parent = event.parent  --reference to the parent scene object
 
    if ( phase == "will" ) then
        -- Call the "resumeGame()" function in the parent scene
        parent:myFunction(myParams to pass back)
    end
end

You can have many functions or data values in the parent scene and access/update them from the overlay.

 

Rob

Then in the overlay scene, 



[TOPIC: post.html]
#14

SGS

[GLOBAL: userInfoPane.html]
SGS
  • Corona Geek

  • 2,219 posts
  • Corona SDK

fwiw, i do same - having access to source makes it no-contest vs composer.  (plus i never needed composer-gui anyway)

 

Bespoke is the only way to get what you want.....

 

For example, in my latest game (almost to be released) I allow the player to tap and drag objects from overlay to the parent - the UI is real slick (even if I do say so myself) - but I have to defer the overlay closing ( and clearing down) by a few seconds to avoid a stall when performing the drag.  The overlay allocates some 30+mb and the GC was a killer!

 

Here is the result (the farm house is being dragged)

 

Attached File  Image1.png   717.88KB   0 downloads



[TOPIC: post.html]
#15

davebollinger

[GLOBAL: userInfoPane.html]
davebollinger
  • Corona Geek

  • 1,373 posts
  • Corona SDK

I always split show and hide events into two functions each:


you've reinvented storyboard! :D

(my opinion too btw, am on record at the time re converting 4 events to 2-with-2-phases was of ? value)



[TOPIC: post.html]
#16

davebollinger

[GLOBAL: userInfoPane.html]
davebollinger
  • Corona Geek

  • 1,373 posts
  • Corona SDK

 the UI is real slick (even if I do say so myself) 

i'll say it too, just so you don't feel guilty.  :D   (well, also because it's deserved)



[TOPIC: post.html]
#17

laurasweet8888

[GLOBAL: userInfoPane.html]
laurasweet8888
  • Contributor

  • 125 posts
  • Corona SDK

@dave,  That looks very nice.  

 

@SGS,  It seems like you have one function that processes all the data from whichever overlay just ended.  All 20 of them.  I guess that keeps it all in one place.  I assume there is an big if (type of overlay) that does the right thing depending on what just ended.  

 

@All,   thanks for the thoughts.  In the end, a function needs to run to process returned parms.   Whether that is attached to the scene object,  passed as a parm, or just one function for every overlay.   I was thinking of treating these overlays like the onComplete function of a transition.  Just pass the function to run when the overlay has ended.  But I could see some value in keeping everything in one big function.  Whether or not you reference the function from the scene parent is personal taste I guess.  

 

L




[topic_controls]
[/topic_controls]