Quick Links: Download Gideros Studio | Gideros Documentation | Gideros community chat | DONATE
ENTER_FRAME listener and garbage collection — Gideros Forum

ENTER_FRAME listener and garbage collection

bowerandybowerandy Guru
edited September 2012 in General questions
Can I just get confirmation that including a listener for the ENTER_FRAME event in a class init() method will not prevent the object from being collected if no other references exist? e.g:
function MyClass:init()
    self:addEventListener(Event.ENTER_FRAME, self.onEnterFrame, self)
end
 
function MyClass:onEnterFrame()
end
 
MyClass.new()
Will that instance get collected correctly without first removing the listener.

best regards

Dislikes: bhou

+1 -1 (+0 / -1 )Share on Facebook

Comments

  • atilimatilim Maintainer
    edited September 2012 Accepted Answer
    Yes it'll be collected. Here is an example based on yours:
    MyClass = Core.class(Sprite)
     
    function MyClass:init()
    	self.frame = 0
    	self:addEventListener(Event.ENTER_FRAME, self.onEnterFrame, self)
    end
     
    function MyClass:onEnterFrame()
    	self.frame = self.frame + 1
    	if self.frame == 60 then
    		print("tick")
    		self.frame = 0
    	end
     
    end
     
    MyClass.new()
     
    stage:addEventListener("mouseDown", function() 
    	collectgarbage()
    end)
    Here this example prints "tick" at every 60th frame until you press the mouse.
  • @atilim, thanks. I guess I should have thought about testing it like that with a print statement. Sorry to trouble you.
  • atilimatilim Maintainer
    np :) Also, you can use unofficial newproxy function to detect when a Lua table is collected:
    MyClass = Core.class(Sprite)
     
    function MyClass:init()
    	self.proxy = newproxy(true)
    	getmetatable(self.proxy).__gc = function() print("collected!") end
     
    	self.frame = 0
    	self:addEventListener(Event.ENTER_FRAME, self.onEnterFrame, self)
    end
     
    function MyClass:onEnterFrame()
    	self.frame = self.frame + 1
    	if self.frame == 60 then
    		print("tick")
    		self.frame = 0
    	end
     
    end
     
    MyClass.new()
     
    stage:addEventListener("mouseDown", function() 
    	collectgarbage()
    end)
  • Hmm.. now that could be very useful, thanks.
  • john26john26 Maintainer
    @atilim I tried your two examples but the "ticks" do not stop when I press the mouse. I am using an older version, however, 2012.2.2.2.
  • atilimatilim Maintainer
    edited September 2012
    Yes It was fixed with 2012.08.2. (In release notes, it's mentioned as Bug: Event objects shouldn't store target object internally (late GC of target object))

    For example, if you test this code:
    MyClass = Core.class(Sprite)
     
    function MyClass:init()
    	self.proxy = newproxy(true)
    	getmetatable(self.proxy).__gc = function() print("collected!") end
     
    	self:addEventListener(Event.ENTER_FRAME, self.onEnterFrame, self)
    end
     
    function MyClass:onEnterFrame()
    end
     
    -- create 4 objects
    MyClass.new()
    MyClass.new()
    MyClass.new()
    MyClass.new()
     
    stage:addEventListener("mouseDown", function() 
    	collectgarbage()
    end)
    With 2012.2.2.2, you see 3 objects are GCed, but with latest version all 4 objects are GCed.
  • @atilim, yes I remembered there being some problem like this - hence the paranoid original question.

    best regards
  • john26john26 Maintainer
    edited September 2012
    @atilim Thanks for your reply! So the bug that previously existed, is it a serious memory leak or just that collection is late? eg:
    function doNothing()
    end
     
    foo=Bitmap.new(Texture.new("foo.png"))
    foo:addEventListener(Event.MOUSE_DOWN,doNothing)
    stage:addChild(foo)
     
    -- destroy level
    foo:removeFromParent()                            
     
    --start new level
    foo=Bitmap.new(Texture.new("bar.png"))   -- garbage collected?
    will the old sprite be elligible for GC on "foo=Bitmap.new()" command?
  • bowerandybowerandy Guru
    edited September 2012
    @john26, I think in that older version it was a genuine leak. The recommendation back then was to ensure that ENTER_FRAME handlers were removed when an object was taken off the stage. Hence, I always used to use ADDED_TO_STAGE and REMOVED_FROM_STAGE handlers to install/remove the ENTER_FRAME handlers (if that makes sense).

    Anyway, as @atilim has confirmed the bug has been fixed in the latest download so there should be no need to jump through these hoops now.

    best regards
  • atilimatilim Maintainer
    edited September 2012
    Also, I think it's not very serious. Only 1 sprite (the last one) remains uncollected.
Sign In or Register to comment.