Quick Links: Download Gideros Studio | Gideros Documentation | Gideros community chat | DONATE
collectgarbage() do nothing and related listeners problem in SceneManager — Gideros Forum

collectgarbage() do nothing and related listeners problem in SceneManager

nat12nat12 Member
edited December 2011 in Bugs and issues
Hello,

I am using the SceneManager (v1.0.1 with collectgarbage) and discovered the old scenes do remain in memory also after the scene change (also after 3 or more scene changes, if they happen in short succession), it is eventually freed only after a random delay, supposedly when the background garbage collector do its work.

This is not a problem for the memory occupation, but i have also found the event listeners of the old scene are still called until the scene is eventually destroyed for real...
Any suggestion for a workaround? (the only solution I have found is to manually remove all listeners before to call changeScene, but this is tedious and error prone)

Comments

  • atilimatilim Maintainer
    Hi nat,

    First of all, upgrade your Scene Manager to v1.0.3 from here: https://github.com/gideros/Scene-Manager

    Here, there are 4 types of events that your scene can register:
    - enterBegin
    - enterEnd
    - exitBegin
    - exitEnd


    The "exitBegin" event is very appropriate for stopping your times, removing your listeners etc. Similarly, "enterEnd" is appropriate for registering your events, starting your timers etc. (here is a bit more explanation: http://www.giderosmobile.com/blog/2011/11/17/gideros-scene-manager/)

    Let me given an example:
    MyScene = gideros.class(Sprite)
     
    function MyScene:init()
      self:addEventListener("enterEnd", self.onEnterEnd, self)
      self:addEventListener("exitBegin", self.onExitBegin, self)
    end
     
    function MyScene:enterEnd()
      self:addEventListener(Event.ENTER_FRAME, self.onEnterFrame, self)
      -- create your timers
      -- also you can add your player sprite
      -- and so on...
    end
     
    function MyScene:exitBegin()
      self:removeEventListener(Event.ENTER_FRAME, self.onEnterFrame, self)
      -- stop your timers
      -- save score
      -- and so on...
    end
     
    function MyScene:onEnterFrame()
    end

    On the other hand, ENTER_FRAME event is dispatched even when the sprite is _not_ on the stage. (When the sprite is collected, the dispatching of ENTER_FRAME stops). If you want to dispatch ENTER_FRAME only while the sprite is attached to the stage, you can use this method:
    MySprite = gideros.class(Sprite)
     
    function MySprite:init()
      self:addEventListener(Event.ADDED_TO_STAGE, self.onAddedToStage, self)
      self:addEventListener(Event.REMOVED_FROM_STAGE, self.onRemovedFromStage, self)
    end
     
    function MySprite:onAddedToStage()
      self:addEventListener(Event.ENTER_FRAME, self.onEnterFrame, self)
    end
     
    function MySprite:onRemovedFromStage()
      self:removeEventListener(Event.ENTER_FRAME, self.onEnterFrame, self)
    end
     
    function MySprite:onEnterFrame()
    end

    I've done some initial tests and see my scenes are collected right after they exit from the scene. But I'll do some more tests.

    PS: Also I can add a function like "removeAllListeners" to make this easier.

    best,
  • Thank You,

    I was unaware of REMOVED_FROM_STAGE.
    removeAllListeners sound good, i do not need it for now but can imagine situations where it can be useful.

    I will try version 1.0.3

    Maybe for a future release you can consider to add an event ENTER_STAGE_FRAME similar to ENTER_FRAME but dispatched only to objects on stage?
  • atilimatilim Maintainer

    Maybe for a future release you can consider to add an event ENTER_STAGE_FRAME similar to ENTER_FRAME but dispatched only to objects on stage?
    Exactly! I was thinking about adding this event but couldn't find a good name for it. I think the name ENTER_STAGE_FRAME is great. :)


Sign In or Register to comment.