Manually bind EventDispatcher::addCustomEventListener to avoid memory issue

This commit is contained in:
pandamicro 2016-12-13 14:01:13 +08:00
parent e469f4f710
commit 3d6b1367cd
4 changed files with 64 additions and 2 deletions

View File

@ -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, "getDataFromFile", js_cocos2dx_CCFileUtils_getDataFromFile, 1, JSPROP_ENUMERATE | JSPROP_PERMANENT);
JS_DefineFunction(cx, tmpObj, "writeDataToFile", js_cocos2dx_CCFileUtils_writeDataToFile, 2, 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); JS_GetProperty(cx, ccObj, "EventListenerTouchOneByOne", &tmpVal);
tmpObj = tmpVal.toObjectOrNull(); tmpObj = tmpVal.toObjectOrNull();
JS_DefineFunction(cx, tmpObj, "create", js_EventListenerTouchOneByOne_create, 0, JSPROP_READONLY | JSPROP_PERMANENT); JS_DefineFunction(cx, tmpObj, "create", js_EventListenerTouchOneByOne_create, 0, JSPROP_READONLY | JSPROP_PERMANENT);

View File

@ -22,6 +22,7 @@
#include "scripting/js-bindings/manual/jsb_event_dispatcher_manual.h" #include "scripting/js-bindings/manual/jsb_event_dispatcher_manual.h"
#include "base/CCEventDispatcher.h"
#include "base/CCEventListenerFocus.h" #include "base/CCEventListenerFocus.h"
#include "base/CCEventListenerKeyboard.h" #include "base/CCEventListenerKeyboard.h"
#include "base/CCEventListenerMouse.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); JS_ReportError(cx, "wrong number of arguments: %d, was expecting %d", argc, 0);
return false; 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<void (cocos2d::EventCustom *)> 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<JSFunctionWrapper> 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<EventCustom>(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<EventListenerCustom>(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;
}

View File

@ -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_EventListenerKeyboard_create(JSContext *cx, uint32_t argc, jsval *vp);
bool js_EventListenerMouse_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_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__) */ #endif /* defined(__cocos2d_js_bindings__jsb_event_dispatcher__) */

View File

@ -118,7 +118,7 @@ skip = Node::[^setPosition$ setGLServerState description getUserObject .*UserDat
EventTouch::[(s|g)etTouches], EventTouch::[(s|g)etTouches],
EventKeyboard::[*], EventKeyboard::[*],
Device::[getTextureDataForText], Device::[getTextureDataForText],
EventDispatcher::[dispatchCustomEvent], EventDispatcher::[dispatchCustomEvent addCustomEventListener],
EventCustom::[getUserData setUserData], EventCustom::[getUserData setUserData],
Component::[serialize onAdd onRemove update], Component::[serialize onAdd onRemove update],
EventListenerCustom::[init], EventListenerCustom::[init],
@ -155,7 +155,7 @@ rename_functions = SpriteFrameCache::[addSpriteFramesWithFile=addSpriteFrames ge
DrawNode::[drawQuadraticBezier=drawQuadBezier], DrawNode::[drawQuadraticBezier=drawQuadBezier],
FileUtils::[loadFilenameLookupDictionaryFromFile=loadFilenameLookup], FileUtils::[loadFilenameLookupDictionaryFromFile=loadFilenameLookup],
SimpleAudioEngine::[preloadBackgroundMusic=preloadMusic setBackgroundMusicVolume=setMusicVolume getBackgroundMusicVolume=getMusicVolume playBackgroundMusic=playMusic stopBackgroundMusic=stopMusic pauseBackgroundMusic=pauseMusic resumeBackgroundMusic=resumeMusic rewindBackgroundMusic=rewindMusic isBackgroundMusicPlaying=isMusicPlaying willPlayBackgroundMusic=willPlayMusic], 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], EventMouse::[getMouseButton=getButton setMouseButton=setButton setCursorPosition=setLocation getCursorX=getLocationX getCursorY=getLocationY],
Configuration::[getInfo=dumpInfo], Configuration::[getInfo=dumpInfo],
ComponentContainer::[get=getComponent], ComponentContainer::[get=getComponent],