From 00b57c95654fce37c1933351fe7c7e828f1dd027 Mon Sep 17 00:00:00 2001 From: pandamicro Date: Tue, 13 Dec 2016 14:13:48 +0800 Subject: [PATCH] =?UTF-8?q?Manual=20bind=20EventListeners=E2=80=99=20creat?= =?UTF-8?q?e=20to=20avoid=20memory=20issue?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../js-bindings/manual/cocos2d_specifics.cpp | 8 ++ .../manual/jsb_event_dispatcher_manual.cpp | 108 +++++++++++++++++- .../manual/jsb_event_dispatcher_manual.h | 2 + tools/tojs/cocos2dx.ini | 2 +- 4 files changed, 114 insertions(+), 6 deletions(-) diff --git a/cocos/scripting/js-bindings/manual/cocos2d_specifics.cpp b/cocos/scripting/js-bindings/manual/cocos2d_specifics.cpp index 426beb2a1b..e633515562 100644 --- a/cocos/scripting/js-bindings/manual/cocos2d_specifics.cpp +++ b/cocos/scripting/js-bindings/manual/cocos2d_specifics.cpp @@ -6108,10 +6108,18 @@ void register_cocos2dx_js_core(JSContext* cx, JS::HandleObject global) tmpObj = tmpVal.toObjectOrNull(); JS_DefineFunction(cx, tmpObj, "create", js_EventListenerKeyboard_create, 0, JSPROP_READONLY | JSPROP_PERMANENT); + JS_GetProperty(cx, ccObj, "EventListenerAcceleration", &tmpVal); + tmpObj = tmpVal.toObjectOrNull(); + JS_DefineFunction(cx, tmpObj, "create", js_EventListenerAcceleration_create, 1, JSPROP_READONLY | JSPROP_PERMANENT); + JS_GetProperty(cx, ccObj, "EventListenerFocus", &tmpVal); tmpObj = tmpVal.toObjectOrNull(); JS_DefineFunction(cx, tmpObj, "create", js_EventListenerFocus_create, 0, JSPROP_READONLY | JSPROP_PERMANENT); + JS_GetProperty(cx, ccObj, "EventListenerCustom", &tmpVal); + tmpObj = tmpVal.toObjectOrNull(); + JS_DefineFunction(cx, tmpObj, "create", js_EventListenerCustom_create, 2, JSPROP_READONLY | JSPROP_PERMANENT); + JS_GetProperty(cx, ccObj, "BezierBy", &tmpVal); tmpObj = tmpVal.toObjectOrNull(); JS_DefineFunction(cx, tmpObj, "create", JSB_CCBezierBy_actionWithDuration, 2, 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 ffa57e537e..d5649977d6 100644 --- a/cocos/scripting/js-bindings/manual/jsb_event_dispatcher_manual.cpp +++ b/cocos/scripting/js-bindings/manual/jsb_event_dispatcher_manual.cpp @@ -26,6 +26,10 @@ #include "base/CCEventListenerFocus.h" #include "base/CCEventListenerKeyboard.h" #include "base/CCEventListenerMouse.h" +#include "base/CCEventListenerAcceleration.h" +#include "base/CCEventListenerCustom.h" +#include "base/CCEvent.h" +#include "base/CCEventCustom.h" #include "scripting/js-bindings/manual/ScriptingCore.h" #include "scripting/js-bindings/manual/cocos2d_specifics.hpp" @@ -64,7 +68,7 @@ bool js_EventListenerTouchOneByOne_create(JSContext *cx, uint32_t argc, jsval *v ScriptingCore::getInstance()->handleTouchEvent(ret, EventTouch::EventCode::CANCELLED, touch, event); }; - jsval jsret = OBJECT_TO_JSVAL(js_get_or_create_jsobject(cx, ret)); + JS::RootedValue jsret(cx, OBJECT_TO_JSVAL(js_get_or_create_jsobject(cx, ret))); args.rval().set(jsret); return true; } @@ -95,7 +99,7 @@ bool js_EventListenerTouchAllAtOnce_create(JSContext *cx, uint32_t argc, jsval * ScriptingCore::getInstance()->handleTouchesEvent(ret, EventTouch::EventCode::CANCELLED, touches, event); }; - jsval jsret = OBJECT_TO_JSVAL(js_get_or_create_jsobject(cx, ret)); + JS::RootedValue jsret(cx, OBJECT_TO_JSVAL(js_get_or_create_jsobject(cx, ret))); args.rval().set(jsret); return true; } @@ -126,7 +130,7 @@ bool js_EventListenerMouse_create(JSContext *cx, uint32_t argc, jsval *vp) ScriptingCore::getInstance()->handleMouseEvent(ret, EventMouse::MouseEventType::MOUSE_SCROLL, event); }; - jsval jsret = OBJECT_TO_JSVAL(js_get_or_create_jsobject(cx, ret)); + JS::RootedValue jsret(cx, OBJECT_TO_JSVAL(js_get_or_create_jsobject(cx, ret))); args.rval().set(jsret); return true; } @@ -149,7 +153,7 @@ bool js_EventListenerKeyboard_create(JSContext *cx, uint32_t argc, jsval *vp) ScriptingCore::getInstance()->handleKeyboardEvent(ret, keyCode, false, event); }; - jsval jsret = OBJECT_TO_JSVAL(js_get_or_create_jsobject(cx, ret)); + JS::RootedValue jsret(cx, OBJECT_TO_JSVAL(js_get_or_create_jsobject(cx, ret))); args.rval().set(jsret); return true; } @@ -158,6 +162,52 @@ bool js_EventListenerKeyboard_create(JSContext *cx, uint32_t argc, jsval *vp) return false; } +bool js_EventListenerAcceleration_create(JSContext *cx, uint32_t argc, jsval *vp) +{ + JS::CallArgs args = JS::CallArgsFromVp(argc, vp); + bool ok = true; + if (argc == 1) { + std::function arg0; + do { + if(JS_TypeOfValue(cx, args.get(0)) == JSTYPE_FUNCTION) + { + JS::RootedObject jstarget(cx, args.thisv().toObjectOrNull()); + std::shared_ptr func(new JSFunctionWrapper(cx, jstarget, args.get(0), args.thisv())); + auto lambda = [=](Acceleration* acc, Event* event) -> void { + JSB_AUTOCOMPARTMENT_WITH_GLOBAL_OBJCET + jsval largv[2]; + largv[0] = ccacceleration_to_jsval(cx, *acc); + if (event) { + js_type_class_t *typeClassEvent = js_get_type_from_native(event); + largv[1] = OBJECT_TO_JSVAL(jsb_get_or_create_weak_jsobject(cx, event, typeClassEvent, "cocos2d::EventAcceleration")); + } else { + largv[1] = JSVAL_NULL; + }; + JS::RootedValue rval(cx); + bool succeed = func->invoke(2, &largv[0], &rval); + if (!succeed && JS_IsExceptionPending(cx)) { + JS_ReportPendingException(cx); + } + removeJSObject(cx, event); + }; + arg0 = lambda; + } + else + { + arg0 = nullptr; + } + } while(0); + JSB_PRECONDITION2(ok, cx, false, "js_cocos2dx_EventListenerAcceleration_create : Error processing arguments"); + + auto ret = EventListenerAcceleration::create(arg0); + JS::RootedValue jsret(cx, OBJECT_TO_JSVAL(js_get_or_create_jsobject(cx, ret))); + args.rval().set(jsret); + return true; + } + JS_ReportError(cx, "js_cocos2dx_EventListenerAcceleration_create : wrong number of arguments"); + return false; +} + bool js_EventListenerFocus_create(JSContext *cx, uint32_t argc, jsval *vp) { if(argc == 0) @@ -167,7 +217,7 @@ bool js_EventListenerFocus_create(JSContext *cx, uint32_t argc, jsval *vp) ScriptingCore::getInstance()->handleFocusEvent(ret, widgetLoseFocus, widgetGetFocus); }; - jsval jsret = OBJECT_TO_JSVAL(js_get_or_create_jsobject(cx, ret)); + JS::RootedValue jsret(cx, OBJECT_TO_JSVAL(js_get_or_create_jsobject(cx, ret))); JS::CallArgs args = JS::CallArgsFromVp(argc, vp); args.rval().set(jsret); @@ -178,6 +228,54 @@ bool js_EventListenerFocus_create(JSContext *cx, uint32_t argc, jsval *vp) return false; } +bool js_EventListenerCustom_create(JSContext *cx, uint32_t argc, jsval *vp) +{ + JS::CallArgs args = JS::CallArgsFromVp(argc, vp); + bool ok = true; + 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 = [=](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_EventListenerCustom_create : Error processing arguments"); + + auto ret = EventListenerCustom::create(arg0, arg1); + JS::RootedValue jsret(cx, OBJECT_TO_JSVAL(js_get_or_create_jsobject(cx, ret))); + args.rval().set(jsret); + return true; + } + JS_ReportError(cx, "js_cocos2dx_EventListenerCustom_create : wrong number of arguments"); + return false; +} + bool js_EventDispatcher_addCustomEventListener(JSContext *cx, uint32_t argc, jsval *vp) { JS::CallArgs args = JS::CallArgsFromVp(argc, vp); 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 6b87f583a5..cf5ca400cd 100644 --- a/cocos/scripting/js-bindings/manual/jsb_event_dispatcher_manual.h +++ b/cocos/scripting/js-bindings/manual/jsb_event_dispatcher_manual.h @@ -30,7 +30,9 @@ bool js_EventListenerTouchOneByOne_create(JSContext *cx, uint32_t argc, jsval *v bool js_EventListenerTouchAllAtOnce_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_EventListenerAcceleration_create(JSContext *cx, uint32_t argc, jsval *vp); bool js_EventListenerFocus_create(JSContext *cx, uint32_t argc, jsval *vp); +bool js_EventListenerCustom_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 73e8a486bb..18fffb2090 100644 --- a/tools/tojs/cocos2dx.ini +++ b/tools/tojs/cocos2dx.ini @@ -114,7 +114,7 @@ skip = Node::[^setPosition$ setGLServerState description getUserObject .*UserDat RenderTexture::[listenToBackground listenToForeground saveToFile], TextFieldTTF::[(g|s)etDelegate], EventListenerVector::[*], - EventListener(Touch|Keyboard|Mouse|Focus).*::[create], + EventListener(Touch|Keyboard|Mouse|Acceleration|Focus|Custom).*::[create], EventTouch::[(s|g)etTouches], EventKeyboard::[*], Device::[getTextureDataForText],