js_cocos2dx_CCLayer_init Cocos2d: Invalid Native Object Cocos2d: JS: Error: Invalid Native Object

I inherit cc.Layer

var MYLayer = cc.Layer.extend({
>
>
init:function () {
>
var bRet = false;
if (this._super()) {
>
bRet = true;
}
return bRet;
},
>
onTouchesMoved:function (touches, event) {
this.processEvent( touches[0] );
},
>
onMouseDragged:function( event ) {
this.processEvent( event );
},
>
processEvent:function( event ) {
>
}
>
});
>
>
>
>
>
MYLayer.create = function () {
var sg = new MYLayer();
if (sg && sg.init()) {
return sg;
}
return null;
};

and call

var scene = cc.Scene.create();
scene.addChild(MYLayer.create());
>
cc.Director.getInstance().replaceScene(cc.TransitionFade.create(1.2, scene));

it reported

jsb_cocos2dx_auto.cpp: Line: 29998, Function: js_cocos2dx_CCLayer_init
Cocos2d: Invalid Native Object
Cocos2d: JS: Error: Invalid Native Object

Your comment welcome

I tested your codes. But i couldn’t reproduce the issue you said. Everything works right.

Could you provide more informations? Engine version? Target Platform?

@James - I faced the similar issues when using CCActions and other objects from javascript. so i ended up adding a function to check if the object exists or has been released. Because in javascript this object seems to be valid but when you call any function on this object, it gives the Invalid Native Object error.

JSBool js_cocos2dx_exists(JSContext *cx, uint32_t argc, jsval *vp)
{
  JSObject *thisObj = JS_THIS_OBJECT(cx, vp);
  if (thisObj) {
    js_proxy_t *proxy;
    JS_GET_NATIVE_PROXY(proxy, thisObj);
    if (proxy) {
            JS_SET_RVAL(cx, vp, JSVAL_TRUE);
      return JS_TRUE;
    }
  }
    JS_SET_RVAL(cx, vp, JSVAL_FALSE);
  return JS_TRUE;
}

And added the bindings.

JS_DefineFunction(cx, jsb_CCAction_prototype, "exists", js_cocos2dx_exists, 0, JSPROP_READONLY | JSPROP_PERMANENT);
JS_DefineFunction(cx, jsb_CCAnimation_prototype, "exists", js_cocos2dx_exists, 0, JSPROP_READONLY | JSPROP_PERMANENT);
JS_DefineFunction(cx, jsb_CCSpriteFrame_prototype, "exists", js_cocos2dx_exists, 0, JSPROP_READONLY | JSPROP_PERMANENT);
JS_DefineFunction(cx, jsb_CCNode_prototype, "exists", js_cocos2dx_exists, 0, JSPROP_READONLY | JSPROP_PERMANENT);

And then in Javascript i check.

if(!anim || !anim.exists() || anim.isDone()) {
  //create animation
}

Or is there another way to check the validity of an object from javascript? Ideally if its possible, the javascript variable should be set to null if the object is released.

@Shuja

Or is there another way to check the validity of an object from javascript?

Your solution is good.

Ideally if its possible, the javascript variable should be set to null if the object is released.

It’s difficult to set the js object, which associates native object, to NULL since native(c++) don’t know the js object’s reference.

@James - Would be good to have this functionality in cocos2d-x JSB, if you are fine with my approach I can send a pull request, or may be you would want to implement this in a different way?

I found if I unable

if (this.*super) {
>
bRet = true;
}
it will work.
It looks like this.*super() can not work correctly

The `Invaild native object` prompt is for warning you your game logic contains something wrong.
Yep, we could add an `exists()` function for JSB, but all developers have to know that how to use it. More over, it will take a function invocation and cocos2d-html5 also need to this method but empty implementation.
Does it make sense that before every calling of native method (like setPostion, runAciton, etc), we need to check `exists()`function? If so, I think developer should consider that their game logic may have some problems.
BTW, for certain, this issue only appears on cocos2d-x JSB while cocos2d-html5 will work without any problems. The reason is that we use the lifecycle of cpp object to control the js object’s.
You guys may ask why not use the lifecycle of js objects to control cpp’s. Then, there will be the same as HTML5. Yep, we have considered that, but if you imagine that IN JS VM, it doesn’t know how many memory native(c++) layer uses. Maybe JS objects use 10M bytes memory while native objects are already allocating 100M ~ or more memory.

