js -- 绑定

代码: 360/js/jsbinding/myJSB


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源码










你可能感兴趣的:(js -- 绑定)