【cocos2d-x从c++到js】回调函数一——按键回调
【cocos2d-x从c++到js】回调函数1——按键回调
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<cocos2d::MenuItemImage>(cx, ret, jsCallback, jsThis);
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<cocos2d::MenuItemImage>(cx, ret, jsCallback, jsThis);
|
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<T>(nativeObj);
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<BasicScriptData*>(data);
if (NULL
== basicScriptData->nativeObject)
return 0;
MenuItem*
menuItem = static_cast<MenuItem*>(basicScriptData->nativeObject);
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);
}
}
|