【cocos2d-x从c++到js】回调函数二——JSCallbackWrapper
【cocos2d-x从c++到js】回调函数2——JSCallbackWrapper
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);
}
}
|