shuja shabandri wrote:

@James - Would be good to have this functionality in cocos2d-x JSB, if you are fine with my approach I can send a pull request, or may be you would want to implement this in a different way?

You are absolutely right. But the use case for exists() is not for checking before every native function call. For example I have a button, tapping on the button should play an animation. But if the animation is already playing, it should not do anything.

so usually the condition would be to check if (animation == null || animation.isDone() ) then create the animation and run. In this case if the animation has already completed calling isDone() sometimes throws Invalid Native Object error.

Otherwise, is it possible to throw a JS exception instead? that would be a better way of handling it i guess?

Otherwise, is it possible to throw a JS exception instead? that would be a better way of handling it i guess?
I agree, that will be better. :slight_smile:

I found that

this.*super caused the problem
it looks like this.*super() does not exist

but I review the code of jsb_cocos2d.js

cc.Class.extend = function (prop) {
var *super = this.prototype;
>
// Instantiate a base class
initializing = true;
var prototype = new this;
initializing = false;
fnTest = /xyz/.test) ? /\b_super\b/ : /.*/;
>
// Copy the properties over onto the new prototype
for {
// Check if we’re overwriting an existing function
prototype[name] = typeof prop[name] “function” &&
typeof _super[name] “function” && fnTest.test ?
{
return function {
var tmp = this.*super;
>
// Add a new .*super method that is the same method
// but on the super-class
this.*super = *super[name];
>
// The method only need to be bound temporarily, so we
// remove it when we’re done executing
var ret = fn.apply;
this.*super = tmp;
>
return ret;
};
})(name, prop[name]) :
prop[name];
}
>
// The dummy class constructor
function Class() {
// All construction is actually done in the init method
if (!initializing && this.ctor)
this.ctor.apply(this, arguments);
}
>
// Populate our constructed prototype object
Class.prototype = prototype;
>
// Enforce the constructor to be what we expect
Class.prototype.constructor = Class;
>
// And make this class extendable
Class.extend = arguments.callee;
>
return Class;
};

it looks like _super has been defined

confusing…

hello…i got errors too with Invalid Native Object

jsb: ERROR: File …\auto\jsb_cocos2dx_auto.cpp: Line: 4302, Function: js_cocos2dx_Node_getPositionX
js_cocos2dx_Node_getPositionX : Invalid Native Object

what is that mean? it just reference to file whic is from frameworks folder.

I am facing with the same issue but there are some differences;
The web game is working, but the IOS side is not…

Target platform: IOS
Test, Development platform: Web

[object Object],[object Object],[object Object],[object Object]
gamestarted
[object Object]
jsb: ERROR: File /Users/sckn/projects/business/taquin/with.cocos2d.new/taquin/frameworks/cocos2d-x/cocos/scripting/js-bindings/auto/jsb_cocos2dx_auto.cpp: Line: 8678, Function: js_cocos2dx_Action_clone
js_cocos2dx_Action_clone : Invalid Native Object
JS: /var/containers/Bundle/Application/AF4DF063-14BC-4EA1-BF1D-75EA0C3FDEF2/taquin-mobile.app/src/app.refactored.js:210:Error: js_cocos2dx_Action_clone : Invalid Native Object

These are my debug informations.

I have store my animations with my objects. I am using object constructor notation for creating game objects.
Every object has an animation property, value of this property is another object indicates every single animations it has.

And I am using these values like this;

runActionFor([this.ball], “gameover”);

I am thinking about your posts but, I think this thing have to work. But it does not.

Is this a bug, or am I missing something about js objects’ lifecycle ?

This is, how I store my objects and animations together;

OK, I am sorry for the flood.
But I solved my problem.

The tricky part is here (which confuses me!)
The web platform behaves differently because its internal routines are different. ( point of GC )

Note for the newbies;
Do not let it trick you. If you are getting this error. Check your game logic twice.
Do not create and attach the objects/classes. It doesn’t work like that when it comes to the native side.

Good luck!