Cocos2d-x-3.x版 Js Binding 的手动绑定实现
来源:程序员人生 发布时间:2015-04-13 08:42:52 阅读次数:3888次
网上流传的是1份2.x版本的,现在已更新到3.x,经过千辛万苦,终究调试成功。
1 .首先定义待绑定的类
AnimationKoo.h
#ifndef __AnimationKoo_H__
#define __AnimationKoo_H__
namespace ls{
class AnimationKoo{
public:
virtual void funcTest();
static AnimationKoo * create();
};
}
#endif // __AnimationKoo_H__
AnimationKoo.cpp
#include "cocos2d.h"
#include "cocos2d_specifics.hpp"
#include " AnimationKoo.h"
void ls::AnimationKoo::funcTest(){
CCLOG("binding test...");
}
ls::AnimationKoo * ls::AnimationKoo::create()
{
AnimationKoo * ret = new AnimationKoo();
return ret;
}
定义类在ls命名空间,我们测试funcTest方法
2,添加绑定代码到AppDelegate 的类
在applicationDidFinishLaunching方法里面,添加sc->addRegisterCallback(register_all_ls);//手动绑定的类
编写 jsb_ls_auto.h ,以下
#include "jsapi.h"
#include "jsfriendapi.h"
#include "ScriptingCore.h"
void js_register_ls_Animationkoo(JSContext* cx, JS::HandleObject global);
void js_cocos2d_Animationkoo_finalize(JSFreeOp *fop, JSObject *obj);
bool js_cocos2dx_Animationkoo_create(JSContext *cx, uint32_t argc, jsval *vp);
static bool js_is_native_obj(JSContext *cx, uint32_t argc, jsval *vp);
bool js_cocos2dx_AnimationkooFuncTest_getDescription(JSContext *cx, uint32_t argc, jsval *vp);
bool js_cocos2dx_Animationkoo_constructor(JSContext *cx, uint32_t argc, jsval *vp);
void register_all_ls(JSContext* cx, JS::HandleObject obj);
没错,就是这么坑爹,需要写这么多东西。
下面是它的实现
jsb_ls_auto.cpp
#include "cocos2d.h"
#include "koogame/Animationkoo.h"
#include "jsapi.h"
#include "jsb_ls_auto.h"
#include "cocos2d_specifics.hpp"
// 定义 js 真个类型
JSClass *jsb_LsLeafsoar_class;
JSObject *jsb_LsLeafsoar_prototype;
// 实现 ls 命名空间下的类绑定
void register_all_ls(JSContext* cx, JS::HandleObject obj) {
JS::RootedObject ns(cx);
get_or_create_js_obj(cx, obj, "ls", &ns);
// 实现绑定 Leafsoar 类,它的定义后文给出
js_register_ls_Animationkoo(cx, ns);
}
void js_cocos2d_Animationkoo_finalize(JSFreeOp *fop, JSObject *obj) {
CCLOGINFO("jsbindings: finalizing JS object %p (Node)", obj);
}
bool js_cocos2dx_Animationkoo_create(JSContext *cx, uint32_t argc, jsval *vp)
{
JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
if (argc == 0) {
ls::AnimationKoo* ret = ls::AnimationKoo::create();
jsval jsret = JSVAL_NULL;
do {
if (ret) {
js_proxy_t *jsProxy = js_get_or_create_proxy<ls::AnimationKoo>(cx, (ls::AnimationKoo*)ret);
jsret = OBJECT_TO_JSVAL(jsProxy->obj);
} else {
jsret = JSVAL_NULL;
}
} while (0);
args.rval().set(jsret);
return true;
}
JS_ReportError(cx, "js_cocos2dx_Animationkoo_create : wrong number of arguments");
return false;
}
static bool js_is_native_obj(JSContext *cx, uint32_t argc, jsval *vp)
{
JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
args.rval().setBoolean(true);
return true;
}
bool js_cocos2dx_AnimationkooFuncTest_getDescription(JSContext *cx, uint32_t argc, jsval *vp)
{
JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
JS::RootedObject obj(cx, args.thisv().toObjectOrNull());
js_proxy_t *proxy = jsb_get_js_proxy(obj);
ls::AnimationKoo* cobj = (ls::AnimationKoo *)(proxy ? proxy->ptr : NULL);
JSB_PRECONDITION2( cobj, cx, false, "js_cocos2dx_Node_getDescription : Invalid Native Object");
if (argc == 0) {
cobj->funcTest();
/*
std::string ret = cobj->funcTest();
jsval jsret = JSVAL_NULL;
jsret = std_string_to_jsval(cx, ret);
args.rval().set(jsret);
*/
return true;
}
JS_ReportError(cx, "js_cocos2dx_Node_getDescription : wrong number of arguments: %d, was expecting %d", argc, 0);
return false;
}
bool js_cocos2dx_Animationkoo_constructor(JSContext *cx, uint32_t argc, jsval *vp)
{
JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
bool ok = true;
ls::AnimationKoo* cobj = new (std::nothrow) ls::AnimationKoo();
cocos2d::Ref *_ccobj = dynamic_cast<cocos2d::Ref *>(cobj);
if (_ccobj) {
_ccobj->autorelease();
}
TypeTest<ls::AnimationKoo> t;
js_type_class_t *typeClass = nullptr;
std::string typeName = t.s_name();
auto typeMapIter = _js_global_type_map.find(typeName);
CCASSERT(typeMapIter != _js_global_type_map.end(), "Can't find the class type!");
typeClass = typeMapIter->second;
CCASSERT(typeClass, "The value is null.");
// JSObject *obj = JS_NewObject(cx, typeClass->jsclass, typeClass->proto, typeClass->parentProto);
JS::RootedObject proto(cx, typeClass->proto.get());
JS::RootedObject parent(cx, typeClass->parentProto.get());
JS::RootedObject obj(cx, JS_NewObject(cx, typeClass->jsclass, proto, parent));
args.rval().set(OBJECT_TO_JSVAL(obj));
// link the native object with the javascript object
js_proxy_t* p = jsb_new_proxy(cobj, obj);
AddNamedObjectRoot(cx, &p->obj, "ls::AnimationKoo");
if (JS_HasProperty(cx, obj, "_ctor", &ok) && ok)
ScriptingCore::getInstance()->executeFunctionWithOwner(OBJECT_TO_JSVAL(obj), "_ctor", args);
return true;
}
void js_register_ls_Animationkoo(JSContext* cx, JS::HandleObject global){
jsb_LsLeafsoar_class = (JSClass *)calloc(1, sizeof(JSClass));
jsb_LsLeafsoar_class->name = "AnimationKoo";
jsb_LsLeafsoar_class->addProperty = JS_PropertyStub;
jsb_LsLeafsoar_class->delProperty = JS_DeletePropertyStub;
jsb_LsLeafsoar_class->getProperty = JS_PropertyStub;
jsb_LsLeafsoar_class->setProperty = JS_StrictPropertyStub;
jsb_LsLeafsoar_class->enumerate = JS_EnumerateStub;
jsb_LsLeafsoar_class->resolve = JS_ResolveStub;
jsb_LsLeafsoar_class->convert = JS_ConvertStub;
jsb_LsLeafsoar_class->finalize = js_cocos2d_Animationkoo_finalize;
jsb_LsLeafsoar_class->flags = JSCLASS_HAS_RESERVED_SLOTS(2);
static JSPropertySpec properties[] = {
JS_PSG("__nativeObj", js_is_native_obj, JSPROP_PERMANENT | JSPROP_ENUMERATE),
JS_PS_END
};
static JSFunctionSpec funcs[] = {
JS_FN("funcTest", js_cocos2dx_AnimationkooFuncTest_getDescription, 0, JSPROP_PERMANENT | JSPROP_ENUMERATE),
JS_FS_END
};
static JSFunctionSpec st_funcs[] = {
JS_FN("create", js_cocos2dx_Animationkoo_create, 0, JSPROP_PERMANENT | JSPROP_ENUMERATE),
JS_FS_END
};
jsb_LsLeafsoar_prototype = JS_InitClass(
cx, global,
JS::NullPtr(), // parent proto
jsb_LsLeafsoar_class,
js_cocos2dx_Animationkoo_constructor, 0, // constructor
properties,
funcs,
NULL, // no static properties
st_funcs);
// make the class enumerable in the registered namespace
// bool found;
//FIXME: Removed in Firefox v27
// JS_SetPropertyAttributes(cx, global, "Node", JSPROP_ENUMERATE | JSPROP_READONLY, &found);
// add the proto and JSClass to the type->js info hash table
TypeTest<ls::AnimationKoo> t;
js_type_class_t *p;
std::string typeName = t.s_name();
if (_js_global_type_map.find(typeName) == _js_global_type_map.end())
{
p = (js_type_class_t *)malloc(sizeof(js_type_class_t));
p->jsclass = jsb_LsLeafsoar_class;
p->proto = jsb_LsLeafsoar_prototype;
p->parentProto = NULL;
_js_global_type_map.insert(std::make_pair(typeName, p));
}
}
这次要写的更多了。
离成功就差1步了。cocos2d js中测试
var animationKoo =ls.AnimationKoo.create();
animationKoo.funcTest();
输出binding test...,成功
生活不易,码农辛苦
如果您觉得本网站对您的学习有所帮助,可以手机扫描二维码进行捐赠