From 3d6b1367cd18a0f50c3ccfb45227ceef93f6db7c Mon Sep 17 00:00:00 2001 From: pandamicro Date: Tue, 13 Dec 2016 14:01:13 +0800 Subject: [PATCH] Manually bind EventDispatcher::addCustomEventListener to avoid memory issue --- .../js-bindings/manual/cocos2d_specifics.cpp | 3 + .../manual/jsb_event_dispatcher_manual.cpp | 58 +++++++++++++++++++ .../manual/jsb_event_dispatcher_manual.h | 1 + tools/tojs/cocos2dx.ini | 4 +- 4 files changed, 64 insertions(+), 2 deletions(-) diff --git a/cocos/scripting/js-bindings/manual/cocos2d_specifics.cpp b/cocos/scripting/js-bindings/manual/cocos2d_specifics.cpp index 64f5611b2b..426beb2a1b 100644 --- a/cocos/scripting/js-bindings/manual/cocos2d_specifics.cpp +++ b/cocos/scripting/js-bindings/manual/cocos2d_specifics.cpp @@ -6089,6 +6089,9 @@ void register_cocos2dx_js_core(JSContext* cx, JS::HandleObject global) JS_DefineFunction(cx, tmpObj, "getDataFromFile", js_cocos2dx_CCFileUtils_getDataFromFile, 1, JSPROP_ENUMERATE | JSPROP_PERMANENT); JS_DefineFunction(cx, tmpObj, "writeDataToFile", js_cocos2dx_CCFileUtils_writeDataToFile, 2, JSPROP_ENUMERATE | JSPROP_PERMANENT); + tmpObj.set(jsb_cocos2d_EventDispatcher_prototype); + JS_DefineFunction(cx, tmpObj, "addCustomListener", js_EventDispatcher_addCustomEventListener, 2, JSPROP_PERMANENT | JSPROP_ENUMERATE); + JS_GetProperty(cx, ccObj, "EventListenerTouchOneByOne", &tmpVal); tmpObj = tmpVal.toObjectOrNull(); JS_DefineFunction(cx, tmpObj, "create", js_EventListenerTouchOneByOne_create, 0, JSPROP_READONLY | JSPROP_PERMANENT); diff --git a/cocos/scripting/js-bindings/manual/jsb_event_dispatcher_manual.cpp b/cocos/scripting/js-bindings/manual/jsb_event_dispatcher_manual.cpp index 807e74546c..ffa57e537e 100644 --- a/cocos/scripting/js-bindings/manual/jsb_event_dispatcher_manual.cpp +++ b/cocos/scripting/js-bindings/manual/jsb_event_dispatcher_manual.cpp @@ -22,6 +22,7 @@ #include "scripting/js-bindings/manual/jsb_event_dispatcher_manual.h" +#include "base/CCEventDispatcher.h" #include "base/CCEventListenerFocus.h" #include "base/CCEventListenerKeyboard.h" #include "base/CCEventListenerMouse.h" @@ -176,3 +177,60 @@ bool js_EventListenerFocus_create(JSContext *cx, uint32_t argc, jsval *vp) JS_ReportError(cx, "wrong number of arguments: %d, was expecting %d", argc, 0); return false; } + +bool js_EventDispatcher_addCustomEventListener(JSContext *cx, uint32_t argc, jsval *vp) +{ + JS::CallArgs args = JS::CallArgsFromVp(argc, vp); + bool ok = true; + JS::RootedObject obj(cx, args.thisv().toObjectOrNull()); + js_proxy_t *proxy = jsb_get_js_proxy(obj); + cocos2d::EventDispatcher* cobj = (cocos2d::EventDispatcher *)(proxy ? proxy->ptr : NULL); + JSB_PRECONDITION2( cobj, cx, false, "js_cocos2dx_EventDispatcher_addCustomEventListener : Invalid Native Object"); + if (argc == 2) { + std::string arg0; + std::function arg1; + ok &= jsval_to_std_string(cx, args.get(0), &arg0); + 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), args.thisv())); + auto lambda = [=](cocos2d::EventCustom* event) -> void { + JSB_AUTOCOMPARTMENT_WITH_GLOBAL_OBJCET + jsval largv[1]; + if (event) { + js_type_class_t *typeClassEvent = js_get_type_from_native(event); + largv[0] = OBJECT_TO_JSVAL(jsb_get_or_create_weak_jsobject(cx, event, typeClassEvent, "cocos2d::EventCustom")); + } else { + largv[0] = JSVAL_NULL; + }; + JS::RootedValue rval(cx); + bool succeed = func->invoke(1, &largv[0], &rval); + if (!succeed && JS_IsExceptionPending(cx)) { + JS_ReportPendingException(cx); + } + removeJSObject(cx, event); + }; + arg1 = lambda; + } + else + { + arg1 = nullptr; + } + } while(0); + JSB_PRECONDITION2(ok, cx, false, "js_cocos2dx_EventDispatcher_addCustomEventListener : Error processing arguments"); + cocos2d::EventListenerCustom* ret = cobj->addCustomEventListener(arg0, arg1); + JS::RootedValue jsret(cx); + if (ret) { + jsret = OBJECT_TO_JSVAL(js_get_or_create_jsobject(cx, ret)); + args.rval().set(jsret); + } else { + jsret = JSVAL_NULL; + }; + args.rval().set(jsret); + return true; + } + + JS_ReportError(cx, "js_cocos2dx_EventDispatcher_addCustomEventListener : wrong number of arguments: %d, was expecting %d", argc, 2); + return false; +} \ No newline at end of file diff --git a/cocos/scripting/js-bindings/manual/jsb_event_dispatcher_manual.h b/cocos/scripting/js-bindings/manual/jsb_event_dispatcher_manual.h index dd222e34e3..6b87f583a5 100644 --- a/cocos/scripting/js-bindings/manual/jsb_event_dispatcher_manual.h +++ b/cocos/scripting/js-bindings/manual/jsb_event_dispatcher_manual.h @@ -31,5 +31,6 @@ bool js_EventListenerTouchAllAtOnce_create(JSContext *cx, uint32_t argc, jsval * bool js_EventListenerKeyboard_create(JSContext *cx, uint32_t argc, jsval *vp); bool js_EventListenerMouse_create(JSContext *cx, uint32_t argc, jsval *vp); bool js_EventListenerFocus_create(JSContext *cx, uint32_t argc, jsval *vp); +bool js_EventDispatcher_addCustomEventListener(JSContext *cx, uint32_t argc, jsval *vp); #endif /* defined(__cocos2d_js_bindings__jsb_event_dispatcher__) */ diff --git a/tools/tojs/cocos2dx.ini b/tools/tojs/cocos2dx.ini index c1badabfc9..73e8a486bb 100644 --- a/tools/tojs/cocos2dx.ini +++ b/tools/tojs/cocos2dx.ini @@ -118,7 +118,7 @@ skip = Node::[^setPosition$ setGLServerState description getUserObject .*UserDat EventTouch::[(s|g)etTouches], EventKeyboard::[*], Device::[getTextureDataForText], - EventDispatcher::[dispatchCustomEvent], + EventDispatcher::[dispatchCustomEvent addCustomEventListener], EventCustom::[getUserData setUserData], Component::[serialize onAdd onRemove update], EventListenerCustom::[init], @@ -155,7 +155,7 @@ rename_functions = SpriteFrameCache::[addSpriteFramesWithFile=addSpriteFrames ge DrawNode::[drawQuadraticBezier=drawQuadBezier], FileUtils::[loadFilenameLookupDictionaryFromFile=loadFilenameLookup], SimpleAudioEngine::[preloadBackgroundMusic=preloadMusic setBackgroundMusicVolume=setMusicVolume getBackgroundMusicVolume=getMusicVolume playBackgroundMusic=playMusic stopBackgroundMusic=stopMusic pauseBackgroundMusic=pauseMusic resumeBackgroundMusic=resumeMusic rewindBackgroundMusic=rewindMusic isBackgroundMusicPlaying=isMusicPlaying willPlayBackgroundMusic=willPlayMusic], - EventDispatcher::[addCustomEventListener=addCustomListener removeEventListener=removeListener removeEventListenersForType=removeListeners removeEventListenersForTarget=removeListeners removeCustomEventListeners=removeCustomListeners removeAllEventListeners=removeAllListeners pauseEventListenersForTarget=pauseTarget resumeEventListenersForTarget=resumeTarget], + EventDispatcher::[removeEventListener=removeListener removeEventListenersForType=removeListeners removeEventListenersForTarget=removeListeners removeCustomEventListeners=removeCustomListeners removeAllEventListeners=removeAllListeners pauseEventListenersForTarget=pauseTarget resumeEventListenersForTarget=resumeTarget], EventMouse::[getMouseButton=getButton setMouseButton=setButton setCursorPosition=setLocation getCursorX=getLocationX getCursorY=getLocationY], Configuration::[getInfo=dumpInfo], ComponentContainer::[get=getComponent],