【cocos2d-x从c 到js】回调函数1——按键回调
发表于2017-08-19
1 2 3 4 5 6 7 8 9 10 11 12 | // add a "close" icon to exit the progress. it's an autorelease object var closeItem = cc.MenuItemImage.create( "res/CloseNormal.png" , "res/CloseSelected.png" , function () { cc.log( "close button was clicked." ); }, this ); closeItem.setAnchorPoint(cc.p(0.5, 0.5)); var menu = cc.Menu.create(closeItem); menu.setPosition(cc.p(0, 0)); this .addChild(menu, 1); closeItem.setPosition(cc.p(size.width - 20, 20)); |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | // "create" in JS // cc.MenuItemImage.create( normalImage, selectedImage, [disabledImage], callback_fn, [this] JSBool js_cocos2dx_CCMenuItemImage_create(JSContext *cx, uint32_t argc, jsval *vp) { if (argc >= 2 && argc <= 5) { jsval *argv = JS_ARGV(cx, vp); JSStringWrapper arg0(argv[0]); JSStringWrapper arg1(argv[1]); JSStringWrapper arg2; bool thirdArgIsString = true ; jsval jsCallback = JSVAL_VOID; jsval jsThis = JSVAL_VOID; int last = 2; if (argc >= 3) { thirdArgIsString = argv[2].isString(); if (thirdArgIsString) { arg2.set(argv[2], cx); last = 3; } } cocos2d::MenuItemImage* ret = cocos2d::MenuItemImage::create(arg0.get(), arg1.get(), std::string(arg2.get())); if (argc >= 3) { if (!thirdArgIsString) { //cc.MenuItemImage.create( normalImage, selectedImage, callback_fn, [this] ) jsCallback = argv[last ]; if (argc == 4) { jsThis = argv[last]; } } else { //cc.MenuItemImage.create( normalImage, selectedImage, disabledImage, callback_fn, [this] ) if (argc >= 4) { jsCallback = argv[last ]; if (argc == 5) { jsThis = argv[last]; } } } } JSObject *obj = bind_menu_item JS_SET_RVAL(cx, vp, OBJECT_TO_JSVAL(obj)); return JS_TRUE; } JS_ReportError(cx, "Invalid number of arguments. Expecting: 2 <= args <= 5" ); return JS_FALSE; } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | if (argc >= 3) { if (!thirdArgIsString) { //cc.MenuItemImage.create( normalImage, selectedImage, callback_fn, [this] ) jsCallback = argv[last ]; if (argc == 4) { jsThis = argv[last]; } } else { //cc.MenuItemImage.create( normalImage, selectedImage, disabledImage, callback_fn, [this] ) if (argc >= 4) { jsCallback = argv[last ]; if (argc == 5) { jsThis = argv[last]; } } } } |
1 | JSObject *obj = bind_menu_item |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | template < class T> JSObject* bind_menu_item(JSContext *cx, T* nativeObj, jsval callback, jsval thisObj) { js_proxy_t *p = jsb_get_native_proxy(nativeObj); if (p) { addCallBackAndThis(p->obj, callback, thisObj); return p->obj; } else { js_type_class_t *classType = js_get_type_from_native assert (classType); JSObject *tmp = JS_NewObject(cx, classType->jsclass, classType->proto, classType->parentProto); // bind nativeObj <-> JSObject js_proxy_t *proxy = jsb_new_proxy(nativeObj, tmp); JS_AddNamedObjectRoot(cx, &proxy->obj, typeid (*nativeObj).name()); addCallBackAndThis(tmp, callback, thisObj); return tmp; } } |
1 2 3 4 5 6 7 8 9 | static void addCallBackAndThis(JSObject *obj, jsval callback, jsval &thisObj) { if (callback != JSVAL_VOID) { ScriptingCore::getInstance()->setReservedSpot(0, obj, callback); } if (thisObj != JSVAL_VOID) { ScriptingCore::getInstance()->setReservedSpot(1, obj, thisObj); } } |
1 2 3 4 | JSBool ScriptingCore::setReservedSpot(uint32_t i, JSObject *obj, jsval value) { JS_SetReservedSlot(obj, i, value); return JS_TRUE; } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | void MenuItem::activate() { if (_enabled) { if ( _callback ) { _callback( this ); } if (kScriptTypeNone != _scriptType) { BasicScriptData data( this ); ScriptEvent scriptEvent(kMenuClickedEvent,&data); ScriptEngineManager::getInstance()->getScriptEngine()->sendEvent(&scriptEvent); } } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | int ScriptingCore::sendEvent(ScriptEvent* evt) { if (NULL == evt) return 0; JSAutoCompartment ac(_cx, _global); switch (evt->type) { case kNodeEvent: { return handleNodeEvent(evt->data); } break ; case kMenuClickedEvent: { return handleMenuClickedEvent(evt->data); } break ; case kTouchEvent: { return handleTouchEvent(evt->data); } break ; case kTouchesEvent: { return handleTouchesEvent(evt->data); } break ; case kKeypadEvent: { return handleKeypadEvent(evt->data); } break ; case kAccelerometerEvent: { return handleAccelerometerEvent(evt->data); } break ; default : break ; } return 0; } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | int ScriptingCore::handleMenuClickedEvent(void* data) { if (NULL == data) return 0; BasicScriptData* basicScriptData = static_cast if (NULL == basicScriptData->nativeObject) return 0; MenuItem* menuItem = static_cast js_proxy_t * p = jsb_get_native_proxy(menuItem); if (!p) return 0; jsval retval; jsval dataVal; js_proxy_t *proxy = jsb_get_native_proxy(menuItem); dataVal = (proxy ? OBJECT_TO_JSVAL(proxy->obj) : JSVAL_NULL); executeJSFunctionFromReservedSpot( this ->_cx, p->obj, dataVal, retval); return 1; } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | static void executeJSFunctionFromReservedSpot(JSContext *cx, JSObject *obj, jsval &dataVal, jsval &retval) { jsval func = JS_GetReservedSlot(obj, 0); if (func == JSVAL_VOID) { return ; } jsval thisObj = JS_GetReservedSlot(obj, 1); JSAutoCompartment ac(cx, obj); if (thisObj == JSVAL_VOID) { JS_CallFunctionValue(cx, obj, func, 1, &dataVal, &retval); } else { assert (!JSVAL_IS_PRIMITIVE(thisObj)); JS_CallFunctionValue(cx, JSVAL_TO_OBJECT(thisObj), func, 1, &dataVal, &retval); } } |
如社区发表内容存在侵权行为,您可以点击这里查看侵权投诉指引