Cocos2d-x-3.x版 Js Binding 的手动绑定实现

网上流传的是一份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,jsval *vp);
bool  js_cocos2dx_AnimationkooFuncTest_getDescription(jscontext *cx,jsval *vp);
bool  js_cocos2dx_Animationkoo_constructor(jscontext *cx,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,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,vp);
    args.rval().setBoolean(true);
    return true;    
}

bool js_cocos2dx_AnimationkooFuncTest_getDescription(jscontext *cx,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,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,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,"_ctor",&ok) && ok)
        Scriptingcore::getInstance()->executeFunctionWithOwner(OBJECT_TO_JSVAL(obj),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,JS_FS_END
    };

    static JSFunctionSpec st_funcs[] = {
        JS_FN("create",js_cocos2dx_Animationkoo_create,JS_FS_END
    };

    jsb_LsLeafsoar_prototype = JS_InitClass(
        cx,global,JS::NullPtr(),// parent proto
        jsb_LsLeafsoar_class,js_cocos2dx_Animationkoo_constructor,// 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,"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));
    }
}

这次要写的更多了。

离成功就差一步了。cocos2d js中测试

var animationKoo =ls.AnimationKoo.create();

animationKoo.functest();

输出binding test...,成功

相关文章

    本文实践自 RayWenderlich、Ali Hafizji 的文章《...
Cocos-code-ide使用入门学习地点:杭州滨江邮箱:appdevzw@1...
第一次開始用手游引擎挺激动!!!进入正题。下载资源1:从C...
    Cocos2d-x是一款强大的基于OpenGLES的跨平台游戏开发...
1.  来源 QuickV3sample项目中的2048样例游戏,以及最近《...
   Cocos2d-x3.x已经支持使用CMake来进行构建了,这里尝试...