[Cocos2d-x from c ++ to js] 09: JS and C ++ interaction 1-JS Code call C ++ code

Source: Internet
Author: User

As we mentioned earlier, when starting a game, we need to use the registration interface of the SpiderMonkey engine to register the corresponding binding functions from C ++ to JS with SpiderMonkey, these functions are used to convert the JS function call code to the corresponding C ++ function call for execution.


// In the AppDelegate: applicationDidFinishLaunching function, ScriptingCore * SC = ScriptingCore: getInstance (); SC-> addRegisterCallback (callback ); SC-> addRegisterCallback (callback); SC-> addRegisterCallback (JSB_register_opengl); SC-> addRegisterCallback (callback ); SC-> addRegisterCallback (MinXmlHttpRequest: _ js_register); SC-> addRegisterCallback (callback); SC-> addRegisterCallback (register_CCBuilderReader ); SC-> addRegisterCallback (callback );


We can see that the above imported a variety of Cocos2d-x library, core library, extension, opengl, physical engine, websocket, CCB and so on.


The following describes how to call C ++ code using JS Code.

First, a corresponding C ++ object will be created when a JS object is created. In other words, JS objects correspond to C ++ objects one by one. Of course, they must be supported by the engine and bound to interfaces ). Then, what happens when a JS object executes a function? The SpiderMonkey engine finds the corresponding C ++ object through the registered interface and calls the corresponding C ++ function on the object.


In other words, if the following JS Code is available:

var node = cc.Node.create();node.setVisible(false);


After SpiderMonkey is executed, the following code is called:

auto node = CCNode::create();node->setVisible(false);


Of course, SpiderMonkey is far more than just doing this, but also doing a lot of things, such as binding and finding the correspondence between JS and C ++ objects, packaging parameters for the corresponding type, type security check, return Value packaging and so on. You need to know what he has done, and it is better to look at the engine code directly.


In the engine of Cocos2d-x version 3.0, the engine directory structure is reconstructed on a large scale.

650) this. width = 650; "src =" http://www.bkjia.com/uploads/allimg/140207/222RKM1-0.jpg "title =" C148BFB0-CE91-43D5-A0E9-CEB2DDB8351A.png "alt =" wKioL1LeN2WTLO7WAABQNtZHSLU725.jpg "/>

The two scripting languages are put in a similar directory. The auto-generated/js-bindings folder is all C ++ code automatically generated by the gxx-generator tool. The javascript/bingdings folder is a handwritten binding code, because the tool cannot be fully automatically bound, so some handwritten scripting languages must be like this, just get used to it, thank you ).


Okay. Let's continue to look for the source code we just mentioned. Open jsb_cocos2dx_auto.cpp

JSBool js_cocos2dx_Node_create(JSContext *cx, uint32_t argc, jsval *vp){    if (argc == 0) {        cocos2d::Node* ret = cocos2d::Node::create();        jsval jsret = JSVAL_NULL;        do {        if (ret) {            js_proxy_t *proxy = js_get_or_create_proxy<cocos2d::Node>(cx, (cocos2d::Node*)ret);            jsret = OBJECT_TO_JSVAL(proxy->obj);        } else {            jsret = JSVAL_NULL;        }    } while (0);        JS_SET_RVAL(cx, vp, jsret);        return JS_TRUE;    }    JS_ReportError(cx, "js_cocos2dx_Node_create : wrong number of arguments");    return JS_FALSE;}


This is the code that the underlying C ++ runs when cc. Node. create () is executed. All code Calling C ++ through JS is very consistent with this form. First, let's look at the function interface:

The first parameter JSContext * cx is the JS context.

The second parameter uint32_t argc is the number of parameters in the JS Code, in which argc = 0

The third parameter jsval * vp is a specific parameter in JS Code.


Continue analysis

cocos2d::Node* ret = cocos2d::Node::create();

This code is no longer familiar with the standard Cocos2d-x static workshop to generate object code


