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, 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));
    }
}

这次要写的更多了。

 

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

                   var animationKoo =ls.AnimationKoo.create();

                   animationKoo.funcTest();

 

输出binding test...,成功


郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。