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 fc873e3317..4231eac359 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 @@ -37,26 +37,7 @@ void static freeSpaceChildren(cpSpace *space); template static bool dummy_constructor(JSContext *cx, uint32_t argc, jsval *vp) { - TypeTest t; - T* cobj = new (std::nothrow) T(); - cobj->autorelease(); - js_type_class_t *p; - 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!"); - p = typeMapIter->second; - CCASSERT(p, "The value is null."); - - JS::RootedObject proto(cx, p->proto.ref()); - JS::RootedObject parentProto(cx, p->parentProto.ref()); - JS::RootedObject _tmp(cx, JS_NewObject(cx, p->jsclass, proto, parentProto)); - js_proxy_t *pp = jsb_new_proxy(cobj, _tmp); - JS::AddObjectRoot(cx, &pp->obj); - JS::CallArgs args = JS::CallArgsFromVp(argc, vp); - args.rval().set(OBJECT_TO_JSVAL(_tmp)); - - return true; + return false; } #pragma mark - convertions @@ -68,7 +49,6 @@ static bool dummy_constructor(JSContext *cx, uint32_t argc, jsval *vp) { JSClass* JSPROXY_CCPhysicsSprite_class = NULL; JSObject* JSPROXY_CCPhysicsSprite_object = NULL; -// Constructor // Arguments: // Ret value: BOOL (b) @@ -180,27 +160,12 @@ bool JSB_CCPhysicsDebugNode_debugNodeForCPSpace__static(JSContext *cx, uint32_t PhysicsDebugNode* ret = PhysicsDebugNode::create(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, "CCDebugNode"); - } else { - jsret = JSVAL_NULL; - } - } while (0); + if (ret) { + js_type_class_t *typeClass = js_get_type_from_native(ret); + JS::RootedValue jsret(cx, OBJECT_TO_JSVAL(jsb_ref_autoreleased_get_or_create_jsobject(cx, ret, typeClass, "cocos2d::extension::PhysicsDebugNode"))); + } else { + jsret = JSVAL_NULL; + } args.rval().set(jsret); return true; @@ -249,24 +214,12 @@ bool JSB_CCPhysicsDebugNode_constructor(JSContext *cx, uint32_t argc, jsval *vp) JS::CallArgs args = JS::CallArgsFromVp(argc, vp); bool ok = true; PhysicsDebugNode* cobj = new (std::nothrow) PhysicsDebugNode(); - 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)); - // link the native object with the javascript object - js_proxy_t* p = jsb_new_proxy(cobj, obj); - JS::AddNamedObjectRoot(cx, &p->obj, "PhysicsDebugNode"); + + js_type_class_t *typeClass = js_get_type_from_native(cobj); + JS::RootedObject obj(cx, jsb_ref_get_or_create_jsobject(cx, cobj, typeClass, "cocos2d::extension::PhysicsDebugNode")); + JS::RootedValue retVal(cx, OBJECT_TO_JSVAL(obj)); + args.rval().set(retVal); + if (JS_HasProperty(cx, obj, "_ctor", &ok)) ScriptingCore::getInstance()->executeFunctionWithOwner(OBJECT_TO_JSVAL(obj), "_ctor", args); return true; @@ -283,7 +236,6 @@ 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_ref_finalize; JSB_CCPhysicsDebugNode_class->flags = 0; static JSPropertySpec properties[] = { @@ -321,6 +273,7 @@ bool JSPROXY_CCPhysicsSprite_spriteWithFile_rect__static(JSContext *cx, uint32_t JS::CallArgs args = JS::CallArgsFromVp(argc, vp); bool ok = true; + PhysicsSprite* ret = nullptr; if (argc == 2) { const char* arg0 = nullptr; std::string arg0_tmp; ok &= jsval_to_std_string(cx, args.get(0), &arg0_tmp); arg0 = arg0_tmp.c_str(); @@ -328,64 +281,28 @@ bool JSPROXY_CCPhysicsSprite_spriteWithFile_rect__static(JSContext *cx, uint32_t ok &= jsval_to_ccrect(cx, args.get(1), &arg1); JSB_PRECONDITION2(ok, cx, false, "Error processing arguments"); - PhysicsSprite* ret = PhysicsSprite::create(arg0, arg1); - - 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); - return true; + ret = PhysicsSprite::create(arg0, arg1); } - if (argc == 1) { + else if (argc == 1) { const char* arg0 = nullptr; std::string arg0_tmp; ok &= jsval_to_std_string(cx, args.get(0), &arg0_tmp); arg0 = arg0_tmp.c_str(); JSB_PRECONDITION2(ok, cx, false, "Error processing arguments"); - PhysicsSprite* ret = PhysicsSprite::create(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); - return true; + ret = PhysicsSprite::create(arg0); } - return false; - + else { + return false; + } + + jsval jsret; + if (ret) { + js_type_class_t *typeClass = js_get_type_from_native(ret); + jsret = OBJECT_TO_JSVAL(jsb_ref_autoreleased_get_or_create_jsobject(cx, ret, typeClass, "cocos2d::extension::PhysicsSprite")); + } else { + jsret = JSVAL_NULL; + } + args.rval().set(jsret); + return true; } // Arguments: SpriteFrame* @@ -405,25 +322,12 @@ bool JSPROXY_CCPhysicsSprite_spriteWithSpriteFrame__static(JSContext *cx, uint32 PhysicsSprite* ret = PhysicsSprite::createWithSpriteFrame(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); + if (ret) { + js_type_class_t *typeClass = js_get_type_from_native(ret); + JS::RootedValue jsret(cx, OBJECT_TO_JSVAL(jsb_ref_autoreleased_get_or_create_jsobject(cx, ret, typeClass, "cocos2d::extension::PhysicsSprite"))); + } else { + jsret = JSVAL_NULL; + } args.rval().set(jsret); return true; } @@ -456,10 +360,9 @@ bool JSPROXY_CCPhysicsSprite_constructor(JSContext *cx, uint32_t argc, jsval *vp bool ok = true; 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::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; @@ -490,7 +393,6 @@ 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 = jsb_ref_finalize; JSPROXY_CCPhysicsSprite_class->flags = 0; static JSPropertySpec properties[] = { @@ -1230,7 +1132,7 @@ bool JSB_cpSpace_removeBody(JSContext *cx, uint32_t argc, jsval *vp) { ok &= jsval_to_c_class( cx, args.get(0), (void**)&arg1, &retproxy ); JSB_PRECONDITION(ok, "Error processing arguments"); - cpSpaceRemoveBody((cpSpace*)arg0 , (cpBody*)arg1 ); + cpSpaceRemoveBody((cpSpace*)arg0, (cpBody*)arg1); JS::RemoveObjectRoot(cx, &retproxy->jsobj); args.rval().setUndefined(); @@ -2111,8 +2013,17 @@ bool JSB_cpBase_constructor(JSContext *cx, uint32_t argc, jsval *vp) void JSB_cpBase_finalize(JSFreeOp *fop, JSObject *obj) { CCLOGINFO("jsbindings: finalizing JS object %p (cpBase)", obj); + JSContext *cx = ScriptingCore::getInstance()->getGlobalContext(); + JS::RootedObject jsobj(cx, obj); - // should not delete the handle since it was manually added + js_proxy_t* nproxy = nullptr; + js_proxy_t* jsproxy = nullptr; + jsproxy = jsb_get_js_proxy(jsobj); + if (jsproxy) + { + nproxy = jsb_get_native_proxy(jsproxy->ptr); + jsb_remove_proxy(nproxy, jsproxy); + } } bool JSB_cpBase_getHandle(JSContext *cx, uint32_t argc, jsval *vp) diff --git a/cocos/scripting/js-bindings/manual/cocosbuilder/js_bindings_ccbreader.cpp b/cocos/scripting/js-bindings/manual/cocosbuilder/js_bindings_ccbreader.cpp index 6c910a1530..46e354a4ae 100644 --- a/cocos/scripting/js-bindings/manual/cocosbuilder/js_bindings_ccbreader.cpp +++ b/cocos/scripting/js-bindings/manual/cocosbuilder/js_bindings_ccbreader.cpp @@ -141,8 +141,8 @@ bool js_cocos2dx_CCBReader_readNodeGraphFromFile(JSContext *cx, uint32_t argc, j cocos2d::Node* ret = cobj->readNodeGraphFromFile(arg0, arg1); jsval jsret; do { if (ret) { - js_proxy_t *proxy = js_get_or_create_proxy(cx, ret); - jsret = OBJECT_TO_JSVAL(proxy->obj); + JS::RootedObject jsobj(cx, js_get_or_create_jsobject(cx, ret)); + jsret = OBJECT_TO_JSVAL(jsobj); } else { jsret = JSVAL_NULL; } @@ -158,8 +158,8 @@ bool js_cocos2dx_CCBReader_readNodeGraphFromFile(JSContext *cx, uint32_t argc, j cocos2d::Node* ret = cobj->readNodeGraphFromFile(arg0); jsval jsret; do { if (ret) { - js_proxy_t *proxy = js_get_or_create_proxy(cx, ret); - jsret = OBJECT_TO_JSVAL(proxy->obj); + JS::RootedObject jsobj(cx, js_get_or_create_jsobject(cx, ret)); + jsret = OBJECT_TO_JSVAL(jsobj); } else { jsret = JSVAL_NULL; } @@ -185,8 +185,8 @@ bool js_cocos2dx_CCBReader_readNodeGraphFromFile(JSContext *cx, uint32_t argc, j cocos2d::Node* ret = cobj->readNodeGraphFromFile(arg0, arg1, arg2); jsval jsret; do { if (ret) { - js_proxy_t *proxy = js_get_or_create_proxy(cx, ret); - jsret = OBJECT_TO_JSVAL(proxy->obj); + JS::RootedObject jsobj(cx, js_get_or_create_jsobject(cx, ret)); + jsret = OBJECT_TO_JSVAL(jsobj); } else { jsret = JSVAL_NULL; } @@ -223,8 +223,8 @@ bool js_cocos2dx_CCBReader_createSceneWithNodeGraphFromFile(JSContext *cx, uint3 cocos2d::Scene* ret = cobj->createSceneWithNodeGraphFromFile(arg0, arg1); jsval jsret; do { if (ret) { - js_proxy_t *proxy = js_get_or_create_proxy(cx, ret); - jsret = OBJECT_TO_JSVAL(proxy->obj); + JS::RootedObject jsobj(cx, js_get_or_create_jsobject(cx, ret)); + jsret = OBJECT_TO_JSVAL(jsobj); } else { jsret = JSVAL_NULL; } @@ -240,8 +240,8 @@ bool js_cocos2dx_CCBReader_createSceneWithNodeGraphFromFile(JSContext *cx, uint3 cocos2d::Scene* ret = cobj->createSceneWithNodeGraphFromFile(arg0); jsval jsret; do { if (ret) { - js_proxy_t *proxy = js_get_or_create_proxy(cx, ret); - jsret = OBJECT_TO_JSVAL(proxy->obj); + JS::RootedObject jsobj(cx, js_get_or_create_jsobject(cx, ret)); + jsret = OBJECT_TO_JSVAL(jsobj); } else { jsret = JSVAL_NULL; } @@ -266,10 +266,11 @@ bool js_cocos2dx_CCBReader_createSceneWithNodeGraphFromFile(JSContext *cx, uint3 JSB_PRECONDITION2(ok, cx, false, "Error processing arguments"); cocos2d::Scene* ret = cobj->createSceneWithNodeGraphFromFile(arg0, arg1, arg2); - jsval jsret; do { + jsval jsret; + do { if (ret) { - js_proxy_t *proxy = js_get_or_create_proxy(cx, ret); - jsret = OBJECT_TO_JSVAL(proxy->obj); + JS::RootedObject jsobj(cx, js_get_or_create_jsobject(cx, ret)); + jsret = OBJECT_TO_JSVAL(jsobj); } else { jsret = JSVAL_NULL; } @@ -294,14 +295,9 @@ bool js_CocosBuilder_create(JSContext *cx, uint32_t argc, jsval *vp) jsval jsret; if (ret) { - js_proxy_t *proxy = jsb_get_native_proxy(ret); - if (proxy) { - jsret = OBJECT_TO_JSVAL(proxy->obj); - } else { - // create a new js obj of that class - proxy = js_get_or_create_proxy(cx, ret); - jsret = OBJECT_TO_JSVAL(proxy->obj); - } + // create a new js obj of that class + JS::RootedObject jsobj(cx, js_get_or_create_jsobject(cx, ret)); + jsret = OBJECT_TO_JSVAL(jsobj); } else { jsret = JSVAL_NULL; } diff --git a/cocos/scripting/js-bindings/manual/cocostudio/jsb_cocos2dx_studio_manual.cpp b/cocos/scripting/js-bindings/manual/cocostudio/jsb_cocos2dx_studio_manual.cpp index 0263abaebc..559596ae2d 100644 --- a/cocos/scripting/js-bindings/manual/cocostudio/jsb_cocos2dx_studio_manual.cpp +++ b/cocos/scripting/js-bindings/manual/cocostudio/jsb_cocos2dx_studio_manual.cpp @@ -37,7 +37,7 @@ void JSArmatureWrapper::movementCallbackFunc(cocostudio::Armature *armature, coc { JSContext *cx = ScriptingCore::getInstance()->getGlobalContext(); JS::RootedObject thisObj(cx, getJSCallbackThis().toObjectOrNull()); - js_proxy_t *proxy = js_get_or_create_proxy(cx, armature); + JS::RootedObject jsarmature(cx, js_get_or_create_jsobject(cx, armature)); JS::RootedValue callback(cx, getJSCallbackFunc()); JS::RootedValue retval(cx); if (!callback.isNullOrUndefined()) @@ -48,7 +48,7 @@ void JSArmatureWrapper::movementCallbackFunc(cocostudio::Armature *armature, coc jsval idVal = std_string_to_jsval(cx, movementID); jsval valArr[3]; - valArr[0] = OBJECT_TO_JSVAL(proxy->obj); + valArr[0] = OBJECT_TO_JSVAL(jsarmature); valArr[1] = movementVal; valArr[2] = idVal; @@ -82,7 +82,7 @@ void JSArmatureWrapper::frameCallbackFunc(cocostudio::Bone *bone, const std::str JSContext *cx = ScriptingCore::getInstance()->getGlobalContext(); JS::RootedObject thisObj(cx, getJSCallbackThis().toObjectOrNull()); JS::RootedValue callback(cx, getJSCallbackFunc()); - js_proxy_t *proxy = js_get_or_create_proxy(cx, bone); + JS::RootedObject jsbone(cx, js_get_or_create_jsobject(cx, bone)); JS::RootedValue retval(cx); if (!callback.isNullOrUndefined()) { @@ -91,7 +91,7 @@ void JSArmatureWrapper::frameCallbackFunc(cocostudio::Bone *bone, const std::str jsval currentIndexVal = INT_TO_JSVAL(currentFrameIndex); jsval valArr[4]; - valArr[0] = OBJECT_TO_JSVAL(proxy->obj); + valArr[0] = OBJECT_TO_JSVAL(jsbone); valArr[1] = nameVal; valArr[2] = originIndexVal; valArr[3] = currentIndexVal; @@ -800,8 +800,8 @@ bool js_get_AnimationData_movementDataDic(JSContext *cx, JS::HandleObject obj, J cocostudio::MovementData* movementData = iter->second; do { if (movementData) { - js_proxy_t *jsProxy = js_get_or_create_proxy(cx, (cocostudio::MovementData*)movementData); - dictElement = OBJECT_TO_JSVAL(jsProxy->obj); + JS::RootedObject jsobj(cx, js_get_or_create_jsobject(cx, movementData)); + dictElement = OBJECT_TO_JSVAL(jsobj); } else { CCLOGERROR("js_get_AnimationData_movementDataDic : Fail to retrieve property movementDataDic of AnimationData."); return false; @@ -1154,8 +1154,8 @@ bool js_get_TextureData_contourDataList(JSContext *cx, JS::HandleObject obj, JS: for(const auto& contourData : ret) { JS::RootedValue arrElement(cx); - js_proxy_t *jsProxy = js_get_or_create_proxy(cx, (cocostudio::ContourData*)contourData); - arrElement = OBJECT_TO_JSVAL(jsProxy->obj); + JS::RootedObject contourObj(cx, js_get_or_create_jsobject(cx, contourData)); + arrElement = OBJECT_TO_JSVAL(contourObj); if (!JS_SetElement(cx, jsretArr, i, arrElement)) { break; diff --git a/cocos/scripting/js-bindings/manual/component/CCComponentJS.cpp b/cocos/scripting/js-bindings/manual/component/CCComponentJS.cpp index f6dee2717f..97d87e188a 100644 --- a/cocos/scripting/js-bindings/manual/component/CCComponentJS.cpp +++ b/cocos/scripting/js-bindings/manual/component/CCComponentJS.cpp @@ -75,6 +75,15 @@ ComponentJS::ComponentJS(const std::string& scriptFileName) JS::RootedObject obj(cx, JS_NewObject(cx, theClass, proto, parent)); jsObj->ref() = obj; + // Unbind current proxy binding + js_proxy_t* nproxy = jsb_get_native_proxy(this); + if (nproxy) + { +#if CC_ENABLE_GC_FOR_NATIVE_OBJECTS + JS::RemoveObjectRoot(cx, &nproxy->obj); +#endif // CC_ENABLE_GC_FOR_NATIVE_OBJECTS + jsb_remove_proxy(nproxy, jsb_get_js_proxy(nproxy->obj)); + } // link the native object with the javascript object jsb_new_proxy(this, jsObj->ref()); diff --git a/cocos/scripting/js-bindings/manual/experimental/jsb_cocos2dx_experimental_video_manual.cpp b/cocos/scripting/js-bindings/manual/experimental/jsb_cocos2dx_experimental_video_manual.cpp index 7f3f343ad5..8e0f25aca3 100644 --- a/cocos/scripting/js-bindings/manual/experimental/jsb_cocos2dx_experimental_video_manual.cpp +++ b/cocos/scripting/js-bindings/manual/experimental/jsb_cocos2dx_experimental_video_manual.cpp @@ -22,11 +22,8 @@ static bool jsb_cocos2dx_experimental_ui_VideoPlayer_addEventListener(JSContext std::shared_ptr func(new JSFunctionWrapper(cx, obj, args.get(0))); cobj->addEventListener([=](Ref* widget, experimental::ui::VideoPlayer::EventType type)->void{ jsval arg[2]; - js_proxy_t *proxy = js_get_or_create_proxy(cx, widget); - if(proxy) - arg[0] = OBJECT_TO_JSVAL(proxy->obj); - else - arg[0] = JSVAL_NULL; + JS::RootedObject jsobj(cx, js_get_or_create_jsobject(cx, widget)); + arg[0] = OBJECT_TO_JSVAL(jsobj); arg[1] = int32_to_jsval(cx, (int32_t)type); JS::RootedValue rval(cx); diff --git a/cocos/scripting/js-bindings/manual/experimental/jsb_cocos2dx_experimental_webView_manual.cpp b/cocos/scripting/js-bindings/manual/experimental/jsb_cocos2dx_experimental_webView_manual.cpp index 27badfad61..ec61e0c33b 100644 --- a/cocos/scripting/js-bindings/manual/experimental/jsb_cocos2dx_experimental_webView_manual.cpp +++ b/cocos/scripting/js-bindings/manual/experimental/jsb_cocos2dx_experimental_webView_manual.cpp @@ -22,11 +22,8 @@ static bool jsb_cocos2dx_experimental_webView_setOnShouldStartLoading(JSContext cobj->setOnShouldStartLoading([=](experimental::ui::WebView *sender, const std::string &url)->bool{ JSB_AUTOCOMPARTMENT_WITH_GLOBAL_OBJCET jsval arg[2]; - js_proxy_t *proxy = js_get_or_create_proxy(cx, sender); - if(proxy) - arg[0] = OBJECT_TO_JSVAL(proxy->obj); - else - arg[0] = JSVAL_NULL; + JS::RootedObject jsobj(cx, js_get_or_create_jsobject(cx, sender)); + arg[0] = OBJECT_TO_JSVAL(jsobj); arg[1] = std_string_to_jsval(cx, url); JS::RootedValue rval(cx); @@ -53,11 +50,8 @@ static bool jsb_cocos2dx_experimental_webView_setOnDidFinishLoading(JSContext *c cobj->setOnDidFinishLoading([=](experimental::ui::WebView *sender, const std::string &url)->void{ JSB_AUTOCOMPARTMENT_WITH_GLOBAL_OBJCET jsval arg[2]; - js_proxy_t *proxy = js_get_or_create_proxy(cx, sender); - if(proxy) - arg[0] = OBJECT_TO_JSVAL(proxy->obj); - else - arg[0] = JSVAL_NULL; + JS::RootedObject jsobj(cx, js_get_or_create_jsobject(cx, sender)); + arg[0] = OBJECT_TO_JSVAL(jsobj); arg[1] = std_string_to_jsval(cx, url); JS::RootedValue rval(cx); @@ -83,11 +77,8 @@ static bool jsb_cocos2dx_experimental_webView_setOnDidFailLoading(JSContext *cx, cobj->setOnDidFailLoading([=](experimental::ui::WebView *sender, const std::string &url)->void{ JSB_AUTOCOMPARTMENT_WITH_GLOBAL_OBJCET jsval arg[2]; - js_proxy_t *proxy = js_get_or_create_proxy(cx, sender); - if(proxy) - arg[0] = OBJECT_TO_JSVAL(proxy->obj); - else - arg[0] = JSVAL_NULL; + JS::RootedObject jsobj(cx, js_get_or_create_jsobject(cx, sender)); + arg[0] = OBJECT_TO_JSVAL(jsobj); arg[1] = std_string_to_jsval(cx, url); JS::RootedValue rval(cx); @@ -113,11 +104,8 @@ static bool jsb_cocos2dx_experimental_webView_setOnJSCallback(JSContext *cx, uin cobj->setOnJSCallback([=](experimental::ui::WebView *sender, const std::string &url)->void{ JSB_AUTOCOMPARTMENT_WITH_GLOBAL_OBJCET jsval arg[2]; - js_proxy_t *proxy = js_get_or_create_proxy(cx, sender); - if(proxy) - arg[0] = OBJECT_TO_JSVAL(proxy->obj); - else - arg[0] = JSVAL_NULL; + JS::RootedObject jsobj(cx, js_get_or_create_jsobject(cx, sender)); + arg[0] = OBJECT_TO_JSVAL(jsobj); arg[1] = std_string_to_jsval(cx, url); JS::RootedValue rval(cx); diff --git a/cocos/scripting/js-bindings/manual/extension/jsb_cocos2dx_extension_manual.cpp b/cocos/scripting/js-bindings/manual/extension/jsb_cocos2dx_extension_manual.cpp index 1ba9a19b74..b3244e9168 100644 --- a/cocos/scripting/js-bindings/manual/extension/jsb_cocos2dx_extension_manual.cpp +++ b/cocos/scripting/js-bindings/manual/extension/jsb_cocos2dx_extension_manual.cpp @@ -425,8 +425,8 @@ static bool js_cocos2dx_CCTableView_create(JSContext *cx, uint32_t argc, jsval * do { if (ret) { - js_proxy_t *proxy = js_get_or_create_proxy(cx, ret); - jsret = OBJECT_TO_JSVAL(proxy->obj); + JS::RootedObject jsobj(cx, js_get_or_create_jsobject(cx, ret)); + jsret = OBJECT_TO_JSVAL(jsobj); } else { @@ -560,7 +560,7 @@ public: js_proxy_t* p = jsb_get_native_proxy(controlButton); if (!p) { - log("Failed to get proxy for control button"); + log("Failed to get proxy for control button %p", controlButton); return; } @@ -699,133 +699,130 @@ static bool js_cocos2dx_CCControl_removeTargetWithActionForControlEvents(JSConte return false; } -/* -static bool js_cocos2dx_ext_AssetsManager_updateAssets(JSContext *cx, uint32_t argc, jsval *vp) +bool js_cocos2dx_extension_EventListenerAssetsManagerEx_init(JSContext *cx, uint32_t argc, jsval *vp) { - jsval *argv = JS_ARGV(cx, vp); + JS::CallArgs args = JS::CallArgsFromVp(argc, vp); bool ok = true; - JS::RootedObject obj(cx, JS_THIS_OBJECT(cx, vp)); + JS::RootedObject obj(cx, args.thisv().toObjectOrNull()); js_proxy_t *proxy = jsb_get_js_proxy(obj); - cocos2d::extension::AssetsManager* cobj = (cocos2d::extension::AssetsManager *)(proxy ? proxy->ptr : NULL); - JSB_PRECONDITION2( cobj, cx, false, "js_cocos2dx_extension_AssetsManager_updateAssets : Invalid Native Object"); - if (argc == 1) { - std::unordered_map dict; + cocos2d::extension::EventListenerAssetsManagerEx* cobj = (cocos2d::extension::EventListenerAssetsManagerEx *)(proxy ? proxy->ptr : NULL); + JSB_PRECONDITION2( cobj, cx, false, "js_cocos2dx_extension_EventListenerAssetsManagerEx_init : Invalid Native Object"); + if (argc == 2) { + const cocos2d::extension::AssetsManagerEx* arg0 = nullptr; + std::function arg1; do { - if (!argv[0].isObject()) { ok = false; break; } - JS::RootedObject tmpObj(cx, JSVAL_TO_OBJECT(argv[0])); - - if (!tmpObj) { - CCLOG("%s", "jsval_to_ccvaluemap: the jsval is not an object."); - return false; - } - - JSObject* it = JS_NewPropertyIterator(cx, tmpObj); - while (true) + if (args.get(0).isNull()) { arg0 = nullptr; break; } + if (!args.get(0).isObject()) { ok = false; break; } + js_proxy_t *jsProxy; + JS::RootedObject tmpObj(cx, args.get(0).toObjectOrNull()); + jsProxy = jsb_get_js_proxy(tmpObj); + arg0 = (const cocos2d::extension::AssetsManagerEx*)(jsProxy ? jsProxy->ptr : NULL); + JSB_PRECONDITION2( arg0, cx, false, "Invalid Native Object"); + } while (0); + do { + if(JS_TypeOfValue(cx, args.get(1)) == JSTYPE_FUNCTION) { - jsid idp; - jsval key; - if (! JS_NextProperty(cx, it, &idp) || ! JS_IdToValue(cx, idp, &key)) { - return false; // error - } - - if (key == JSVAL_VOID) { - break; // end of iteration - } - - if (!JSVAL_IS_STRING(key)) { - continue; // ignore integer properties - } - - JSStringWrapper keyWrapper(JSVAL_TO_STRING(key), cx); - std::string keystr = keyWrapper.get(); - - JS::RootedValue value(cx); - JS_GetPropertyById(cx, tmpObj, idp, &value); - - JS::RootedObject tmp(cx); - JS::RootedValue jsSrcUrl(cx); - JS::RootedValue jsStoragePath(cx); - JS::RootedValue jsCustomId(cx); - ok = value.isObject() && - JS_ValueToObject(cx, JS::RootedValue(cx, value), &tmp) && - JS_GetProperty(cx, tmp, "srcUrl", &jsSrcUrl) && - JS_GetProperty(cx, tmp, "storagePath", &jsStoragePath) && - JS_GetProperty(cx, tmp, "customId", &jsCustomId); - JSB_PRECONDITION3(ok, cx, false, "Error parsing map entry"); - - Downloader::DownloadUnit unit; - - JSString *jsstr = JS::ToString(cx, jsSrcUrl); - JSB_PRECONDITION3(jsstr, cx, false, "Error processing srcUrl value of entry: %s", keystr); - JSStringWrapper srcUrlStr(jsstr); - unit.srcUrl = srcUrlStr.get(); - - jsstr = JS::ToString(cx, jsStoragePath); - JSB_PRECONDITION3(jsstr, cx, false, "Error processing storagePath value of entry: %s", keystr); - JSStringWrapper storagePathStr(jsstr); - unit.storagePath = storagePathStr.get(); - - jsstr = JS::ToString(cx, jsCustomId); - JSB_PRECONDITION3(jsstr, cx, false, "Error processing customId value of entry: %s", keystr); - JSStringWrapper customIdStr(jsstr); - unit.customId = customIdStr.get(); - - dict[keystr] = unit; + JS::RootedObject jstarget(cx, args.thisv().toObjectOrNull()); + std::shared_ptr func(new JSFunctionWrapper(cx, jstarget, args.get(1))); + auto lambda = [=](cocos2d::extension::EventAssetsManagerEx* larg0) -> void { + JSB_AUTOCOMPARTMENT_WITH_GLOBAL_OBJCET + jsval largv[1]; + do { + if (larg0) { + js_type_class_t* typeClass = js_get_type_from_native(larg0); + largv[0] = OBJECT_TO_JSVAL(jsb_get_or_create_weak_jsobject(cx, larg0, typeClass, "cocos2d::extension::EventAssetsManagerEx")); + } else { + largv[0] = JSVAL_NULL; + } + } while (0); + JS::RootedValue rval(cx); + bool succeed = func->invoke(1, &largv[0], &rval); + if (!succeed && JS_IsExceptionPending(cx)) { + JS_ReportPendingException(cx); + } + removeJSObject(cx, larg0); + }; + arg1 = lambda; } - } while (0); - JSB_PRECONDITION2(ok, cx, false, "js_cocos2dx_extension_AssetsManager_updateAssets : Error processing arguments"); - cobj->updateAssets(dict); - JS_SET_RVAL(cx, vp, JSVAL_VOID); - return true; - } - - JS_ReportError(cx, "js_cocos2dx_extension_AssetsManager_updateAssets : wrong number of arguments: %d, was expecting %d", argc, 1); - return false; -} - -bool js_cocos2dx_ext_AssetsManager_getFailedAssets(JSContext *cx, uint32_t argc, jsval *vp) -{ - JS::RootedObject obj(cx, JS_THIS_OBJECT(cx, vp)); - js_proxy_t *proxy = jsb_get_js_proxy(obj); - cocos2d::extension::AssetsManager* cobj = (cocos2d::extension::AssetsManager *)(proxy ? proxy->ptr : NULL); - JSB_PRECONDITION2( cobj, cx, false, "js_cocos2dx_extension_AssetsManager_getFailedAssets : Invalid Native Object"); - if (argc == 0) { - const std::unordered_map &ret = cobj->getFailedAssets(); + else + { + arg1 = nullptr; + } + } while(0) + ; + JSB_PRECONDITION2(ok, cx, false, "js_cocos2dx_extension_EventListenerAssetsManagerEx_init : Error processing arguments"); + bool ret = cobj->init(arg0, arg1); jsval jsret = JSVAL_NULL; - do { - JSObject* jsRet = JS_NewObject(cx, NULL, NULL, NULL); - - for (auto it = ret.cbegin(); it != ret.cend(); ++it) { - std::string key = it->first; - const Downloader::DownloadUnit& unit = it->second; - - JS::RootedObject elem(cx, JS_NewObject(cx, NULL, NULL, NULL)); - if (!elem) - { - JS_ReportError(cx, "js_cocos2dx_extension_AssetsManager_getFailedAssets : can not create js object"); - break; - } - bool ok = JS_DefineProperty(cx, elem, "srcUrl", std_string_to_jsval(cx, unit.srcUrl), NULL, NULL, JSPROP_ENUMERATE | JSPROP_PERMANENT) && - JS_DefineProperty(cx, elem, "storagePath", std_string_to_jsval(cx, unit.storagePath), NULL, NULL, JSPROP_ENUMERATE | JSPROP_PERMANENT) && - JS_DefineProperty(cx, elem, "customId", std_string_to_jsval(cx, unit.customId), NULL, NULL, JSPROP_ENUMERATE | JSPROP_PERMANENT); - JSB_PRECONDITION2(ok, cx, false, "js_cocos2dx_extension_AssetsManager_getFailedAssets : Error processing DownloadUnit struct"); - - if (!key.empty()) - { - JS::RootedValue dictElement(cx); - dictElement = OBJECT_TO_JSVAL(elem); - JS_SetProperty(cx, jsRet, key.c_str(), dictElement); - } - } - } while (0); - JS_SET_RVAL(cx, vp, jsret); + jsret = BOOLEAN_TO_JSVAL(ret); + args.rval().set(jsret); return true; } - JS_ReportError(cx, "js_cocos2dx_extension_AssetsManager_getFailedAssets : wrong number of arguments: %d, was expecting %d", argc, 0); + JS_ReportError(cx, "js_cocos2dx_extension_EventListenerAssetsManagerEx_init : wrong number of arguments: %d, was expecting %d", argc, 2); + return false; +} +bool js_cocos2dx_extension_EventListenerAssetsManagerEx_create(JSContext *cx, uint32_t argc, jsval *vp) +{ + JS::CallArgs args = JS::CallArgsFromVp(argc, vp); + bool ok = true; + if (argc == 2) { + cocos2d::extension::AssetsManagerEx* arg0 = nullptr; + std::function arg1; + do { + if (args.get(0).isNull()) { arg0 = nullptr; break; } + if (!args.get(0).isObject()) { ok = false; break; } + js_proxy_t *jsProxy; + JS::RootedObject tmpObj(cx, args.get(0).toObjectOrNull()); + jsProxy = jsb_get_js_proxy(tmpObj); + arg0 = (cocos2d::extension::AssetsManagerEx*)(jsProxy ? jsProxy->ptr : NULL); + JSB_PRECONDITION2( arg0, cx, false, "Invalid Native Object"); + } while (0); + do { + if(JS_TypeOfValue(cx, args.get(1)) == JSTYPE_FUNCTION) + { + JS::RootedObject jstarget(cx, args.thisv().toObjectOrNull()); + std::shared_ptr func(new JSFunctionWrapper(cx, jstarget, args.get(1))); + auto lambda = [=](cocos2d::extension::EventAssetsManagerEx* larg0) -> void { + JSB_AUTOCOMPARTMENT_WITH_GLOBAL_OBJCET + jsval largv[1]; + do { + if (larg0) { + js_type_class_t* typeClass = js_get_type_from_native(larg0); + largv[0] = OBJECT_TO_JSVAL(jsb_get_or_create_weak_jsobject(cx, larg0, typeClass, "cocos2d::extension::EventAssetsManagerEx")); + } else { + largv[0] = JSVAL_NULL; + } + } while (0); + JS::RootedValue rval(cx); + bool succeed = func->invoke(1, &largv[0], &rval); + if (!succeed && JS_IsExceptionPending(cx)) { + JS_ReportPendingException(cx); + } + removeJSObject(cx, larg0); + }; + arg1 = lambda; + } + else + { + arg1 = nullptr; + } + } while(0) + ; + JSB_PRECONDITION2(ok, cx, false, "js_cocos2dx_extension_EventListenerAssetsManagerEx_create : Error processing arguments"); + cocos2d::extension::EventListenerAssetsManagerEx* ret = cocos2d::extension::EventListenerAssetsManagerEx::create(arg0, arg1); + jsval jsret = JSVAL_NULL; + if (ret) { + JS::RootedObject jsobj(cx, js_get_or_create_jsobject(cx, ret)); + jsret = OBJECT_TO_JSVAL(jsobj); + } else { + jsret = JSVAL_NULL; + } + args.rval().set(jsret); + return true; + } + JS_ReportError(cx, "js_cocos2dx_extension_EventListenerAssetsManagerEx_create : wrong number of arguments"); return false; } -*/ __JSDownloaderDelegator::__JSDownloaderDelegator(JSContext *cx, JS::HandleObject obj, const std::string &url, JS::HandleObject callback) : _cx(cx) @@ -940,16 +937,8 @@ void __JSDownloaderDelegator::onSuccess(Texture2D *tex) if (tex) { valArr[0] = BOOLEAN_TO_JSVAL(true); - js_proxy_t* p = jsb_get_native_proxy(tex); - if (!p) - { - JS::RootedObject texProto(_cx, jsb_cocos2d_Texture2D_prototype); - JS::RootedObject obj(_cx, JS_NewObject(_cx, jsb_cocos2d_Texture2D_class, texProto, global)); - // link the native object with the javascript object - p = jsb_new_proxy(tex, obj); - JS::AddNamedObjectRoot(_cx, &p->obj, "cocos2d::Texture2D"); - } - valArr[1] = OBJECT_TO_JSVAL(p->obj); + JS::RootedObject jsobj(_cx, js_get_or_create_jsobject(_cx, tex)); + valArr[1] = OBJECT_TO_JSVAL(jsobj); } else { @@ -994,14 +983,17 @@ extern JSObject* jsb_cocos2d_extension_ScrollView_prototype; extern JSObject* jsb_cocos2d_extension_TableView_prototype; extern JSObject* jsb_cocos2d_extension_Control_prototype; extern JSObject* jsb_cocos2d_extension_AssetsManagerEx_prototype; +extern JSObject* jsb_cocos2d_extension_EventListenerAssetsManagerEx_prototype; extern JSObject* jsb_cocos2d_extension_Manifest_prototype; void register_all_cocos2dx_extension_manual(JSContext* cx, JS::HandleObject global) { JS::RootedObject ccObj(cx); + JS::RootedObject jsbObj(cx); JS::RootedValue tmpVal(cx); JS::RootedObject tmpObj(cx); get_or_create_js_obj(cx, global, "cc", &ccObj); + get_or_create_js_obj(cx, global, "jsb", &jsbObj); tmpObj.set(jsb_cocos2d_extension_AssetsManagerEx_prototype); JS_DefineFunction(cx, tmpObj, "retain", js_cocos2dx_retain, 0, JSPROP_ENUMERATE | JSPROP_PERMANENT); @@ -1010,8 +1002,11 @@ void register_all_cocos2dx_extension_manual(JSContext* cx, JS::HandleObject glob JS_DefineFunction(cx, tmpObj, "retain", js_cocos2dx_retain, 0, JSPROP_ENUMERATE | JSPROP_PERMANENT); JS_DefineFunction(cx, tmpObj, "release", js_cocos2dx_release, 0, JSPROP_ENUMERATE | JSPROP_PERMANENT); - //JS_DefineFunction(cx, jsb_cocos2d_extension_AssetsManager_prototype, "updateAssets", js_cocos2dx_ext_AssetsManager_updateAssets, 1, JSPROP_ENUMERATE | JSPROP_PERMANENT); - //JS_DefineFunction(cx, jsb_cocos2d_extension_AssetsManager_prototype, "getFailedAssets", js_cocos2dx_ext_AssetsManager_getFailedAssets, 0, JSPROP_ENUMERATE | JSPROP_PERMANENT); + JS_GetProperty(cx, ccObj, "EventListenerAssetsManager", &tmpVal); + tmpObj.set(tmpVal.toObjectOrNull()); + JS_DefineFunction(cx, tmpObj, "create", js_cocos2dx_extension_EventListenerAssetsManagerEx_create, 2, JSPROP_READONLY | JSPROP_PERMANENT); + tmpObj.set(jsb_cocos2d_extension_EventListenerAssetsManagerEx_prototype); + JS_DefineFunction(cx, tmpObj, "init", js_cocos2dx_extension_EventListenerAssetsManagerEx_init, 2, JSPROP_ENUMERATE | JSPROP_PERMANENT); tmpObj.set(jsb_cocos2d_extension_ScrollView_prototype); JS_DefineFunction(cx, tmpObj, "setDelegate", js_cocos2dx_CCScrollView_setDelegate, 1, JSPROP_ENUMERATE | JSPROP_PERMANENT); @@ -1027,8 +1022,5 @@ void register_all_cocos2dx_extension_manual(JSContext* cx, JS::HandleObject glob tmpObj.set(tmpVal.toObjectOrNull()); JS_DefineFunction(cx, tmpObj, "create", js_cocos2dx_CCTableView_create, 3, JSPROP_READONLY | JSPROP_PERMANENT); - JS::RootedObject jsbObj(cx); - get_or_create_js_obj(cx, global, "jsb", &jsbObj); - JS_DefineFunction(cx, jsbObj, "loadRemoteImg", js_load_remote_image, 2, JSPROP_READONLY | JSPROP_PERMANENT); } \ No newline at end of file diff --git a/cocos/scripting/js-bindings/manual/js_bindings_opengl.cpp b/cocos/scripting/js-bindings/manual/js_bindings_opengl.cpp index 3459ef2f71..42ab6d95f3 100644 --- a/cocos/scripting/js-bindings/manual/js_bindings_opengl.cpp +++ b/cocos/scripting/js-bindings/manual/js_bindings_opengl.cpp @@ -128,7 +128,6 @@ 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 = jsb_ref_finalize; js_cocos2dx_GLNode_class->flags = JSCLASS_HAS_RESERVED_SLOTS(2); static JSPropertySpec properties[] = { diff --git a/cocos/scripting/js-bindings/manual/navmesh/jsb_cocos2dx_navmesh_manual.cpp b/cocos/scripting/js-bindings/manual/navmesh/jsb_cocos2dx_navmesh_manual.cpp index 64bbfaaf32..331a69d2f1 100644 --- a/cocos/scripting/js-bindings/manual/navmesh/jsb_cocos2dx_navmesh_manual.cpp +++ b/cocos/scripting/js-bindings/manual/navmesh/jsb_cocos2dx_navmesh_manual.cpp @@ -58,12 +58,9 @@ static bool jsb_cocos2dx_navmesh_NavMeshAgent_move(JSContext *cx, uint32_t argc, std::shared_ptr func(new JSFunctionWrapper(cx, obj, args.get(1))); cobj->move(arg0, [=](cocos2d::NavMeshAgent *agent, float totalTimeAfterMove)->void{ - jsval arg[2]; - js_proxy_t *agentProxy = js_get_or_create_proxy(cx, agent); - if (proxy) - arg[0] = OBJECT_TO_JSVAL(agentProxy->obj); - else - arg[0] = JSVAL_NULL; + jsval arg[2]; + JS::RootedObject jsobj(cx, js_get_or_create_jsobject(cx, agent)); + arg[0] = OBJECT_TO_JSVAL(jsobj); arg[1] = DOUBLE_TO_JSVAL((double)totalTimeAfterMove); JS::RootedValue rval(cx); diff --git a/cocos/scripting/js-bindings/manual/network/XMLHTTPRequest.cpp b/cocos/scripting/js-bindings/manual/network/XMLHTTPRequest.cpp index 3f5de58d1c..158594130b 100644 --- a/cocos/scripting/js-bindings/manual/network/XMLHTTPRequest.cpp +++ b/cocos/scripting/js-bindings/manual/network/XMLHTTPRequest.cpp @@ -336,24 +336,36 @@ JS_BINDED_CONSTRUCTOR_IMPL(MinXmlHttpRequest) { JS::CallArgs args = JS::CallArgsFromVp(argc, vp); MinXmlHttpRequest* req = new (std::nothrow) MinXmlHttpRequest(); - req->autorelease(); - - js_proxy_t *p; - jsval out; JS::RootedObject proto(cx, MinXmlHttpRequest::js_proto); JS::RootedObject parentProto(cx, MinXmlHttpRequest::js_parent); JS::RootedObject obj(cx, JS_NewObject(cx, &MinXmlHttpRequest::js_class, proto, parentProto)); + js_proxy_t *p = jsb_new_proxy(req, obj); - if (obj) { +#if CC_ENABLE_GC_FOR_NATIVE_OBJECTS + js_add_FinalizeHook(cx, obj); + // don't retain it, already retained +#if COCOS2D_DEBUG + ScriptingCore::retainCount++; + CCLOG("++++++RETAINED++++++ %d Cpp(XMLHttpRequest): %p - JS: %p", ScriptingCore::retainCount, ref, obj.get()); +#endif // COCOS2D_DEBUG +#else + // autorelease it + req->autorelease(); + JS::AddNamedObjectRoot(cx, &p->obj, "XMLHttpRequest"); +#endif + + jsval out; + if (obj) + { JS_SetPrivate(obj, req); out = OBJECT_TO_JSVAL(obj); } - + else + { + out = JS::NullValue(); + } args.rval().set(out); - p = jsb_new_proxy(req, obj); - - JS::AddNamedObjectRoot(cx, &p->obj, "XMLHttpRequest"); return true; } diff --git a/cocos/scripting/js-bindings/manual/physics3d/jsb_cocos2dx_physics3d_manual.cpp b/cocos/scripting/js-bindings/manual/physics3d/jsb_cocos2dx_physics3d_manual.cpp index a0335e5522..cfdbcee04e 100644 --- a/cocos/scripting/js-bindings/manual/physics3d/jsb_cocos2dx_physics3d_manual.cpp +++ b/cocos/scripting/js-bindings/manual/physics3d/jsb_cocos2dx_physics3d_manual.cpp @@ -81,9 +81,9 @@ bool js_cocos2dx_PhysicsSprite3D_create(JSContext *cx, uint32_t argc, jsval *vp) ok &= jsval_to_physics3DRigidBodyDes(cx, args.get(1), &arg1); JSB_PRECONDITION2(ok, cx, false, "js_cocos2dx_physics3d_PhysicsSprite3D_create : Error processing arguments"); cocos2d::PhysicsSprite3D* ret = cocos2d::PhysicsSprite3D::create(arg0, &arg1); - - js_proxy_t *jsProxy = js_get_or_create_proxy(cx, (cocos2d::PhysicsSprite3D*)ret); - jsval jsret = jsProxy ? OBJECT_TO_JSVAL(jsProxy->obj) : JSVAL_VOID; + + JS::RootedObject jsobj(cx, js_get_or_create_jsobject(cx, ret)); + jsval jsret = OBJECT_TO_JSVAL(jsobj); args.rval().set(jsret); return true; @@ -98,9 +98,9 @@ bool js_cocos2dx_PhysicsSprite3D_create(JSContext *cx, uint32_t argc, jsval *vp) ok &= jsval_to_vector3(cx, args.get(2), &arg2); JSB_PRECONDITION2(ok, cx, false, "js_cocos2dx_physics3d_PhysicsSprite3D_create : Error processing arguments"); cocos2d::PhysicsSprite3D* ret = cocos2d::PhysicsSprite3D::create(arg0, &arg1, arg2); - - js_proxy_t *jsProxy = js_get_or_create_proxy(cx, (cocos2d::PhysicsSprite3D*)ret); - jsval jsret = jsProxy ? OBJECT_TO_JSVAL(jsProxy->obj) : JSVAL_VOID; + + JS::RootedObject jsobj(cx, js_get_or_create_jsobject(cx, ret)); + jsval jsret = OBJECT_TO_JSVAL(jsobj); args.rval().set(jsret); return true; @@ -117,9 +117,9 @@ bool js_cocos2dx_PhysicsSprite3D_create(JSContext *cx, uint32_t argc, jsval *vp) ok &= jsval_to_quaternion(cx, args.get(3), &arg3); JSB_PRECONDITION2(ok, cx, false, "js_cocos2dx_physics3d_PhysicsSprite3D_create : Error processing arguments"); cocos2d::PhysicsSprite3D* ret = cocos2d::PhysicsSprite3D::create(arg0, &arg1, arg2, arg3); - - js_proxy_t *jsProxy = js_get_or_create_proxy(cx, (cocos2d::PhysicsSprite3D*)ret); - jsval jsret = jsProxy ? OBJECT_TO_JSVAL(jsProxy->obj) : JSVAL_VOID; + + JS::RootedObject jsobj(cx, js_get_or_create_jsobject(cx, ret)); + jsval jsret = OBJECT_TO_JSVAL(jsobj); args.rval().set(jsret); return true; @@ -138,9 +138,9 @@ bool js_cocos2dx_physics3d_Physics3DRigidBody_create(JSContext *cx, uint32_t arg ok &= jsval_to_physics3DRigidBodyDes(cx, args.get(0), &arg0); JSB_PRECONDITION2(ok, cx, false, "js_cocos2dx_physics3d_Physics3DRigidBody_create : Error processing arguments"); cocos2d::Physics3DRigidBody* ret = cocos2d::Physics3DRigidBody::create(&arg0); - - js_proxy_t *jsProxy = js_get_or_create_proxy(cx, (cocos2d::Physics3DRigidBody*)ret); - jsval jsret = OBJECT_TO_JSVAL(jsProxy->obj); + + JS::RootedObject jsobj(cx, js_get_or_create_jsobject(cx, ret)); + jsval jsret = OBJECT_TO_JSVAL(jsobj); args.rval().set(jsret); return true; @@ -207,10 +207,10 @@ bool js_cocos2dx_physics3d_Physics3dShape_createMesh(JSContext *cx, uint32_t arg bool ok = jsval_to_int(cx, args.get(1), &arg1); JSB_PRECONDITION2(ok, cx, false, "js_cocos2dx_physics3d_Physics3dShape_createMesh : Error processing arguments"); - + Physics3DShape* ret = Physics3DShape::createMesh(&arg0[0], arg1); - js_proxy_t* proxy = js_get_or_create_proxy(cx, ret); - jsval jsret = OBJECT_TO_JSVAL(proxy->obj); + JS::RootedObject jsobj(cx, js_get_or_create_jsobject(cx, ret)); + jsval jsret = OBJECT_TO_JSVAL(jsobj); args.rval().set(jsret); return true; @@ -240,13 +240,13 @@ jsval physics3d_collisionPoint_to_jsval(JSContext*cx, const Physics3DCollisionIn jsval physics3d_collisioninfo_to_jsval(JSContext* cx, const Physics3DCollisionInfo& ci) { JS::RootedObject tmp(cx, JS_NewObject(cx, NULL, JS::NullPtr(), JS::NullPtr())); - - js_proxy_t* proxy = js_get_or_create_proxy(cx, ci.objA); - JS::RootedValue prop(cx, OBJECT_TO_JSVAL(proxy->obj)); + + JS::RootedObject jsobj(cx, js_get_or_create_jsobject(cx, ci.objA)); + JS::RootedValue prop(cx, OBJECT_TO_JSVAL(jsobj)); JS_DefineProperty(cx, tmp, "objA", prop, JSPROP_ENUMERATE | JSPROP_PERMANENT); - proxy = js_get_or_create_proxy(cx, ci.objB); - prop.set(OBJECT_TO_JSVAL(proxy->obj)); + jsobj.set(js_get_or_create_jsobject(cx, ci.objB)); + prop.set(OBJECT_TO_JSVAL(jsobj)); JS_DefineProperty(cx, tmp, "objB", prop, JSPROP_ENUMERATE | JSPROP_PERMANENT); JS::RootedObject jsarr(cx, JS_NewArrayObject(cx, ci.collisionPointList.size())); @@ -377,9 +377,9 @@ bool js_cocos2dx_physics3d_Physics3dShape_createHeightfield(JSContext *cx, uint3 ret = cocos2d::Physics3DShape::createHeightfield(arg0, arg1, &arg2[0], arg3, arg4, arg5, arg6, arg7); else if(argc == 9) ret = cocos2d::Physics3DShape::createHeightfield(arg0, arg1, &arg2[0], arg3, arg4, arg5, arg6, arg7, arg8); - - js_proxy_t *jsProxy = js_get_or_create_proxy(cx, ret); - jsval jsret = OBJECT_TO_JSVAL(jsProxy->obj); + + JS::RootedObject jsobj(cx, js_get_or_create_jsobject(cx, ret)); + jsval jsret = OBJECT_TO_JSVAL(jsobj); args.rval().set(jsret); return true; @@ -425,8 +425,8 @@ jsval Physics3DWorld_HitResult_to_jsval(JSContext *cx, const cocos2d::Physics3DW if (v.hitObj) { - js_proxy_t *jsProxy = js_get_or_create_proxy(cx, (cocos2d::Physics3DObject*)v.hitObj); - hitobject.set(OBJECT_TO_JSVAL(jsProxy->obj)); + JS::RootedObject jsobj(cx, js_get_or_create_jsobject(cx, v.hitObj)); + hitobject.set(OBJECT_TO_JSVAL(jsobj)); } bool ok = JS_DefineProperty(cx, tmp, "hitPosition", hitPosition, JSPROP_ENUMERATE | JSPROP_PERMANENT) && diff --git a/cocos/scripting/js-bindings/manual/platform/ios/JavaScriptObjCBridge.mm b/cocos/scripting/js-bindings/manual/platform/ios/JavaScriptObjCBridge.mm index 9834c20c31..f3e0536cea 100644 --- a/cocos/scripting/js-bindings/manual/platform/ios/JavaScriptObjCBridge.mm +++ b/cocos/scripting/js-bindings/manual/platform/ios/JavaScriptObjCBridge.mm @@ -261,6 +261,16 @@ JS_BINDED_CONSTRUCTOR_IMPL(JavaScriptObjCBridge) static void basic_object_finalize(JSFreeOp *freeOp, JSObject *obj) { CCLOG("basic_object_finalize %p ...", obj); + + js_proxy_t* nproxy; + js_proxy_t* jsproxy; + JSContext *cx = ScriptingCore::getInstance()->getGlobalContext(); + JS::RootedObject jsobj(cx, obj); + jsproxy = jsb_get_js_proxy(jsobj); + if (jsproxy) { + nproxy = jsb_get_native_proxy(jsproxy->ptr); + jsb_remove_proxy(nproxy, jsproxy); + } } JS_BINDED_FUNC_IMPL(JavaScriptObjCBridge, callStaticMethod){ diff --git a/cocos/scripting/js-bindings/manual/spine/jsb_cocos2dx_spine_manual.cpp b/cocos/scripting/js-bindings/manual/spine/jsb_cocos2dx_spine_manual.cpp index bee3f344a3..7523364a35 100644 --- a/cocos/scripting/js-bindings/manual/spine/jsb_cocos2dx_spine_manual.cpp +++ b/cocos/scripting/js-bindings/manual/spine/jsb_cocos2dx_spine_manual.cpp @@ -582,11 +582,12 @@ public: JSContext *cx = ScriptingCore::getInstance()->getGlobalContext(); JS::RootedObject thisObj(cx, getJSCallbackThis().toObjectOrNull()); JS::RootedValue callback(cx, getJSCallbackFunc()); - js_proxy_t *proxy = js_get_or_create_proxy(cx, node); + + JS::RootedObject jsnode(cx, js_get_or_create_jsobject(cx, node)); JS::RootedValue retval(cx); if (!callback.isNullOrUndefined()) { - jsval nodeVal = OBJECT_TO_JSVAL(proxy->obj); + jsval nodeVal = OBJECT_TO_JSVAL(jsnode); jsval trackIndexVal = INT_TO_JSVAL(trackIndex); int tmpType = (int)type; jsval typeVal = INT_TO_JSVAL(tmpType); diff --git a/tests/js-tests/project/Classes/js_DrawNode3D_bindings.cpp b/tests/js-tests/project/Classes/js_DrawNode3D_bindings.cpp index e3d0dc14fb..4046f9abb0 100644 --- a/tests/js-tests/project/Classes/js_DrawNode3D_bindings.cpp +++ b/tests/js-tests/project/Classes/js_DrawNode3D_bindings.cpp @@ -517,7 +517,6 @@ 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 = jsb_ref_finalize; jsb_cocos2d_DrawNode3D_class->flags = JSCLASS_HAS_RESERVED_SLOTS(2); static JSPropertySpec properties[] = { diff --git a/tests/js-tests/project/Classes/js_Effect3D_bindings.cpp b/tests/js-tests/project/Classes/js_Effect3D_bindings.cpp index eb242f1ad1..3934d20f19 100644 --- a/tests/js-tests/project/Classes/js_Effect3D_bindings.cpp +++ b/tests/js-tests/project/Classes/js_Effect3D_bindings.cpp @@ -449,8 +449,8 @@ bool js_cocos2dx_Effect3DOutline_create(JSContext *cx, uint32_t argc, jsval *vp) jsval jsret = JSVAL_NULL; do { if (ret) { - js_proxy_t *jsProxy = js_get_or_create_proxy(cx, (Effect3DOutline*)ret); - jsret = OBJECT_TO_JSVAL(jsProxy->obj); + JS::RootedObject jsobj(cx, js_get_or_create_jsobject(cx, ret)); + jsret = OBJECT_TO_JSVAL(jsobj); } else { jsret = JSVAL_NULL; } @@ -465,33 +465,19 @@ bool js_cocos2dx_Effect3DOutline_create(JSContext *cx, uint32_t argc, jsval *vp) JSObject *jsb_Effect3D_prototype; -void js_Effect3DOutline_finalize(JSFreeOp *fop, JSObject *obj) { - CCLOGINFO("jsbindings: finalizing JS object %p (Effect3DOutline)", obj); -} - bool jsb_Effect3DOutline_constructor(JSContext *cx, uint32_t argc, jsval *vp) { JS::CallArgs args = JS::CallArgsFromVp(argc, vp); bool ok = true; Effect3DOutline* cobj = new (std::nothrow) Effect3DOutline(); cobj->init(); - cobj->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 parent(cx, typeClass->parentProto.ref()); - JS::RootedObject obj(cx, JS_NewObject(cx, typeClass->jsclass, proto, parent)); - args.rval().set(OBJECT_TO_JSVAL(obj)); - // link the native object with the javascript object - js_proxy_t* p = jsb_new_proxy(cobj, obj); - AddNamedObjectRoot(cx, &p->obj, "cocos2d::Effect3DOutline"); - if (JS_HasProperty(cx, obj, "_ctor", &ok) && ok) - ScriptingCore::getInstance()->executeFunctionWithOwner(OBJECT_TO_JSVAL(obj), "_ctor", args); + + js_type_class_t *typeClass = js_get_type_from_native(cobj); + JS::RootedObject jsobj(cx, jsb_ref_create_jsobject(cx, cobj, typeClass, "Effect3DOutline")); + 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; } @@ -505,7 +491,6 @@ void js_register_cocos2dx_Effect3DOutline(JSContext *cx, JS::HandleObject global jsb_Effect3DOutline_class->enumerate = JS_EnumerateStub; jsb_Effect3DOutline_class->resolve = JS_ResolveStub; jsb_Effect3DOutline_class->convert = JS_ConvertStub; - jsb_Effect3DOutline_class->finalize = js_Effect3DOutline_finalize; jsb_Effect3DOutline_class->flags = JSCLASS_HAS_RESERVED_SLOTS(2); static JSPropertySpec properties[] = { @@ -614,8 +599,8 @@ bool js_cocos2dx_EffectSprite3D_createFromObjFileAndTexture(JSContext *cx, uint3 jsval jsret = JSVAL_NULL; do { if (ret) { - js_proxy_t *jsProxy = js_get_or_create_proxy(cx, (EffectSprite3D*)ret); - jsret = OBJECT_TO_JSVAL(jsProxy->obj); + JS::RootedObject jsobj(cx, js_get_or_create_jsobject(cx, ret)); + jsret = OBJECT_TO_JSVAL(jsobj); } else { jsret = JSVAL_NULL; } @@ -639,8 +624,8 @@ bool js_cocos2dx_EffectSprite3D_create(JSContext *cx, uint32_t argc, jsval *vp) jsval jsret = JSVAL_NULL; do { if (ret) { - js_proxy_t *jsProxy = js_get_or_create_proxy(cx, (EffectSprite3D*)ret); - jsret = OBJECT_TO_JSVAL(jsProxy->obj); + JS::RootedObject jsobj(cx, js_get_or_create_jsobject(cx, ret)); + jsret = OBJECT_TO_JSVAL(jsobj); } else { jsret = JSVAL_NULL; } @@ -655,10 +640,6 @@ bool js_cocos2dx_EffectSprite3D_create(JSContext *cx, uint32_t argc, jsval *vp) extern JSObject *jsb_cocos2d_Sprite3D_prototype; -void js_EffectSprite3D_finalize(JSFreeOp *fop, JSObject *obj) { - CCLOGINFO("jsbindings: finalizing JS object %p (EffectSprite3D)", obj); -} - bool jsb_EffectSprite3D_constructor(JSContext *cx, uint32_t argc, jsval *vp) { JS::CallArgs args = JS::CallArgsFromVp(argc, vp); @@ -676,23 +657,13 @@ bool jsb_EffectSprite3D_constructor(JSContext *cx, uint32_t argc, jsval *vp) cobj->setTexture(texture); } } - cobj->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 parent(cx, typeClass->parentProto.ref()); - JS::RootedObject obj(cx, JS_NewObject(cx, typeClass->jsclass, proto, parent)); - args.rval().set(OBJECT_TO_JSVAL(obj)); - // link the native object with the javascript object - js_proxy_t* p = jsb_new_proxy(cobj, obj); - AddNamedObjectRoot(cx, &p->obj, "cocos2d::EffectSprite3D"); - if (JS_HasProperty(cx, obj, "_ctor", &ok) && ok) - ScriptingCore::getInstance()->executeFunctionWithOwner(OBJECT_TO_JSVAL(obj), "_ctor", args); + + js_type_class_t *typeClass = js_get_type_from_native(cobj); + JS::RootedObject jsobj(cx, jsb_ref_create_jsobject(cx, cobj, typeClass, "EffectSprite3D")); + 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; } @@ -706,7 +677,6 @@ void js_register_cocos2dx_EffectSprite3D(JSContext *cx, JS::HandleObject global) jsb_EffectSprite3D_class->enumerate = JS_EnumerateStub; jsb_EffectSprite3D_class->resolve = JS_ResolveStub; jsb_EffectSprite3D_class->convert = JS_ConvertStub; - jsb_EffectSprite3D_class->finalize = js_EffectSprite3D_finalize; jsb_EffectSprite3D_class->flags = JSCLASS_HAS_RESERVED_SLOTS(2); static JSPropertySpec properties[] = {