Improve TrackEntry issue solution with internal unordered_map

This commit is contained in:
pandamicro 2016-12-26 00:08:18 +08:00
parent 0496857283
commit 7c2ea03b00
1 changed files with 86 additions and 35 deletions

View File

@ -28,6 +28,8 @@
using namespace spine; using namespace spine;
std::unordered_map<spTrackEntry*, JSObject*> _spTrackEntryMap;
jsval speventdata_to_jsval(JSContext* cx, spEventData& v) jsval speventdata_to_jsval(JSContext* cx, spEventData& v)
{ {
JS::RootedObject tmp(cx, JS_NewObject(cx, nullptr, JS::NullPtr(), JS::NullPtr())); 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; 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); js_proxy_t *proxy = jsb_get_js_proxy(jsthis);
spTrackEntry* cobj = (spTrackEntry *)(proxy ? proxy->ptr : NULL); spTrackEntry* cobj = (spTrackEntry *)(proxy ? proxy->ptr : NULL);
if (cobj) { 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); jsret = sptrackentry_to_jsval(cx, *cobj->next);
} }
vp.set(jsret); args.rval().set(jsret);
return true; return true;
} }
else { 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); js_proxy_t *proxy = jsb_get_js_proxy(jsthis);
spTrackEntry* cobj = (spTrackEntry *)(proxy ? proxy->ptr : NULL); spTrackEntry* cobj = (spTrackEntry *)(proxy ? proxy->ptr : NULL);
if (cobj) { 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); jsret = sptrackentry_to_jsval(cx, *cobj->previous);
} }
vp.set(jsret); args.rval().set(jsret);
return true; return true;
} }
else { 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<spTrackEntry*, JSObject*>::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) jsval sptrackentry_to_jsval(JSContext* cx, spTrackEntry& v)
{ {
js_proxy_t *proxy = jsb_get_native_proxy(&v); JS::RootedObject entry(cx);
if (proxy) std::unordered_map<spTrackEntry*, JSObject*>::iterator existed = _spTrackEntryMap.find(&v);
bool found = existed != _spTrackEntryMap.end();
if (found)
{ {
JS::RootedObject entry(cx, proxy->obj); entry.set(existed->second);
return OBJECT_TO_JSVAL(entry);
} }
else else
{ {
JS::RootedObject tmp(cx, JS_NewObject(cx, nullptr, JS::NullPtr(), JS::NullPtr())); JS::RootedObject proto(cx, jsb_spine_TrackEntry_prototype);
if (!tmp) return JSVAL_NULL; entry.set(JS_NewObject(cx, jsb_spine_TrackEntry_class, proto, JS::NullPtr()));
}
jsb_new_proxy(&v, tmp); JS::RootedValue entryVal(cx, OBJECT_TO_JSVAL(entry));
js_add_FinalizeHook(cx, tmp, false); if (entryVal.isObject())
{
#if COCOS2D_DEBUG > 1 JS::RootedValue val(cx, DOUBLE_TO_JSVAL(v.delay));
CCLOG("++++++WEAK_REF++++++ Cpp(spine::TrackEntry): %p - JS: %p", &v, tmp.get()); bool ok = JS_SetProperty(cx, entry, "delay", val);
#endif // COCOS2D_DEBUG val.set(DOUBLE_TO_JSVAL(v.time));
ok &= JS_SetProperty(cx, entry, "time", val);
JS::RootedValue jsanimation(cx, spanimation_to_jsval(cx, *v.animation)); val.set(DOUBLE_TO_JSVAL(v.lastTime));
bool ok = JS_DefineProperty(cx, tmp, "delay", v.delay, JSPROP_ENUMERATE | JSPROP_PERMANENT) && ok &= JS_SetProperty(cx, entry, "lastTime", val);
JS_DefineProperty(cx, tmp, "time", v.time, JSPROP_ENUMERATE | JSPROP_PERMANENT) && val.set(DOUBLE_TO_JSVAL(v.endTime));
JS_DefineProperty(cx, tmp, "lastTime", v.lastTime, JSPROP_ENUMERATE | JSPROP_PERMANENT) && ok &= JS_SetProperty(cx, entry, "endTime", val);
JS_DefineProperty(cx, tmp, "endTime", v.endTime, JSPROP_ENUMERATE | JSPROP_PERMANENT) && val.set(DOUBLE_TO_JSVAL(v.timeScale));
JS_DefineProperty(cx, tmp, "timeScale", v.timeScale, JSPROP_ENUMERATE | JSPROP_PERMANENT) && ok &= JS_SetProperty(cx, entry, "timeScale", val);
JS_DefineProperty(cx, tmp, "mixTime", v.mixTime, JSPROP_ENUMERATE | JSPROP_PERMANENT) && val.set(DOUBLE_TO_JSVAL(v.mixTime));
JS_DefineProperty(cx, tmp, "mixDuration", v.mixDuration, JSPROP_ENUMERATE | JSPROP_PERMANENT) && ok &= JS_SetProperty(cx, entry, "mixTime", val);
JS_DefineProperty(cx, tmp, "animation", jsanimation, JSPROP_ENUMERATE | JSPROP_PERMANENT) && val.set(DOUBLE_TO_JSVAL(v.mixDuration));
JS_DefineProperty(cx, tmp, "next", JS::UndefinedHandleValue, JSPROP_ENUMERATE | JSPROP_PERMANENT, jsb_spine_TrackEntry_get_next) && ok &= JS_SetProperty(cx, entry, "mixDuration", val);
JS_DefineProperty(cx, tmp, "previous", JS::UndefinedHandleValue, JSPROP_ENUMERATE | JSPROP_PERMANENT, jsb_spine_TrackEntry_get_previous); val.set(spanimation_to_jsval(cx, *v.animation));
ok &= JS_SetProperty(cx, entry, "animation", val);
if (ok) 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) 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) 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::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, "findBone", jsb_cocos2dx_spine_findBone, 1, JSPROP_ENUMERATE | JSPROP_PERMANENT);
JS_DefineFunction(cx, skeletonRenderer, "findSlot", jsb_cocos2dx_spine_findSlot, 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, "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, "setAnimation", jsb_cocos2dx_spine_setAnimation, 3, JSPROP_ENUMERATE | JSPROP_PERMANENT);
JS_DefineFunction(cx, skeletonAnimation, "addAnimation", jsb_cocos2dx_spine_addAnimation, 4, JSPROP_ENUMERATE | JSPROP_PERMANENT); JS_DefineFunction(cx, skeletonAnimation, "addAnimation", jsb_cocos2dx_spine_addAnimation, 4, JSPROP_ENUMERATE | JSPROP_PERMANENT);
} }