From 47911e0c249ae366a6dae63ea3aede56e44d480e Mon Sep 17 00:00:00 2001 From: Ricardo Quesada Date: Fri, 11 Dec 2015 15:18:09 -0800 Subject: [PATCH 1/2] more js fixes fixes in how ref count is measured opengl bindings converted to new API --- cocos/base/CCRef.cpp | 9 +- cocos/base/CCRef.h | 1 + .../js-bindings/manual/ScriptingCore.cpp | 37 +++---- .../js-bindings/manual/ScriptingCore.h | 2 +- .../js-bindings/manual/cocos2d_specifics.cpp | 23 +--- .../js-bindings/manual/js_bindings_opengl.cpp | 101 ++++++++---------- .../manual/js_manual_conversions.h | 2 +- .../src/MemoryModelTest/MemoryModelTest.js | 7 ++ 8 files changed, 78 insertions(+), 104 deletions(-) diff --git a/cocos/base/CCRef.cpp b/cocos/base/CCRef.cpp index 59215c5738..4c4ce17674 100644 --- a/cocos/base/CCRef.cpp +++ b/cocos/base/CCRef.cpp @@ -50,6 +50,7 @@ Ref::Ref() , _scriptObject(nullptr) , _rooted(false) , _scriptOwned(false) +,_referenceCountAtRootTime(0) #endif { #if CC_ENABLE_SCRIPT_BINDING @@ -93,11 +94,15 @@ void Ref::retain() ++_referenceCount; #if CC_ENABLE_SCRIPT_BINDING && CC_ENABLE_GC_FOR_NATIVE_OBJECTS - if (!_rooted && _scriptOwned) + if (_scriptOwned && !_rooted) { auto scriptMgr = ScriptEngineManager::getInstance()->getScriptEngine(); if (scriptMgr && scriptMgr->getScriptType() == kScriptTypeJavascript) { + _referenceCountAtRootTime = _referenceCount-1; + + CCLOG("retain + root: %p (%s) rc=%d rcrt=%d", this, typeid(*this).name(), _referenceCount, _referenceCountAtRootTime); + scriptMgr->rootObject(this); _rooted = true; } @@ -111,7 +116,7 @@ void Ref::release() --_referenceCount; #if CC_ENABLE_SCRIPT_BINDING && CC_ENABLE_GC_FOR_NATIVE_OBJECTS - if (_scriptOwned && _referenceCount==1 && _rooted) + if (_scriptOwned && _rooted && _referenceCount==_referenceCountAtRootTime) { auto scriptMgr = ScriptEngineManager::getInstance()->getScriptEngine(); if (scriptMgr && scriptMgr->getScriptType() == kScriptTypeJavascript) diff --git a/cocos/base/CCRef.h b/cocos/base/CCRef.h index 5ca40a0c9e..4451243ae1 100644 --- a/cocos/base/CCRef.h +++ b/cocos/base/CCRef.h @@ -161,6 +161,7 @@ public: When true, it means that the object was already rooted. */ bool _rooted; + unsigned int _referenceCountAtRootTime; /** * The life of the object is scrolled by the scripting engine. diff --git a/cocos/scripting/js-bindings/manual/ScriptingCore.cpp b/cocos/scripting/js-bindings/manual/ScriptingCore.cpp index 19354fa161..91ff3b53e9 100644 --- a/cocos/scripting/js-bindings/manual/ScriptingCore.cpp +++ b/cocos/scripting/js-bindings/manual/ScriptingCore.cpp @@ -1563,14 +1563,12 @@ void ScriptingCore::rootObject(Ref* ref) nproxy = jsb_get_native_proxy(ptr); if (nproxy) { JSContext *cx = getGlobalContext(); - // FIXME: Creating a RootedObject here is not needed. - // it is being created only because jsb_get_js_proxy() requires one - // but only the raw pointer is used in jsb_get_js_proxy() - JS::RootedObject handle(cx, nproxy->obj.get()); - jsproxy = jsb_get_js_proxy(handle); - AddObjectRoot(cx, &jsproxy->obj); - - CCLOG("Rooting %p - %p: %s", ref, &jsproxy->obj, typeid(*ref).name()); + jsproxy = jsb_get_js_proxy(nproxy->obj); + JS::AddNamedObjectRoot(cx, &jsproxy->obj, typeid(*ref).name()); + } + else + { + CCLOG("BUG in rootObject"); } } @@ -1583,14 +1581,12 @@ void ScriptingCore::unrootObject(Ref* ref) nproxy = jsb_get_native_proxy(ptr); if (nproxy) { JSContext *cx = getGlobalContext(); - // FIXME: Creating a RootedObject here is not needed. - // it is being created only because jsb_get_js_proxy() requires one - // but only the raw pointer is used in jsb_get_js_proxy() - JS::RootedObject handle(cx, nproxy->obj.get()); - jsproxy = jsb_get_js_proxy(handle); - RemoveObjectRoot(cx, &jsproxy->obj); - - CCLOG("Unrooting #2 %p - %p: %s", ref, &jsproxy->obj, typeid(*ref).name()); + jsproxy = jsb_get_js_proxy(nproxy->obj); + JS::RemoveObjectRoot(cx, &jsproxy->obj); + } + else + { + CCLOG("BUG in unrootObject"); } } @@ -1949,11 +1945,10 @@ js_proxy_t* jsb_get_native_proxy(void* nativeObj) return p; } -js_proxy_t* jsb_get_js_proxy(JS::HandleObject jsObj) +js_proxy_t* jsb_get_js_proxy(JSObject* jsObj) { js_proxy_t* p = nullptr; - JSObject* ptr = jsObj.get(); - JS_GET_NATIVE_PROXY(p, ptr); + JS_GET_NATIVE_PROXY(p, jsObj); return p; } @@ -2059,8 +2054,6 @@ void jsb_ref_finalize(JSFreeOp* fop, JSObject* obj) js_proxy_t* nproxy; js_proxy_t* jsproxy; - CCLOG("jsb_ref_finalize #1: JSObject address = %p", obj); - JS::RootedObject jsobj(fop->runtime(), obj); jsproxy = jsb_get_js_proxy(jsobj); if (jsproxy) @@ -2070,8 +2063,6 @@ void jsb_ref_finalize(JSFreeOp* fop, JSObject* obj) if (ref) { - CCLOG("jsb_ref_finalize #2: JSObject address = %p (%s)", obj, typeid(*ref).name()); - jsb_remove_proxy(nproxy, jsproxy); ref->release(); } diff --git a/cocos/scripting/js-bindings/manual/ScriptingCore.h b/cocos/scripting/js-bindings/manual/ScriptingCore.h index b9ac8b295c..820553bfc3 100644 --- a/cocos/scripting/js-bindings/manual/ScriptingCore.h +++ b/cocos/scripting/js-bindings/manual/ScriptingCore.h @@ -549,7 +549,7 @@ js_type_class_t *jsb_register_class(JSContext *cx, JSClass *jsClass, JS::HandleO js_proxy_t* jsb_new_proxy(void* nativeObj, JS::HandleObject jsObj); js_proxy_t* jsb_get_native_proxy(void* nativeObj); -js_proxy_t* jsb_get_js_proxy(JS::HandleObject jsObj); +js_proxy_t* jsb_get_js_proxy(JSObject* jsObj); void jsb_remove_proxy(js_proxy_t* nativeProxy, js_proxy_t* jsProxy); /** diff --git a/cocos/scripting/js-bindings/manual/cocos2d_specifics.cpp b/cocos/scripting/js-bindings/manual/cocos2d_specifics.cpp index 0f4c728ab2..99a761f32c 100644 --- a/cocos/scripting/js-bindings/manual/cocos2d_specifics.cpp +++ b/cocos/scripting/js-bindings/manual/cocos2d_specifics.cpp @@ -5142,25 +5142,10 @@ bool js_cocos2dx_EventKeyboard_constructor(JSContext *cx, uint32_t argc, jsval * JSB_PRECONDITION2(ok, cx, false, "js_cocos2dx_EventKeyboard_constructor : Error processing arguments"); cocos2d::EventKeyboard* cobj = new (std::nothrow) cocos2d::EventKeyboard(arg0, arg1); - cocos2d::Ref *_ccobj = dynamic_cast(cobj); - if (_ccobj) { - _ccobj->autorelease(); - } - TypeTest t; - js_type_class_t *typeClass = nullptr; - std::string typeName = t.s_name(); - auto typeMapIter = _js_global_type_map.find(typeName); - CCASSERT(typeMapIter != _js_global_type_map.end(), "Can't find the class type!"); - typeClass = typeMapIter->second; - CCASSERT(typeClass, "The value is null."); - JS::RootedObject proto(cx, typeClass->proto.ref()); - JS::RootedObject parentProto(cx, typeClass->parentProto.ref()); - JS::RootedObject obj(cx, JS_NewObject(cx, typeClass->jsclass, proto, parentProto)); - JS::RootedValue objVal(cx, OBJECT_TO_JSVAL(obj)); - args.rval().set(objVal); - // link the native object with the javascript object - js_proxy_t* p = jsb_new_proxy(cobj, obj); - JS::AddNamedObjectRoot(cx, &p->obj, "cocos2d::EventKeyboard"); + js_type_class_t *typeClass = js_get_type_from_native(cobj); + auto jsobj = jsb_ref_create_jsobject(cx, cobj, typeClass, "cocos2d::EventKeyboard"); + + args.rval().set(OBJECT_TO_JSVAL(jsobj)); return true; } diff --git a/cocos/scripting/js-bindings/manual/js_bindings_opengl.cpp b/cocos/scripting/js-bindings/manual/js_bindings_opengl.cpp index 605bc616fd..bb69e13000 100644 --- a/cocos/scripting/js-bindings/manual/js_bindings_opengl.cpp +++ b/cocos/scripting/js-bindings/manual/js_bindings_opengl.cpp @@ -32,31 +32,31 @@ void GLNode::draw(Renderer *renderer, const Mat4& transform, uint32_t flags) { void GLNode::onDraw(Mat4 &transform, uint32_t flags) { - js_proxy_t* proxy = NULL; JSContext *cx = ScriptingCore::getInstance()->getGlobalContext(); - proxy = js_get_or_create_proxy(cx, this); - if( proxy ) { -// JSObject *jsObj = proxy->obj; - JS::RootedObject jsObj(cx, proxy->obj.get()); - if (jsObj) { - bool found = false; - JSB_AUTOCOMPARTMENT_WITH_GLOBAL_OBJCET + js_type_class_t *typeClass = js_get_type_from_native(this); + auto j = jsb_ref_get_or_create_jsobject(cx, this, typeClass, "cocos2d::GLNode"); - JS_HasProperty(cx, jsObj, "draw", &found); - if (found == true) { - auto director = Director::getInstance(); - director->pushMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW); - director->loadMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW, transform); + if (j) + { + JS::RootedObject jsObj(cx, j); - JS::RootedValue rval(cx); - JS::RootedValue fval(cx); - JS_GetProperty(cx, jsObj, "draw", &fval); + bool found = false; + JSB_AUTOCOMPARTMENT_WITH_GLOBAL_OBJCET - JS_CallFunctionValue(cx, jsObj, fval, JS::HandleValueArray::empty(), &rval); + JS_HasProperty(cx, jsObj, "draw", &found); + if (found) { + auto director = Director::getInstance(); + director->pushMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW); + director->loadMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW, transform); - director->popMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW); - } + JS::RootedValue rval(cx); + JS::RootedValue fval(cx); + JS_GetProperty(cx, jsObj, "draw", &fval); + + JS_CallFunctionValue(cx, jsObj, fval, JS::HandleValueArray::empty(), &rval); + + director->popMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW); } } } @@ -68,32 +68,18 @@ JSObject *js_cocos2dx_GLNode_prototype; bool js_cocos2dx_GLNode_constructor(JSContext *cx, uint32_t argc, jsval *vp) { - if (argc == 0) { - cocos2d::GLNode* cobj = new cocos2d::GLNode(); - cocos2d::Ref *_ccobj = dynamic_cast(cobj); - if (_ccobj) { - _ccobj->autorelease(); - } + cocos2d::GLNode* cobj = new (std::nothrow) cocos2d::GLNode; - TypeTest t; - js_type_class_t *typeClass = nullptr; - std::string typeName = t.s_name(); - auto typeMapIter = _js_global_type_map.find(typeName); + js_type_class_t *typeClass = js_get_type_from_native(cobj); + JS::RootedObject jsobj(cx, jsb_ref_create_jsobject(cx, cobj, typeClass, "cocos2d::GLNode")); - CCASSERT(typeMapIter != _js_global_type_map.end(), "Can't find the class type!"); - typeClass = typeMapIter->second; - CCASSERT(typeClass, "The value is null."); - - JS::RootedObject proto(cx, typeClass->proto.ref()); - JS::RootedObject parentProto(cx, typeClass->parentProto.ref()); - JS::RootedObject obj(cx, JS_NewObject(cx, typeClass->jsclass, proto, parentProto)); JS::CallArgs args = JS::CallArgsFromVp(argc, vp); - args.rval().set(OBJECT_TO_JSVAL(obj)); - // link the native object with the javascript object - js_proxy_t *p = jsb_new_proxy(cobj, obj); + args.rval().set(OBJECT_TO_JSVAL(jsobj)); - JS::AddNamedObjectRoot(cx, &p->obj, "cocos2d::GLNode"); + bool ok=false; + if (JS_HasProperty(cx, jsobj, "_ctor", &ok) && ok) + ScriptingCore::getInstance()->executeFunctionWithOwner(OBJECT_TO_JSVAL(jsobj), "_ctor", args); return true; } @@ -101,17 +87,16 @@ bool js_cocos2dx_GLNode_constructor(JSContext *cx, uint32_t argc, jsval *vp) return false; } -void js_cocos2dx_GLNode_finalize(JSFreeOp *fop, JSObject *obj) { -} - static bool js_cocos2dx_GLNode_ctor(JSContext *cx, uint32_t argc, jsval *vp) { JS::CallArgs args = JS::CallArgsFromVp(argc, vp); JS::RootedObject obj(cx, args.thisv().toObjectOrNull()); - cocos2d::GLNode *nobj = new cocos2d::GLNode(); - js_proxy_t* p = jsb_new_proxy(nobj, obj); - nobj->autorelease(); - JS::AddNamedObjectRoot(cx, &p->obj, "GLNode"); + cocos2d::GLNode *nobj = new (std::nothrow) cocos2d::GLNode; + auto newproxy = jsb_new_proxy(nobj, obj); + jsb_ref_init(cx, &newproxy->obj, nobj, "cocos2d::GLNode"); + bool isFound = false; + if (JS_HasProperty(cx, obj, "_ctor", &isFound) && isFound) + ScriptingCore::getInstance()->executeFunctionWithOwner(OBJECT_TO_JSVAL(obj), "_ctor", args); args.rval().setUndefined(); return true; } @@ -119,16 +104,16 @@ static bool js_cocos2dx_GLNode_ctor(JSContext *cx, uint32_t argc, jsval *vp) bool js_cocos2dx_GLNode_create(JSContext *cx, uint32_t argc, jsval *vp) { JS::CallArgs args = JS::CallArgsFromVp(argc, vp); - cocos2d::GLNode* ret = new cocos2d::GLNode(); - jsval jsret; - do { - if (ret) { - js_proxy_t *proxy = js_get_or_create_proxy(cx, ret); - jsret = OBJECT_TO_JSVAL(proxy->obj); - } else { - jsret = JSVAL_NULL; - } - } while (0); + cocos2d::GLNode* ret = new (std::nothrow) cocos2d::GLNode; + jsval jsret = JSVAL_NULL; + + if (ret) { + js_type_class_t *typeClass = js_get_type_from_native(ret); + + auto jsobj = jsb_ref_create_jsobject(cx, ret, typeClass, "cocos2d::GLNode"); + jsret = OBJECT_TO_JSVAL(jsobj); + } + args.rval().set(jsret); return true; } @@ -145,7 +130,7 @@ void js_register_cocos2dx_GLNode(JSContext *cx, JS::HandleObject global) { js_cocos2dx_GLNode_class->enumerate = JS_EnumerateStub; js_cocos2dx_GLNode_class->resolve = JS_ResolveStub; js_cocos2dx_GLNode_class->convert = JS_ConvertStub; - js_cocos2dx_GLNode_class->finalize = js_cocos2dx_GLNode_finalize; + js_cocos2dx_GLNode_class->finalize = jsb_ref_finalize; js_cocos2dx_GLNode_class->flags = JSCLASS_HAS_RESERVED_SLOTS(2); static JSPropertySpec properties[] = { diff --git a/cocos/scripting/js-bindings/manual/js_manual_conversions.h b/cocos/scripting/js-bindings/manual/js_manual_conversions.h index ce64a45310..e2d2f538f0 100644 --- a/cocos/scripting/js-bindings/manual/js_manual_conversions.h +++ b/cocos/scripting/js-bindings/manual/js_manual_conversions.h @@ -119,7 +119,7 @@ bool jsval_to_ray(JSContext *cx, JS::HandleValue vp, cocos2d::Ray* ret); bool jsval_to_resourcedata(JSContext *cx, JS::HandleValue v, cocos2d::ResourceData* ret); // forward declaration -CC_JS_DLL js_proxy_t* jsb_get_js_proxy(JS::HandleObject jsObj); +CC_JS_DLL js_proxy_t* jsb_get_js_proxy(JSObject* jsObj); template bool jsvals_variadic_to_ccvector( JSContext *cx, /*jsval *vp, int argc,*/const JS::CallArgs& args, cocos2d::Vector* ret) diff --git a/tests/js-tests/src/MemoryModelTest/MemoryModelTest.js b/tests/js-tests/src/MemoryModelTest/MemoryModelTest.js index a38d14f122..ea0e8a245d 100644 --- a/tests/js-tests/src/MemoryModelTest/MemoryModelTest.js +++ b/tests/js-tests/src/MemoryModelTest/MemoryModelTest.js @@ -70,6 +70,7 @@ var SetPropertyMemoryModelTest = MemoryModelTestBase.extend({ _subtitle:"See console for possible errors", ctor:function () { + cc.sys.garbageCollect(); this._super(); var sprite = new cc.Sprite(s_grossini_dance_atlas, cc.rect(0, 0, 85, 121)); var tag = 10; @@ -157,6 +158,12 @@ var LocalVarMemoryModelTest = MemoryModelTestBase.extend({ var sprite2 = new cc.Sprite(s_grossini_dance_atlas, cc.rect(0, 0, 85, 121)); var sprite3 = new cc.Sprite(s_grossini_dance_atlas, cc.rect(0, 0, 85, 121)); var a = 10; + this.addChild(sprite1); + this.removeChild(sprite1); +// this.addChild(sprite2); +// this.removeChild(sprite2); + this.addChild(sprite3); + this.removeChild(sprite3); //cc.sys.dumpRoot(); cc.sys.garbageCollect(); cc.log(sprite1); From c5058aa2f963ce41a6317781dfcc2709806c99eb Mon Sep 17 00:00:00 2001 From: Ricardo Quesada Date: Fri, 11 Dec 2015 17:18:20 -0800 Subject: [PATCH 2/2] more conversions --- .../chipmunk/js_bindings_chipmunk_manual.cpp | 81 +++++-------------- .../js-bindings/manual/cocos2d_specifics.cpp | 6 +- .../js-bindings/manual/cocos2d_specifics.hpp | 7 +- .../project.pbxproj | 12 +-- .../Classes/js_DrawNode3D_bindings.cpp | 33 ++------ 5 files changed, 33 insertions(+), 106 deletions(-) diff --git a/cocos/scripting/js-bindings/manual/chipmunk/js_bindings_chipmunk_manual.cpp b/cocos/scripting/js-bindings/manual/chipmunk/js_bindings_chipmunk_manual.cpp index 936430eff6..34e4d42722 100644 --- a/cocos/scripting/js-bindings/manual/chipmunk/js_bindings_chipmunk_manual.cpp +++ b/cocos/scripting/js-bindings/manual/chipmunk/js_bindings_chipmunk_manual.cpp @@ -70,12 +70,6 @@ JSClass* JSPROXY_CCPhysicsSprite_class = NULL; JSObject* JSPROXY_CCPhysicsSprite_object = NULL; // Constructor -// Destructor -void JSPROXY_CCPhysicsSprite_finalize(JSFreeOp *fop, JSObject *obj) -{ - CCLOGINFO("jsbindings: finalizing JS object %p (PhysicsSprite)", obj); -} - // Arguments: // Ret value: BOOL (b) bool JSPROXY_CCPhysicsSprite_isDirty(JSContext *cx, uint32_t argc, jsval *vp) { @@ -173,12 +167,6 @@ extern JSObject *js_cocos2dx_CCDrawNode_prototype; // Constructor -// Destructor -void JSB_CCPhysicsDebugNode_finalize(JSFreeOp *fop, JSObject *obj) -{ - CCLOGINFO("jsbindings: finalizing JS object %p (PhysicsDebugNode)", obj); -} - // Arguments: cpSpace* // Ret value: PhysicsDebugNode* (o) bool JSB_CCPhysicsDebugNode_debugNodeForCPSpace__static(JSContext *cx, uint32_t argc, jsval *vp) { @@ -295,7 +283,7 @@ void JSB_CCPhysicsDebugNode_createClass(JSContext *cx, JS::HandleObject globalOb JSB_CCPhysicsDebugNode_class->enumerate = JS_EnumerateStub; JSB_CCPhysicsDebugNode_class->resolve = JS_ResolveStub; JSB_CCPhysicsDebugNode_class->convert = JS_ConvertStub; - JSB_CCPhysicsDebugNode_class->finalize = JSB_CCPhysicsDebugNode_finalize; + JSB_CCPhysicsDebugNode_class->finalize = jsb_ref_finalize; JSB_CCPhysicsDebugNode_class->flags = 0; static JSPropertySpec properties[] = { @@ -442,7 +430,8 @@ bool JSPROXY_CCPhysicsSprite_spriteWithSpriteFrame__static(JSContext *cx, uint32 // Arguments: NSString* // Ret value: PhysicsSprite* (o) -bool JSPROXY_CCPhysicsSprite_spriteWithSpriteFrameName__static(JSContext *cx, uint32_t argc, jsval *vp) { +bool JSPROXY_CCPhysicsSprite_spriteWithSpriteFrameName__static(JSContext *cx, uint32_t argc, jsval *vp) +{ JS::CallArgs args = JS::CallArgsFromVp(argc, vp); bool ok = true; const char* arg0 = nullptr; @@ -452,27 +441,9 @@ bool JSPROXY_CCPhysicsSprite_spriteWithSpriteFrameName__static(JSContext *cx, ui PhysicsSprite* ret = PhysicsSprite::createWithSpriteFrameName(arg0); - jsval jsret; - do { - if (ret) { - TypeTest t; - js_type_class_t *typeClass = nullptr; - std::string typeName = t.s_name(); - auto typeMapIter = _js_global_type_map.find(typeName); - CCASSERT(typeMapIter != _js_global_type_map.end(), "Can't find the class type!"); - typeClass = typeMapIter->second; - CCASSERT(typeClass, "The value is null."); - JS::RootedObject proto(cx, typeClass->proto.ref()); - JS::RootedObject parentProto(cx, typeClass->parentProto.ref()); - JS::RootedObject obj(cx, JS_NewObject(cx, typeClass->jsclass, proto, parentProto)); - jsret = OBJECT_TO_JSVAL(obj); - js_proxy_t *p = jsb_new_proxy(ret, obj); - JS::AddNamedObjectRoot(cx, &p->obj, "CCPhysicsSprite"); - } else { - jsret = JSVAL_NULL; - } - } while (0); - args.rval().set(jsret); + js_type_class_t *typeClass = js_get_type_from_native(ret); + JS::RootedObject jsret(cx, jsb_ref_autoreleased_create_jsobject(cx, ret, typeClass, "cocos2d::extension::PhysicsSprite")); + args.rval().set(OBJECT_TO_JSVAL(jsret)); return true; } @@ -483,27 +454,14 @@ bool JSPROXY_CCPhysicsSprite_spriteWithSpriteFrameName__static(JSContext *cx, ui bool JSPROXY_CCPhysicsSprite_constructor(JSContext *cx, uint32_t argc, jsval *vp) { JS::CallArgs args = JS::CallArgsFromVp(argc, vp); bool ok = true; - PhysicsSprite* cobj = new PhysicsSprite(); - cocos2d::Ref *_ccobj = dynamic_cast(cobj); - if (_ccobj) { - _ccobj->autorelease(); - } - TypeTest t; - js_type_class_t *typeClass = nullptr; - std::string typeName = t.s_name(); - auto typeMapIter = _js_global_type_map.find(typeName); - CCASSERT(typeMapIter != _js_global_type_map.end(), "Can't find the class type!"); - typeClass = typeMapIter->second; - CCASSERT(typeClass, "The value is null."); - JS::RootedObject proto(cx, typeClass->proto.ref()); - JS::RootedObject parentProto(cx, typeClass->parentProto.ref()); - JS::RootedObject obj(cx, JS_NewObject(cx, typeClass->jsclass, proto, parentProto)); - args.rval().set(OBJECT_TO_JSVAL(obj)); + auto cobj = new (std::nothrow) cocos2d::extension::PhysicsSprite; + js_type_class_t *typeClass = js_get_type_from_native(cobj); + // link the native object with the javascript object - js_proxy_t* p = jsb_new_proxy(cobj, obj); - JS::AddNamedObjectRoot(cx, &p->obj, "cocos2d::extension::PhysicsSprite"); - if (JS_HasProperty(cx, obj, "_ctor", &ok)) - ScriptingCore::getInstance()->executeFunctionWithOwner(OBJECT_TO_JSVAL(obj), "_ctor", args); + JS::RootedObject jsobj(cx, jsb_ref_create_jsobject(cx, cobj, typeClass, "cocos2d::extension::PhysicsSprite")); + args.rval().set(OBJECT_TO_JSVAL(jsobj)); + if (JS_HasProperty(cx, jsobj, "_ctor", &ok) && ok) + ScriptingCore::getInstance()->executeFunctionWithOwner(OBJECT_TO_JSVAL(jsobj), "_ctor", args); return true; } @@ -511,14 +469,11 @@ static bool JSPROXY_CCPhysicsSprite_ctor(JSContext *cx, uint32_t argc, jsval *vp { JS::CallArgs args = JS::CallArgsFromVp(argc, vp); JS::RootedObject obj(cx, args.thisv().toObjectOrNull()); - PhysicsSprite *nobj = new PhysicsSprite(); - if (nobj) { - nobj->autorelease(); - } - js_proxy_t* p = jsb_new_proxy(nobj, obj); - JS::AddNamedObjectRoot(cx, &p->obj, "cocos2d::extension::SpriteFrame"); + auto nobj = new (std::nothrow) cocos2d::extension::PhysicsSprite; + auto newproxy = jsb_new_proxy(nobj, obj); + jsb_ref_init(cx, &newproxy->obj, nobj, "cocos2d::extension::PhysicsSprite"); bool isFound = false; - if (JS_HasProperty(cx, obj, "_ctor", &isFound)) + if (JS_HasProperty(cx, obj, "_ctor", &isFound) && isFound) ScriptingCore::getInstance()->executeFunctionWithOwner(OBJECT_TO_JSVAL(obj), "_ctor", args); args.rval().setUndefined(); return true; @@ -535,7 +490,7 @@ void JSPROXY_CCPhysicsSprite_createClass(JSContext *cx, JS::HandleObject globalO JSPROXY_CCPhysicsSprite_class->enumerate = JS_EnumerateStub; JSPROXY_CCPhysicsSprite_class->resolve = JS_ResolveStub; JSPROXY_CCPhysicsSprite_class->convert = JS_ConvertStub; - JSPROXY_CCPhysicsSprite_class->finalize = JSPROXY_CCPhysicsSprite_finalize; + JSPROXY_CCPhysicsSprite_class->finalize = jsb_ref_finalize; JSPROXY_CCPhysicsSprite_class->flags = 0; static JSPropertySpec properties[] = { diff --git a/cocos/scripting/js-bindings/manual/cocos2d_specifics.cpp b/cocos/scripting/js-bindings/manual/cocos2d_specifics.cpp index 99a761f32c..025b0ed24f 100644 --- a/cocos/scripting/js-bindings/manual/cocos2d_specifics.cpp +++ b/cocos/scripting/js-bindings/manual/cocos2d_specifics.cpp @@ -5152,10 +5152,6 @@ bool js_cocos2dx_EventKeyboard_constructor(JSContext *cx, uint32_t argc, jsval * extern JSObject *jsb_cocos2d_Event_prototype; -void js_cocos2d_EventKeyboard_finalize(JSFreeOp *fop, JSObject *obj) { - CCLOGINFO("jsbindings: finalizing JS object %p (EventKeyboard)", obj); -} - static bool js_is_native_obj(JSContext *cx, uint32_t argc, jsval *vp) { JS::CallArgs args = JS::CallArgsFromVp(argc, vp); @@ -5173,7 +5169,7 @@ void js_register_cocos2dx_EventKeyboard(JSContext *cx, JS::HandleObject global) jsb_cocos2d_EventKeyboard_class->enumerate = JS_EnumerateStub; jsb_cocos2d_EventKeyboard_class->resolve = JS_ResolveStub; jsb_cocos2d_EventKeyboard_class->convert = JS_ConvertStub; - jsb_cocos2d_EventKeyboard_class->finalize = js_cocos2d_EventKeyboard_finalize; + jsb_cocos2d_EventKeyboard_class->finalize = jsb_ref_finalize; jsb_cocos2d_EventKeyboard_class->flags = JSCLASS_HAS_RESERVED_SLOTS(2); static JSPropertySpec properties[] = { diff --git a/cocos/scripting/js-bindings/manual/cocos2d_specifics.hpp b/cocos/scripting/js-bindings/manual/cocos2d_specifics.hpp index 1c6dc8ff2c..30a096d314 100644 --- a/cocos/scripting/js-bindings/manual/cocos2d_specifics.hpp +++ b/cocos/scripting/js-bindings/manual/cocos2d_specifics.hpp @@ -133,11 +133,8 @@ JSObject* js_get_or_create_jsobject(JSContext *cx, typename std::enable_ifparentProto.ref().get()); JS::RootedObject js_obj(cx, JS_NewObject(cx, typeClass->jsclass, proto, parent)); proxy = jsb_new_proxy(native_obj, js_obj); -#ifdef DEBUG - AddNamedObjectRoot(cx, &proxy->obj, typeid(*native_obj).name()); -#else - AddObjectRoot(cx, &proxy->obj); -#endif + + JS::AddNamedObjectRoot(cx, &proxy->obj, typeid(*native_obj).name()); } return proxy->obj; } diff --git a/cocos/scripting/js-bindings/proj.ios_mac/cocos2d_js_bindings.xcodeproj/project.pbxproj b/cocos/scripting/js-bindings/proj.ios_mac/cocos2d_js_bindings.xcodeproj/project.pbxproj index ab0bc1f418..9e61293b30 100644 --- a/cocos/scripting/js-bindings/proj.ios_mac/cocos2d_js_bindings.xcodeproj/project.pbxproj +++ b/cocos/scripting/js-bindings/proj.ios_mac/cocos2d_js_bindings.xcodeproj/project.pbxproj @@ -172,10 +172,10 @@ BA4095C31A6F730A005E53F6 /* jsb_cocos2dx_studio_conversions.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BA4095C01A6F730A005E53F6 /* jsb_cocos2dx_studio_conversions.cpp */; }; BA4095C41A6F730A005E53F6 /* jsb_cocos2dx_studio_conversions.h in Headers */ = {isa = PBXBuildFile; fileRef = BA4095C11A6F730A005E53F6 /* jsb_cocos2dx_studio_conversions.h */; }; BA4095C51A6F730A005E53F6 /* jsb_cocos2dx_studio_conversions.h in Headers */ = {isa = PBXBuildFile; fileRef = BA4095C11A6F730A005E53F6 /* jsb_cocos2dx_studio_conversions.h */; }; - BA9FD5D21BAC0A7600996C85 /* CCComponentJS.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BA9FD5D01BAC0A7600996C85 /* CCComponentJS.cpp */; settings = {ASSET_TAGS = (); }; }; - BA9FD5D31BAC0A7600996C85 /* CCComponentJS.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BA9FD5D01BAC0A7600996C85 /* CCComponentJS.cpp */; settings = {ASSET_TAGS = (); }; }; - BA9FD5D41BAC0A7600996C85 /* CCComponentJS.h in Headers */ = {isa = PBXBuildFile; fileRef = BA9FD5D11BAC0A7600996C85 /* CCComponentJS.h */; settings = {ASSET_TAGS = (); }; }; - BA9FD5D51BAC0A7600996C85 /* CCComponentJS.h in Headers */ = {isa = PBXBuildFile; fileRef = BA9FD5D11BAC0A7600996C85 /* CCComponentJS.h */; settings = {ASSET_TAGS = (); }; }; + BA9FD5D21BAC0A7600996C85 /* CCComponentJS.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BA9FD5D01BAC0A7600996C85 /* CCComponentJS.cpp */; }; + BA9FD5D31BAC0A7600996C85 /* CCComponentJS.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BA9FD5D01BAC0A7600996C85 /* CCComponentJS.cpp */; }; + BA9FD5D41BAC0A7600996C85 /* CCComponentJS.h in Headers */ = {isa = PBXBuildFile; fileRef = BA9FD5D11BAC0A7600996C85 /* CCComponentJS.h */; }; + BA9FD5D51BAC0A7600996C85 /* CCComponentJS.h in Headers */ = {isa = PBXBuildFile; fileRef = BA9FD5D11BAC0A7600996C85 /* CCComponentJS.h */; }; BAEE4D711AC3FFAD003BEB0F /* jsb_cocos2dx_3d_extension_auto.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BAEE4D6F1AC3FFAD003BEB0F /* jsb_cocos2dx_3d_extension_auto.cpp */; }; BAEE4D721AC3FFAD003BEB0F /* jsb_cocos2dx_3d_extension_auto.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BAEE4D6F1AC3FFAD003BEB0F /* jsb_cocos2dx_3d_extension_auto.cpp */; }; BAEE4D731AC3FFAD003BEB0F /* jsb_cocos2dx_3d_extension_auto.hpp in Headers */ = {isa = PBXBuildFile; fileRef = BAEE4D701AC3FFAD003BEB0F /* jsb_cocos2dx_3d_extension_auto.hpp */; }; @@ -211,7 +211,6 @@ 1A119E3C18BDF19200352BAA /* jsb_cocos2dx_spine_auto.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = jsb_cocos2dx_spine_auto.hpp; sourceTree = ""; }; 1A119E3E18BDF19200352BAA /* jsb_cocos2dx_studio_auto.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = jsb_cocos2dx_studio_auto.cpp; sourceTree = ""; }; 1A119E3F18BDF19200352BAA /* jsb_cocos2dx_studio_auto.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = jsb_cocos2dx_studio_auto.hpp; sourceTree = ""; }; - 1A119E4318BDF19200352BAA /* Android.mk */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = Android.mk; sourceTree = ""; }; 1A119E4418BDF19200352BAA /* js_bindings_chipmunk_auto_classes.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = js_bindings_chipmunk_auto_classes.cpp; sourceTree = ""; }; 1A119E4518BDF19200352BAA /* js_bindings_chipmunk_auto_classes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = js_bindings_chipmunk_auto_classes.h; sourceTree = ""; }; 1A119E4618BDF19200352BAA /* js_bindings_chipmunk_auto_classes_registration.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = js_bindings_chipmunk_auto_classes_registration.h; sourceTree = ""; }; @@ -224,7 +223,6 @@ 1A119E4D18BDF19200352BAA /* js_bindings_chipmunk_registration.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = js_bindings_chipmunk_registration.h; sourceTree = ""; }; 1A119E4E18BDF19200352BAA /* cocos2d_specifics.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = cocos2d_specifics.cpp; sourceTree = ""; }; 1A119E4F18BDF19200352BAA /* cocos2d_specifics.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = cocos2d_specifics.hpp; sourceTree = ""; }; - 1A119E5118BDF19200352BAA /* Android.mk */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = Android.mk; sourceTree = ""; }; 1A119E5218BDF19200352BAA /* cocosbuilder_specifics.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = cocosbuilder_specifics.hpp; sourceTree = ""; }; 1A119E5318BDF19200352BAA /* js_bindings_ccbreader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = js_bindings_ccbreader.cpp; sourceTree = ""; }; 1A119E5418BDF19200352BAA /* js_bindings_ccbreader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = js_bindings_ccbreader.h; sourceTree = ""; }; @@ -428,7 +426,6 @@ 1A119E4218BDF19200352BAA /* chipmunk */ = { isa = PBXGroup; children = ( - 1A119E4318BDF19200352BAA /* Android.mk */, 1A119E4418BDF19200352BAA /* js_bindings_chipmunk_auto_classes.cpp */, 1A119E4518BDF19200352BAA /* js_bindings_chipmunk_auto_classes.h */, 1A119E4618BDF19200352BAA /* js_bindings_chipmunk_auto_classes_registration.h */, @@ -446,7 +443,6 @@ 1A119E5018BDF19200352BAA /* cocosbuilder */ = { isa = PBXGroup; children = ( - 1A119E5118BDF19200352BAA /* Android.mk */, 1A119E5218BDF19200352BAA /* cocosbuilder_specifics.hpp */, 1A119E5318BDF19200352BAA /* js_bindings_ccbreader.cpp */, 1A119E5418BDF19200352BAA /* js_bindings_ccbreader.h */, diff --git a/tests/js-tests/project/Classes/js_DrawNode3D_bindings.cpp b/tests/js-tests/project/Classes/js_DrawNode3D_bindings.cpp index cc1bb7a1f0..e3d0dc14fb 100644 --- a/tests/js-tests/project/Classes/js_DrawNode3D_bindings.cpp +++ b/tests/js-tests/project/Classes/js_DrawNode3D_bindings.cpp @@ -485,29 +485,15 @@ bool js_cocos2dx_DrawNode3D_constructor(JSContext *cx, uint32_t argc, jsval *vp) { JS::CallArgs args = JS::CallArgsFromVp(argc, vp); bool ok = true; - cocos2d::DrawNode3D* cobj = new (std::nothrow) cocos2d::DrawNode3D(); + cocos2d::DrawNode3D* cobj = new (std::nothrow) cocos2d::DrawNode3D; cobj->init(); - cocos2d::Ref *_ccobj = dynamic_cast(cobj); - if (_ccobj) { - _ccobj->autorelease(); - } - TypeTest t; - js_type_class_t *typeClass = nullptr; - std::string typeName = t.s_name(); - auto typeMapIter = _js_global_type_map.find(typeName); - CCASSERT(typeMapIter != _js_global_type_map.end(), "Can't find the class type!"); - typeClass = typeMapIter->second; - CCASSERT(typeClass, "The value is null."); - // JSObject *obj = JS_NewObject(cx, typeClass->jsclass, typeClass->proto, typeClass->parentProto); - JS::RootedObject proto(cx, typeClass->proto.ref()); - JS::RootedObject parent(cx, typeClass->parentProto.ref()); - JS::RootedObject obj(cx, JS_NewObject(cx, typeClass->jsclass, proto, parent)); - args.rval().set(OBJECT_TO_JSVAL(obj)); + js_type_class_t *typeClass = js_get_type_from_native(cobj); + // link the native object with the javascript object - js_proxy_t* p = jsb_new_proxy(cobj, obj); - AddNamedObjectRoot(cx, &p->obj, "cocos2d::DrawNode3D"); - if (JS_HasProperty(cx, obj, "_ctor", &ok) && ok) - ScriptingCore::getInstance()->executeFunctionWithOwner(OBJECT_TO_JSVAL(obj), "_ctor", args); + JS::RootedObject jsobj(cx, jsb_ref_create_jsobject(cx, cobj, typeClass, "cocos2d::DrawNode3D")); + args.rval().set(OBJECT_TO_JSVAL(jsobj)); + if (JS_HasProperty(cx, jsobj, "_ctor", &ok) && ok) + ScriptingCore::getInstance()->executeFunctionWithOwner(OBJECT_TO_JSVAL(jsobj), "_ctor", args); return true; } @@ -520,9 +506,6 @@ static bool js_is_native_obj(JSContext *cx, uint32_t argc, jsval *vp) extern JSObject *jsb_cocos2d_Node_prototype; -void js_cocos2d_DrawNode3D_finalize(JSFreeOp *fop, JSObject *obj) { - CCLOGINFO("jsbindings: finalizing JS object %p (DrawNode3D)", obj); -} void js_register_cocos2dx_DrawNode3D(JSContext *cx, JS::HandleObject global) { jsb_cocos2d_DrawNode3D_class = (JSClass *)calloc(1, sizeof(JSClass)); @@ -534,7 +517,7 @@ void js_register_cocos2dx_DrawNode3D(JSContext *cx, JS::HandleObject global) { jsb_cocos2d_DrawNode3D_class->enumerate = JS_EnumerateStub; jsb_cocos2d_DrawNode3D_class->resolve = JS_ResolveStub; jsb_cocos2d_DrawNode3D_class->convert = JS_ConvertStub; - jsb_cocos2d_DrawNode3D_class->finalize = js_cocos2d_DrawNode3D_finalize; + jsb_cocos2d_DrawNode3D_class->finalize = jsb_ref_finalize; jsb_cocos2d_DrawNode3D_class->flags = JSCLASS_HAS_RESERVED_SLOTS(2); static JSPropertySpec properties[] = {