C++ controls lua object lifecycle or vice versa

Problems of current mechanism

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.

Why you write code use retain()/release() ?

local s = cc.Sprite:create()
scene:addChild(s)

Actually,I would never like to write code like this. I just use it as an example if you intend to cache a srprite in cocos2d lua .

@alexzhengyi
@KJS
This survey is to check if we need to change memory model. Then script developers don’t have to concern memory usage.

本主题已置顶,它将始终显示在它所属分类的顶部。可由职员对所有人解除置顶,或者由用户自己取消置顶。

Lets assume that whenever an object is created retain is invoked.
So you must call release if you free the object.

Lets redefine object:release() to
return
the object if the ref count is not zero
nil if the ref count is zero

This the sequence should always work so the naive user is safe and oversight will leave objects in memory.

local s=cc.sprite:create();
use s

The object will not be freed.

The right code is

local s=cc.sprite:create();
use s
s = s:release()

The following code should work.

local s=cc.sprite:create();
s:release() – do not store the result release since it is nil
scene:addChild(s)

The following code is preferred.

local s=cc.sprite:create();
scene:addChild(s)
s=s:release()

Note that in this case s:release will not return nil.

Andre

Hi, i dont know how to create new topic in forum, can somebody answer me here?

I installed Cocos IDE and i am curious if is it possible to make LUA applications for Windows Phones? Dont see Windows Phones in Debug settings.

Thanks

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.

Incidentally, I found this article. I think you guys from ChuKong should have a glance. :slight_smile:

I think, control the life cycle of c++ object by the lua is better, recently i has done this. more detail see https://github.com/zhongfq/cocos-lua