Current cocos2d-x control the lua userdata referenceCount and the pointer value stored in the userdata by the c++. In this mechanism, the Lua scripting developers didn’t know when the pointer ptr stored in the userdata would be assigned the null value.So,many Lua script developer will happend the error that "invalid ‘cobj’ in function ‘function name’ during they develop games.
Error reproduction
A Error that many Lua script developer would happen as follows:
--create a Sprite
local sprite = cc.Sprite:create()
--Use this sprite in the scheduler update function
local funtion update(dt)
--may trigger error, error: "invalid 'cobj' in function 'lua_cocos2dx_Sprite_setFlippedY'"
sprite:setFlippedY(true)
end
Error analysis
In current mechanism, the sprite is a autorelese object, and the up codes didn’t call retain, so sprite was released and trigger the destrutor in the c++.It will clear the pointer value stored in the related userdata,so when the related userdata call the function bound to lua,it didn’t found the related pointer value,then cause this error.
Solution for this problem
Control the life cycle of c++ object by the lua.
The advantages of solution
It more accord with the concept of the Lua developers, they don’t need to care about when the related c++ pointer assigned null
The disadvantages of solution
This will lead to the delay collection of the c++ object and then leading to memory rises.
The delay collection of the c++ objecte will break mechanism of the cocos2d-x, and lead to some unpredictable errors.
Some bindings functions will implement retain operation for the incoming parameters, in this situation the related userdata in the Lua also needs to implement to the incomine userdata. But these functions do not have any rule to locate, so may be some operataions will be missed.
So guys,can you tell me which mechanism is better and give me some suggestions,thanks.
hi, are we talking about the same problem?About memory management in lua
I think a reference in lua should keep the c++ object in memory, just as many other lua engine do.
And the problem reported by @dualface really make sense.
@alexzhengyi,the problem is the same as the @dualface,if lua keep the c++ object reference, this delayed release will break the c++ object memory management mechanism,and lead to unpredictable error.For this ,can you give some suggestion,thanks.
Hi,in my opinion, memory is managed by the gc in lua will be more friendly to most lua developers from other game engine.
It’s very ridiculous to write some code like this in lua:
–create a sprite without adding to screen, just cache it for use later
local s = cc.sprite:create()
s:retain()
s:release()
s = nil
Is it possible to rewrite some code in the lua source code to integrate the memory management in cocos2d c++.
When there is a reference to the object, just add a reference count to the c object.
On the other hand,Maybe some other open source lua game engines like love or moai can bring in some hints.
I agree with @alexzhengyi, having users manage memory themselves in garbage collected environment does not feel right. I hope there’s a better solution.
This is actually not a problem.
The “invalid ‘cobj’ …” error occurred because the sprite node has become an isolated node. Which behavior is right conform to the GC’s principle: isolated node will be collected.
Trying to operate on an isolated node is the user’s fault and cocos framework shouldn’t be responsible of this.