• js -- 捆绑


    1.环境配置

    主要參考网址:

    http://cocos2d.cocoachina.com/bbs/forum.php?mod=viewthread&tid=10226&extra=page%3D1&page=2

    http://www.cocos2d-x.org/projects/cocos2d-x/wiki/How_to_bind_C++_to_Javascript

    一些环境的搭建參考

    软件安装与卸载:http://blog.csdn.net/renzhe20092584/article/details/10287899

    configuration 里的配置文件夹

    /Users/admin/Documents/work/mac/cocos2d-x-2.1.5/tools/bindings-generator/test

    userconf.ini

    androidndkdir=/Users/admin/Documents/work/android/android-ndk-r8e
    clangllvmdir=/Users/admin/Documents/work/mac/clang+llvm-3.3-x86_64-apple-darwin12
    cxxgeneratordir=/Users/admin/Documents/work/mac/cocos2d-x-2.1.5/tools/bindings-generator

    user.cfg

    PYTHON_BIN=/opt/local/Library/Frameworks/Python.framework/Versions/2.7/bin/python


    2.手动绑定

    參考:http://www.cocos2d-x.org/projects/cocos2d-x/wiki/How_to_bind_C++_to_Javascript

    error:

    JS_DefineFunction(cx, jsb_prototype, "retain", JSB_cocos2dx_retain, 0, JSPROP_READONLY | JSPROP_PERMANENT);
    JS_DefineFunction(cx, jsb_prototype, "release", JSB_cocos2dx_release, 0, JSPROP_READONLY | JSPROP_PERMANENT);


    3.AppDelegate

    1.applicationDidFinishLaunching

    ScriptingCore* sc = ScriptingCore::getInstance();

    sc->addRegisterCallback(register_all);

    sc->start();

    開始的时候就会调用JSB_AUTO的 register_all 方法,注冊一些事件。


    CCScriptEngineProtocol *pEngine =ScriptingCore::getInstance();

    CCScriptEngineManager::sharedManager()->setScriptEngine(pEngine);

    ScriptingCore::getInstance()->runScript("hello.js");         执行此脚本


    2.handle_signal

    void handle_signal(int signal)   此方法一直没有运行过


    4.JSB_AUTO

    都是全局方法没有类方法

    1.  .h文件

    void register_all(JSContext* cx,JSObject* obj);   仅仅有这一个方法的声明,由于  AppDelegate 里引用的是 JSB_AUTO.h 文件,用到方法register_all


    2.js_constructor(JSContext* cx,uint32_t argc, jsval* vp)

    结构体方法。通过 new 在 js 里创建 c++ 对象时候调用。


    3.JSBooljs_create(JSContext* cx,uint32_t argc, jsval* vp)

    通过 create 在 js 里创建 c++ 对象时候调用。


    4.JSBoolJSB_cocos2dx_retain(JSContext* cx,uint32_t argc, jsval *vp)

    在 js 里对 创建的 2dx c++ 对象运行了 .retain 方法时调用


    5.JSBoolJSB_cocos2dx_release(JSContext* cx,uint32_t argc, jsval *vp)

    在 js 里对 创建的 2dx c++ 对象运行了 .release 方法时调用


    6.voidregister_all(JSContext* cx,JSObject* obj)

    在 AppDelegate 里注冊的此方法,还没有执行 js 脚本得时候。就被调用了。

    JS_GetProperty(cx, obj,"JS", &nsval);  固定写法?

    JS_SetProperty(cx, obj,"JSB", &nsval);  TT 是 c++命名空间

    注冊 2dx 的内存管理

    JS_DefineFunction(cx, jsb_prototype,"retain",JSB_cocos2dx_retain,0,JSPROP_READONLY |JSPROP_PERMANENT);

    JS_DefineFunction(cx, jsb_prototype,"release",JSB_cocos2dx_release,0,JSPROP_READONLY |JSPROP_PERMANENT);


    7.void js_register(JSContext* cx,JSObject* global)

    通过 6 方法,调用此方法

    jsb_class->name = "JSBinding";   注冊类名

    staticJSFunctionSpec funcs[] =

        {

            JS_FN("functionTest",js_functionTest,1,JSPROP_PERMANENT | JSPROP_ENUMERATE),   绑定 js 要调用 c++ 的方法 functionTest通过全局方法js_functionTest 去调用 

            JS_FS_END

        };


    JS_SetPropertyAttributes(cx, global, "JSB", JSPROP_ENUMERATE | JSPROP_READONLY, &found);

    TypeTest<JSB::JSBinding> t;


    8.JSBool js_functionTest(JSContext* cx,uint32_t argc,jsval* vp)

    在 7 中注冊了此方法,通过 js 某个事件触发调用。

    JSB::JSBinding* cobj = NULL;

    cobj = (JSB::JSBinding* )(proxy ? proxy->ptr : NULL);

    cobj->functionTest();   调用自己创建的那个类的functionTest 方法 


    5.JSBinding

    此类是自己写得类。这里能够实现自己想要的方法。

    1 .h文件

    namespace JSB    命名空间

    {

        class JSBinding:publiccocos2d::CCObject

        {

        public:

            staticcocos2d::CCScene* scene();

            virtualbool init();

            CREATE_FUNC(JSBinding);

            void functionTest();

        };

    }


    2.bool JSB::JSBinding::init()

    通过 create 在 js 中创建对象的时候调用,建议不要使用 create 创建对象,会出现故障。使用 new 之后再调用 create() 方法。


    3.void JSB::JSBinding::functionTest()  用 js 调用的方法 

    v是回调 js 的參数。

    ScriptingCore::getInstance()->executeFunctionWithOwner(OBJECT_TO_JSVAL(p->obj),"callback",2, v, &retval);


    6.监听home键的绑定

    .cpp

    void AppDelegate::applicationDidEnterBackground()

    {

        Director::getInstance()->stopAnimation();

        SimpleAudioEngine::getInstance()->pauseBackgroundMusic();

        SimpleAudioEngine::getInstance()->pauseAllEffects();

        

        ScriptingCore* sc =ScriptingCore::getInstance();

        jsval nsval;

        JS_GetProperty(sc->getGlobalContext(), sc->getGlobalObject(),"plugin", &nsval);

        if (nsval !=JSVAL_VOID) {

            sc->executeFunctionWithOwner(nsval,"onApplicationDidEnterBackground");

        }

    }


    void AppDelegate::applicationWillEnterForeground()

    {

        Director::getInstance()->startAnimation();

        SimpleAudioEngine::getInstance()->resumeBackgroundMusic();

        SimpleAudioEngine::getInstance()->resumeAllEffects();

        

        ScriptingCore* sc =ScriptingCore::getInstance();

        jsval nsval;

        JS_GetProperty(sc->getGlobalContext(), sc->getGlobalObject(),"plugin", &nsval);

        if (nsval !=JSVAL_VOID) {

            sc->executeFunctionWithOwner(nsval,"onApplicationWillEnterForeground");

        }

    }


    .js调用

    plugin 相当于全局变量

    if(plugin){

        plugin.onApplicationDidEnterBackground = function() {

            cc.log(" plugin.onApplicationDidEnterBackground11.");

        };


        plugin.onApplicationWillEnterForeground = function() {

                cc.log("plugin.onApplicationWillEnterForegro11und.");

        };

    }



    研究

    1.眼下能执行的脚本仅仅有 hello.js 自己创建的脚本不能被执行。

    2. js --> c++ 和 c++ --> js  时候參数的传递

    3. 用 js 写的界面和 c++ 的界面来回切换



    7.cocos2dx源代码实现 JSB

    在cocos2dx源代码里加入自己的实现方法。cocos2d-html5仅仅是方便开发。

    以 cc.FileUtils.getInstance() 加入自己的方法为样例

    1.js_cocos2dx_auto.hpp  

      JSBool js_cocos2dx_CCFileUtils_woTest(JSContext *cx, uint32_t argc, jsval *vp); 測试方法

    2.js_cocos2dx_auto.cpp  

       void js_register_cocos2dx_CCFileUtils(JSContext *cx,JSObject *global) { 找到这种方法

             JS_FN("woTest",js_cocos2dx_CCFileUtils_woTest,1,JSPROP_PERMANENT |JSPROP_ENUMERATE),//加入

       }


    新创建的方法

    JSBool js_cocos2dx_CCFileUtils_woTest(JSContext *cx,uint32_t argc, jsval *vp)

    {

    JSObject *obj =JS_THIS_OBJECT(cx, vp);

    js_proxy_t *proxy =jsb_get_js_proxy(obj);

    cocos2d::CCFileUtils* cobj = (cocos2d::CCFileUtils *)(proxy ? proxy->ptr :NULL);

    JSB_PRECONDITION2( cobj, cx,JS_FALSE,"Invalid Native Object");

    if (argc ==0) {

    std::string ret = cobj->woTest();

    jsval jsret;

    jsret = std_string_to_jsval(cx, ret);

    JS_SET_RVAL(cx, vp, jsret);

    returnJS_TRUE;

    }

        

    JS_ReportError(cx,"wrong number of arguments: %d, was expecting %d", argc,0);

    returnJS_FALSE;

    }


    3.CCFileUtils.h

       virtual std::stringwoTest() =0;


    4.不同平台

    ios平台

    CCFileUtilsIOS.h

      virtual std::stringwoTest();

    CCFileUtilsIOS.mm

    std::stringCCFileUtilsIOS::woTest()

    {

        std::string availMemo ="";

        return availMemo;

    }


    Android

    CCFileUtilsAndroid.cpp

    std::string CCFileUtilsAndroid::woTest(){
    JniMethodInfo methodInfo;
    jstring jstr;
    if (!JniHelper::getStaticMethodInfo(methodInfo,
               "org/cocos2dx/lib/Cocos2dxActivity", "woTest",
               "()Ljava/lang/String;")) {
    CCLOG("%s %d: error to get methodInfo", __FILE__, __LINE__);

    }else{
    jstr =  static_cast<jstring>(methodInfo.env->CallStaticObjectMethod(methodInfo.classID, methodInfo.methodID));
    methodInfo.env->DeleteLocalRef(methodInfo.classID);
    }

    return JniHelper::jstring2string(jstr);
    }

    CCFileUtilsAndroid.h

    virtual std::string woTest();


    Cocos2dxActivity.java

    public static String woTest(){

    return Long.toString(123);
    }


    5.调用

     cc.FileUtils.getInstance().woTest();


    其他 jsb 绑定可参考 cocos2dx源代码

  • 相关阅读:
    洛谷 P1019单词接龙
    洛谷 P1091合唱队列
    洛谷 P1141 01迷宫
    洛谷 P1101单词方阵
    NOIP要炸?
    洛谷 P1219八皇后
    洛谷 P1181数列分段Section I
    刷普及-刷爆了。。。。。。
    洛谷 P3952时间复杂度 (本地AC测评RE的伪题解)
    动态数码管
  • 原文地址:https://www.cnblogs.com/gcczhongduan/p/4744421.html
Copyright © 2020-2023  润新知