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 efbffa2758..c2c2636731 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 @@ -28,6 +28,8 @@ using namespace spine; +std::unordered_map _spTrackEntryMap; + jsval speventdata_to_jsval(JSContext* cx, spEventData& v) { JS::RootedObject tmp(cx, JS_NewObject(cx, nullptr, JS::NullPtr(), JS::NullPtr())); @@ -277,9 +279,13 @@ jsval spanimation_to_jsval(JSContext* cx, spAnimation& v) return JSVAL_NULL; } -bool jsb_spine_TrackEntry_get_next(JSContext *cx, JS::HandleObject obj, JS::HandleId id, JS::MutableHandleValue vp) +JSClass *jsb_spine_TrackEntry_class; +JSObject *jsb_spine_TrackEntry_prototype; + +bool jsb_spine_TrackEntry_get_next(JSContext *cx, uint32_t argc, jsval *vp) { - JS::RootedObject jsthis(cx, obj); + JS::CallArgs args = JS::CallArgsFromVp(argc, vp); + JS::RootedObject jsthis(cx, args.thisv().toObjectOrNull()); js_proxy_t *proxy = jsb_get_js_proxy(jsthis); spTrackEntry* cobj = (spTrackEntry *)(proxy ? proxy->ptr : NULL); if (cobj) { @@ -288,7 +294,7 @@ bool jsb_spine_TrackEntry_get_next(JSContext *cx, JS::HandleObject obj, JS::Hand { jsret = sptrackentry_to_jsval(cx, *cobj->next); } - vp.set(jsret); + args.rval().set(jsret); return true; } else { @@ -297,9 +303,10 @@ bool jsb_spine_TrackEntry_get_next(JSContext *cx, JS::HandleObject obj, JS::Hand } } -bool jsb_spine_TrackEntry_get_previous(JSContext *cx, JS::HandleObject obj, JS::HandleId id, JS::MutableHandleValue vp) +bool jsb_spine_TrackEntry_get_previous(JSContext *cx, uint32_t argc, jsval *vp) { - JS::RootedObject jsthis(cx, obj); + JS::CallArgs args = JS::CallArgsFromVp(argc, vp); + JS::RootedObject jsthis(cx, args.thisv().toObjectOrNull()); js_proxy_t *proxy = jsb_get_js_proxy(jsthis); spTrackEntry* cobj = (spTrackEntry *)(proxy ? proxy->ptr : NULL); if (cobj) { @@ -308,7 +315,7 @@ bool jsb_spine_TrackEntry_get_previous(JSContext *cx, JS::HandleObject obj, JS:: { jsret = sptrackentry_to_jsval(cx, *cobj->previous); } - vp.set(jsret); + args.rval().set(jsret); return true; } else { @@ -317,45 +324,88 @@ bool jsb_spine_TrackEntry_get_previous(JSContext *cx, JS::HandleObject obj, JS:: } } +void js_spine_TrackEntry_finalize(JSFreeOp *fop, JSObject *obj) { + std::unordered_map::iterator existed = _spTrackEntryMap.begin(); + while (existed != _spTrackEntryMap.end()) { + if (existed->second == obj) + { + _spTrackEntryMap.erase(existed); + break; + } + ++existed; + } +} + +void js_register_spine_TrackEntry(JSContext *cx, JS::HandleObject global) +{ + jsb_spine_TrackEntry_class = (JSClass *)calloc(1, sizeof(JSClass)); + jsb_spine_TrackEntry_class->name = "TrackEntry"; + jsb_spine_TrackEntry_class->addProperty = JS_PropertyStub; + jsb_spine_TrackEntry_class->delProperty = JS_DeletePropertyStub; + jsb_spine_TrackEntry_class->getProperty = JS_PropertyStub; + jsb_spine_TrackEntry_class->setProperty = JS_StrictPropertyStub; + jsb_spine_TrackEntry_class->enumerate = JS_EnumerateStub; + jsb_spine_TrackEntry_class->resolve = JS_ResolveStub; + jsb_spine_TrackEntry_class->convert = JS_ConvertStub; + jsb_spine_TrackEntry_class->finalize = js_spine_TrackEntry_finalize; + jsb_spine_TrackEntry_class->flags = JSCLASS_HAS_RESERVED_SLOTS(2); + + static JSPropertySpec properties[] = + { + JS_PSG("previous", jsb_spine_TrackEntry_get_previous, JSPROP_PERMANENT | JSPROP_ENUMERATE), + JS_PSG("next", jsb_spine_TrackEntry_get_next, JSPROP_PERMANENT | JSPROP_ENUMERATE), + JS_PS_END + }; + + jsb_spine_TrackEntry_prototype = JS_InitClass(cx, global, JS::NullPtr(), jsb_spine_TrackEntry_class, nullptr, 0, properties, nullptr, nullptr, nullptr); +} + jsval sptrackentry_to_jsval(JSContext* cx, spTrackEntry& v) { - js_proxy_t *proxy = jsb_get_native_proxy(&v); - if (proxy) + JS::RootedObject entry(cx); + std::unordered_map::iterator existed = _spTrackEntryMap.find(&v); + bool found = existed != _spTrackEntryMap.end(); + if (found) { - JS::RootedObject entry(cx, proxy->obj); - return OBJECT_TO_JSVAL(entry); + entry.set(existed->second); } else { - JS::RootedObject tmp(cx, JS_NewObject(cx, nullptr, JS::NullPtr(), JS::NullPtr())); - if (!tmp) return JSVAL_NULL; - - jsb_new_proxy(&v, tmp); - js_add_FinalizeHook(cx, tmp, false); - -#if COCOS2D_DEBUG > 1 - CCLOG("++++++WEAK_REF++++++ Cpp(spine::TrackEntry): %p - JS: %p", &v, tmp.get()); -#endif // COCOS2D_DEBUG - - JS::RootedValue jsanimation(cx, spanimation_to_jsval(cx, *v.animation)); - bool ok = JS_DefineProperty(cx, tmp, "delay", v.delay, JSPROP_ENUMERATE | JSPROP_PERMANENT) && - JS_DefineProperty(cx, tmp, "time", v.time, JSPROP_ENUMERATE | JSPROP_PERMANENT) && - JS_DefineProperty(cx, tmp, "lastTime", v.lastTime, JSPROP_ENUMERATE | JSPROP_PERMANENT) && - JS_DefineProperty(cx, tmp, "endTime", v.endTime, JSPROP_ENUMERATE | JSPROP_PERMANENT) && - JS_DefineProperty(cx, tmp, "timeScale", v.timeScale, JSPROP_ENUMERATE | JSPROP_PERMANENT) && - JS_DefineProperty(cx, tmp, "mixTime", v.mixTime, JSPROP_ENUMERATE | JSPROP_PERMANENT) && - JS_DefineProperty(cx, tmp, "mixDuration", v.mixDuration, JSPROP_ENUMERATE | JSPROP_PERMANENT) && - JS_DefineProperty(cx, tmp, "animation", jsanimation, JSPROP_ENUMERATE | JSPROP_PERMANENT) && - JS_DefineProperty(cx, tmp, "next", JS::UndefinedHandleValue, JSPROP_ENUMERATE | JSPROP_PERMANENT, jsb_spine_TrackEntry_get_next) && - JS_DefineProperty(cx, tmp, "previous", JS::UndefinedHandleValue, JSPROP_ENUMERATE | JSPROP_PERMANENT, jsb_spine_TrackEntry_get_previous); + JS::RootedObject proto(cx, jsb_spine_TrackEntry_prototype); + entry.set(JS_NewObject(cx, jsb_spine_TrackEntry_class, proto, JS::NullPtr())); + } + + JS::RootedValue entryVal(cx, OBJECT_TO_JSVAL(entry)); + if (entryVal.isObject()) + { + JS::RootedValue val(cx, DOUBLE_TO_JSVAL(v.delay)); + bool ok = JS_SetProperty(cx, entry, "delay", val); + val.set(DOUBLE_TO_JSVAL(v.time)); + ok &= JS_SetProperty(cx, entry, "time", val); + val.set(DOUBLE_TO_JSVAL(v.lastTime)); + ok &= JS_SetProperty(cx, entry, "lastTime", val); + val.set(DOUBLE_TO_JSVAL(v.endTime)); + ok &= JS_SetProperty(cx, entry, "endTime", val); + val.set(DOUBLE_TO_JSVAL(v.timeScale)); + ok &= JS_SetProperty(cx, entry, "timeScale", val); + val.set(DOUBLE_TO_JSVAL(v.mixTime)); + ok &= JS_SetProperty(cx, entry, "mixTime", val); + val.set(DOUBLE_TO_JSVAL(v.mixDuration)); + ok &= JS_SetProperty(cx, entry, "mixDuration", val); + val.set(spanimation_to_jsval(cx, *v.animation)); + ok &= JS_SetProperty(cx, entry, "animation", val); if (ok) { - return OBJECT_TO_JSVAL(tmp); + if (!found) + { + _spTrackEntryMap.emplace(&v, entry); + } + return entryVal; } - - return JSVAL_NULL; } + + return JSVAL_NULL; } bool jsb_cocos2dx_spine_findBone(JSContext *cx, uint32_t argc, jsval *vp) @@ -631,6 +681,8 @@ extern JSObject* jsb_spine_SkeletonAnimation_prototype; void register_all_cocos2dx_spine_manual(JSContext* cx, JS::HandleObject global) { + js_register_spine_TrackEntry(cx, global); + JS::RootedObject skeletonRenderer(cx, jsb_spine_SkeletonRenderer_prototype); JS_DefineFunction(cx, skeletonRenderer, "findBone", jsb_cocos2dx_spine_findBone, 1, JSPROP_ENUMERATE | JSPROP_PERMANENT); JS_DefineFunction(cx, skeletonRenderer, "findSlot", jsb_cocos2dx_spine_findSlot, 1, JSPROP_ENUMERATE | JSPROP_PERMANENT); @@ -642,5 +694,4 @@ void register_all_cocos2dx_spine_manual(JSContext* cx, JS::HandleObject global) JS_DefineFunction(cx, skeletonAnimation, "getCurrent", jsb_cocos2dx_spine_getCurrent, 1, JSPROP_ENUMERATE | JSPROP_PERMANENT); JS_DefineFunction(cx, skeletonAnimation, "setAnimation", jsb_cocos2dx_spine_setAnimation, 3, JSPROP_ENUMERATE | JSPROP_PERMANENT); JS_DefineFunction(cx, skeletonAnimation, "addAnimation", jsb_cocos2dx_spine_addAnimation, 4, JSPROP_ENUMERATE | JSPROP_PERMANENT); - }