本文共 4255 字,大约阅读时间需要 14 分钟。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | class JSCallbackWrapper: public cocos2d::Object { public : JSCallbackWrapper(); virtual ~JSCallbackWrapper(); void setJSCallbackFunc(jsval obj); void setJSCallbackThis(jsval thisObj); void setJSExtraData(jsval data); const jsval& getJSCallbackFunc() const ; const jsval& getJSCallbackThis() const ; const jsval& getJSExtraData() const ; protected : jsval _jsCallback; jsval _jsThisObj; jsval _extraData; }; |
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 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 | // cc.CallFunc.create( func, this, [data]) // cc.CallFunc.create( func ) static JSBool js_callFunc(JSContext *cx, uint32_t argc, jsval *vp) { if (argc >= 1 && argc <= 3) { jsval *argv = JS_ARGV(cx, vp); std::shared_ptr<JSCallbackWrapper> tmpCobj( new JSCallbackWrapper()); tmpCobj->setJSCallbackFunc(argv[0]); if (argc >= 2) { tmpCobj->setJSCallbackThis(argv[1]); } if (argc == 3) { tmpCobj->setJSExtraData(argv[2]); } CallFuncN *ret = CallFuncN::create([=](Node* sender){ const jsval& jsvalThis = tmpCobj->getJSCallbackThis(); const jsval& jsvalCallback = tmpCobj->getJSCallbackFunc(); const jsval& jsvalExtraData = tmpCobj->getJSExtraData(); bool hasExtraData = !JSVAL_IS_VOID(jsvalExtraData); JSObject* thisObj = JSVAL_IS_VOID(jsvalThis) ? nullptr : JSVAL_TO_OBJECT(jsvalThis); JSB_AUTOCOMPARTMENT_WITH_GLOBAL_OBJCET js_proxy_t *proxy = js_get_or_create_proxy<cocos2d::Node>(cx, sender); jsval retval; if (jsvalCallback != JSVAL_VOID) { if (hasExtraData) { jsval valArr[2]; valArr[0] = OBJECT_TO_JSVAL(proxy->obj); valArr[1] = jsvalExtraData; JS_AddValueRoot(cx, valArr); JS_CallFunctionValue(cx, thisObj, jsvalCallback, 2, valArr, &retval); JS_RemoveValueRoot(cx, valArr); } else { jsval senderVal = OBJECT_TO_JSVAL(proxy->obj); JS_AddValueRoot(cx, &senderVal); JS_CallFunctionValue(cx, thisObj, jsvalCallback, 1, &senderVal, &retval); JS_RemoveValueRoot(cx, &senderVal); } } // I think the JSCallFuncWrapper isn't needed. // Since an action will be run by a cc.Node, it will be released at the Node::cleanup. // By James Chen // JSCallFuncWrapper::setTargetForNativeNode(node, (JSCallFuncWrapper *)this); }); js_proxy_t *proxy = js_get_or_create_proxy<cocos2d::CallFunc>(cx, ret); JS_SET_RVAL(cx, vp, OBJECT_TO_JSVAL(proxy->obj)); JS_SetReservedSlot(proxy->obj, 0, argv[0]); if (argc > 1) { JS_SetReservedSlot(proxy->obj, 1, argv[1]); } // if(argc == 3) { // JS_SetReservedSlot(proxy->obj, 2, argv[2]); // } // test->execute(); return JS_TRUE; } JS_ReportError(cx, "Invalid number of arguments" ); return JS_FALSE; } |
1 2 3 4 5 6 7 8 9 10 | CallFuncN * CallFuncN::create( const std::function< void (Node*)> &func) { auto ret = new CallFuncN(); if (ret && ret->initWithFunction(func) ) { ret->autorelease(); return ret; } CC_SAFE_DELETE(ret); return nullptr; } |
1 2 3 4 5 | bool CallFuncN::initWithFunction( const std::function< void (Node *)> &func) { _functionN = func; return true ; } |
1 2 3 4 5 6 7 8 | void CallFuncN::execute() { if (_callFuncN) { (_selectorTarget->*_callFuncN)(_target); } else if (_functionN) { _functionN(_target); } } |
转载地址:http://uzypf.baihongyu.com/