jsval jsret = JSVAL_NULL;

Jsval jsret is the return value of this function, which indicates a JS object.


js_proxy_t *proxy = js_get_or_create_proxy<cocos2d::Node>(cx, (cocos2d::Node*)ret);jsret = OBJECT_TO_JSVAL(proxy->obj);

Note that this template function, get_or_create, is the function that binds the JS object and the C ++ object together. He is very important. Pay attention to the one-to-one correspondence between JS and C ++ objects. Understanding this special effect will help us use the dynamic nature of JS language for more convenient programming. After the binding, the following function is used to obtain the return value.


Finally, all functions must return a JSBool, and whether the execution of the function is successful. If JS_FALSE is returned, an error message is printed through JS_ReportError. Note! The script language has a feature. If a function fails to run, all functions following the function are in the same scope.


Continue to look at the next Function

JSBool js_cocos2dx_Node_setVisible(JSContext *cx, uint32_t argc, jsval *vp){    jsval *argv = JS_ARGV(cx, vp);    JSBool ok = JS_TRUE;    JSObject *obj = JS_THIS_OBJECT(cx, vp);    js_proxy_t *proxy = jsb_get_js_proxy(obj);    cocos2d::Node* cobj = (cocos2d::Node *)(proxy ? proxy->ptr : NULL);    JSB_PRECONDITION2( cobj, cx, JS_FALSE, "js_cocos2dx_Node_setVisible : Invalid Native Object");    if (argc == 1) {        JSBool arg0;        ok &= JS_ValueToBoolean(cx, argv[0], &arg0);        JSB_PRECONDITION2(ok, cx, JS_FALSE, "js_cocos2dx_Node_setVisible : Error processing arguments");        cobj->setVisible(arg0);        JS_SET_RVAL(cx, vp, JSVAL_VOID);        return JS_TRUE;    }    JS_ReportError(cx, "js_cocos2dx_Node_setVisible : wrong number of arguments: %d, was expecting %d", argc, 1);    return JS_FALSE;}

The difference between this function and the previous function is that this function has parameters, and it is a class member function and the previous function is a class static function). Therefore, this pointer must be provided here.

jsval *argv = JS_ARGV(cx, vp);JSBool ok = JS_TRUE;JSObject *obj = JS_THIS_OBJECT(cx, vp);js_proxy_t *proxy = jsb_get_js_proxy(obj);cocos2d::Node* cobj = (cocos2d::Node *)(proxy ? proxy->ptr : NULL);JSB_PRECONDITION2( cobj, cx, JS_FALSE, "js_cocos2dx_Node_setVisible : Invalid Native Object");

This large function is looking for the this pointer. Note that there is an error message Invalid Native Object that often appears in the Cocos2d-x engine. The underlying C ++ object is recycled, so it cannot be found.


if (argc == 1) {    JSBool arg0;    ok &= JS_ValueToBoolean(cx, argv[0], &arg0);    JSB_PRECONDITION2(ok, cx, JS_FALSE, "js_cocos2dx_Node_setVisible : Error processing arguments");    cobj->setVisible(arg0);    JS_SET_RVAL(cx, vp, JSVAL_VOID);    return JS_TRUE;}

CCNode: setVisible (xx) has only one parameter. Therefore, we must first determine that the number of JS parameters is 1. JS_ValueToBoolean converts JS objects to C ++ objects. Note that! This is a conversion of the basic type, which is different from the corresponding object pointer. You can see a lot of such conversions in the code generated by gxx-generator. The result is determined for each conversion. If the conversion fails, the error message is printed. The following describes how to directly call the setVisible corresponding to the C ++ object and set the return value.


Complicated, isn't it? If this code is written by hand, will it be dead. Yes. Therefore, most of the Code is made using a script generator ).



Later, we will continue to explain various JS binding codes.



This article is from the "Old G hut" blog, please be sure to keep this source http://4137613.blog.51cto.com/4127613/1353583

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.