js -- 捆绑
1.環(huán)境配置
主要參考網(wǎng)址:
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
一些環(huán)境的搭建參考
軟件安裝與卸載: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();
開始的時候就會調(diào)用JSB_AUTO的register_all方法,注冊一些事件。
CCScriptEngineProtocol*pEngine =ScriptingCore::getInstance();
CCScriptEngineManager::sharedManager()->setScriptEngine(pEngine);
ScriptingCore::getInstance()->runScript("hello.js");
執(zhí)行此腳本
2.handle_signal
voidhandle_signal(intsignal) 此方法一直沒有運行過
4.JSB_AUTO
都是全局方法沒有類方法
1. .h文件
voidregister_all(JSContext* cx,JSObject* obj);
僅僅有這一個方法的聲明,由于 AppDelegate 里引用的是 JSB_AUTO.h 文件,用到方法register_all
2.js_constructor(JSContext* cx,uint32_targc,jsval*
vp)
結(jié)構(gòu)體方法。通過 new 在 js 里創(chuàng)建 c++ 對象時候調(diào)用。
3.JSBooljs_create(JSContext* cx,uint32_targc,jsval*
vp)
通過 create 在 js 里創(chuàng)建 c++ 對象時候調(diào)用。
4.JSBoolJSB_cocos2dx_retain(JSContext* cx,uint32_targc,jsval*vp)
在 js 里對 創(chuàng)建的 2dx c++ 對象運行了 .retain 方法時調(diào)用
5.JSBoolJSB_cocos2dx_release(JSContext* cx,uint32_targc,jsval*vp)
在 js 里對 創(chuàng)建的 2dx c++ 對象運行了 .release 方法時調(diào)用
6.voidregister_all(JSContext* cx,JSObject*
obj)
在 AppDelegate 里注冊的此方法,還沒有執(zhí)行 js 腳本得時候。就被調(diào)用了。
JS_GetProperty(cx, obj,"JS", &nsval); 固定寫法?
JS_SetProperty(cx, obj,"JSB", &nsval); TT 是 c++命名空間
注冊 2dx 的內(nèi)存管理
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.voidjs_register(JSContext* cx,JSObject*
global)
通過 6 方法,調(diào)用此方法
jsb_class->name = "JSBinding"; 注冊類名
staticJSFunctionSpecfuncs[] =
{
JS_FN("functionTest",js_functionTest,1,JSPROP_PERMANENT|JSPROP_ENUMERATE),
綁定 js 要調(diào)用 c++ 的方法functionTest通過全局方法js_functionTest去調(diào)用
JS_FS_END
};
JS_SetPropertyAttributes(cx, global, "JSB", JSPROP_ENUMERATE | JSPROP_READONLY, &found);
TypeTest<JSB::JSBinding> t;
8.JSBooljs_functionTest(JSContext* cx,uint32_targc,jsval*
vp)
在 7 中注冊了此方法,通過 js 某個事件觸發(fā)調(diào)用。
JSB::JSBinding* cobj = NULL;
cobj = (JSB::JSBinding* )(proxy ? proxy->ptr : NULL);
cobj->functionTest(); 調(diào)用自己創(chuàng)建的那個類的functionTest 方法
5.JSBinding
此類是自己寫得類。這里能夠?qū)崿F(xiàn)自己想要的方法。
1 .h文件
namespaceJSB 命名空間
{
classJSBinding:publiccocos2d::CCObject
{
public:
staticcocos2d::CCScene* scene();
virtualboolinit();
CREATE_FUNC(JSBinding);
voidfunctionTest();
};
}
2.boolJSB::JSBinding::init()
通過 create 在 js 中創(chuàng)建對象的時候調(diào)用,建議不要使用 create 創(chuàng)建對象,會出現(xiàn)故障。使用 new 之后再調(diào)用 create() 方法。
3.voidJSB::JSBinding::functionTest() 用 js 調(diào)用的方法
v是回調(diào) js 的參數(shù)。
ScriptingCore::getInstance()->executeFunctionWithOwner(OBJECT_TO_JSVAL(p->obj),"callback",2,
v, &retval);
6.監(jiān)聽home鍵的綁定
.cpp
voidAppDelegate::applicationDidEnterBackground()
{
Director::getInstance()->stopAnimation();
SimpleAudioEngine::getInstance()->pauseBackgroundMusic();
SimpleAudioEngine::getInstance()->pauseAllEffects();
ScriptingCore* sc =ScriptingCore::getInstance();
jsvalnsval;
JS_GetProperty(sc->getGlobalContext(), sc->getGlobalObject(),"plugin",
&nsval);
if(nsval !=JSVAL_VOID) {
sc->executeFunctionWithOwner(nsval,"onApplicationDidEnterBackground");
}
}
voidAppDelegate::applicationWillEnterForeground()
{
Director::getInstance()->startAnimation();
SimpleAudioEngine::getInstance()->resumeBackgroundMusic();
SimpleAudioEngine::getInstance()->resumeAllEffects();
ScriptingCore* sc =ScriptingCore::getInstance();
jsvalnsval;
JS_GetProperty(sc->getGlobalContext(), sc->getGlobalObject(),"plugin",
&nsval);
if(nsval !=JSVAL_VOID) {
sc->executeFunctionWithOwner(nsval,"onApplicationWillEnterForeground");
}
}
.js調(diào)用
plugin 相當(dāng)于全局變量
if(plugin){
plugin.onApplicationDidEnterBackground = function() {
cc.log(" plugin.onApplicationDidEnterBackground11.");
};
plugin.onApplicationWillEnterForeground = function() {
cc.log("plugin.onApplicationWillEnterForegro11und.");
};
}
研究
1.眼下能執(zhí)行的腳本僅僅有 hello.js 自己創(chuàng)建的腳本不能被執(zhí)行。
2. js --> c++ 和 c++ --> js 時候參數(shù)的傳遞
3. 用 js 寫的界面和 c++ 的界面來回切換
7.cocos2dx源代碼實現(xiàn) JSB
在cocos2dx源代碼里加入自己的實現(xiàn)方法。cocos2d-html5僅僅是方便開發(fā)。
以cc.FileUtils.getInstance() 加入自己的方法為樣例
1.js_cocos2dx_auto.hpp
JSBooljs_cocos2dx_CCFileUtils_woTest(JSContext*cx,uint32_targc,jsval*vp);
測試方法
2.js_cocos2dx_auto.cpp
voidjs_register_cocos2dx_CCFileUtils(JSContext*cx,JSObject*global) { 找到這種方法
JS_FN("woTest",js_cocos2dx_CCFileUtils_woTest,1,JSPROP_PERMANENT|JSPROP_ENUMERATE),//加入
}
新創(chuàng)建的方法
JSBooljs_cocos2dx_CCFileUtils_woTest(JSContext*cx,uint32_targc,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::stringret = cobj->woTest();
jsvaljsret;
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
virtualstd::stringwoTest() =0;
4.不同平臺
ios平臺
CCFileUtilsIOS.h
virtualstd::stringwoTest();
CCFileUtilsIOS.mm
std::stringCCFileUtilsIOS::woTest()
{
std::stringavailMemo ="";
returnavailMemo;
}
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::stringwoTest();
Cocos2dxActivity.java
public static StringwoTest(){
return Long.toString(123);
}
5.調(diào)用
cc.FileUtils.getInstance().woTest();
其他 jsb 綁定可參考 cocos2dx源代碼
總結(jié)
- 上一篇: error C3861: “getpid
- 下一篇: .net 学习官网