代码: 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.iniandroidndkdir=/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:
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源码