Lua userdata being garbage collected before it should be -
i'm new lua. i'm trying create game using cocos2d-x v3.1rc0.
i'm running issue appears 1 of objects, created cocos2d-x lib, being garbage collected before should be.
here class keep track of "prey" on screen. each prey references frames/animations displayed depending on state of prey.
prey = { sprite = false -- main prey sprite. -- frames used movement, getting hit, knocked out, etc. , frame = { idle = false -- idle frames , move = false -- move frames , rest = false -- resting frames } , state = false -- current state of prey. }
here constructor:
function prey:new() local o = {} setmetatable(o, self) self.__index = self return o end
here frames associated prey:
function prey:setframes(frames) --[[ moving ]]-- self.frame.move = cc.animation:createwithspriteframes({frames[1], frames[2], frames[3]}, 1.0) cclog("move frames: " .. #self.frame.move:getframes()) --[[ resting ]]-- self.frame.rest = cc.animation:createwithspriteframes({frames[4], frames[5]}, 2.0) cclog("rest frames: " .. #self.frame.rest:getframes()) end
the above print following:
cocos2d: [lua-print] move frames: 3 cocos2d: [lua-print] rest frames: 2
however, when attempt call following method, frame.move , frame.rest variables appear garbage collected because error raised when attempt access them. please note method called every tick:
function prey:tick() cclog("state: " .. self.state) local animation = false -- moving if (self.state == preystate.moving) cclog("moving: " .. #self.frame.move:getframes()) animation = self.frame.move elseif (self.state == preystate.resting) cclog("resting: " .. #self.frame.rest:getframes()) -- resting animation = self.frame.rest end end
when cclog calls being made either of 2 conditions following error displayed. please note know specific instance of prey has not been garbage collected because self.state set idle before made call tick method. retains self.state on subsequent calls method.
cocos2d: [lua-print] state: 2 cocos2d: [lua-print] ---------------------------------------- cocos2d: [lua-print] lua error: [string "prey.lua"]:189: invalid 'cobj' in function 'lua_cocos2dx_animation_getframes'
after looking @ many articles describing how objects retained, appears it's possible animation object being garbage collected. have no idea why! reference cocos2d-x object should strong, right?
here articles i've read regarding subject:
- http://www.tutorialspoint.com/lua/lua_object_oriented.htm
- http://lua-users.org/wiki/weaktablestutorial
- http://www.lua.org/pil/17.html
- http://phrogz.net/lua/learninglua_valuesandmetatables.html
- http://lua-users.org/wiki/garbagecollectiontutorial
update 1
the following code causes issue:
-- create instance of our prey object here... prey = new prey:new() local function tick() prey:tick() end scheduleid = cc.director:getinstance():getscheduler():schedulescriptfunc(tick, 0, false)
however, when attempt call prey:tick()
outside of scheduler no errors. need code ran every tick... missing? in particular scenario have made prey
global variable tick method access instance of prey. did simplify particular test. however, i'd make prey local , make scheduler run tick function every instance of prey.
the objects being garbage collected. have ran several more tests , came conclusion can not associate any cocos2d objects variable without them later being garbage collected on next cycle. instead, have use cocos2d-x's libs cache textures , query textures @ time need them.
it's difficult illustrate, end result call cc.director:getinstance():gettexturecache():gettextureforkey("texture.png")
@ time needed texture , re-create frames needed each animation when state changed object. i'm going way cache sprites don't have re-create them. however, resolved issue. lesson cococ2d objects garbage collected on next cycle. objects retained cached internally cocos2d. wrong this, have observed.
so process first add image texture cache @ load time:
local texture = cc.director:getinstance():gettexturecache():addimage("texture.png")
and calling following later on:
local texture = cc.director:getinstance():gettexturecache():gettextureforkey("texture.png")
i appreciate insight this. how guys handling this? right process? there articles related caching sprites, textures, etc later use? thank you!
update 1
yes. objects being released within cocos2d-x library. can around caching sprite frames. code used, in lua, cache sprite frames. after cached, reference hold spriteframe, within lua code, continue point active instance of frame.
cc.spriteframecache:getinstance():addspriteframe(frame, name)
and spriteframe out of cache:
local frame = cc.spriteframecache:getinstance():getspriteframe(name)
Comments
Post a Comment