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...,成功

时间: 2024-08-28 18:37:47

Cocos2d-x-3.x版 Js Binding 的手动绑定实现的相关文章

[cocos2dx笔记008]cocos2d 用luabridge手动绑定类

基于cocos2dx 2.2.2版本.这几天使用了cocostudio实现了,动画,骨骼动画,UI编辑,粒子效果,虽然有些不足,但已经算是非常好了.今天尝试用lua,这个非常简单,创建的时候,设置语言为lua,那就可以创建lua工程. 在cocos2d-x-2.2.2\tools\project-creator下运行: python create_project.py -project test_lua -package com.android.zdhsoft -language lua xco

cocos2d-js 3.0 RC0 手动绑定 C++调用js,js调用C++ jsbinding

参考:http://www.tairan.com/archives/4902 参考文章是2.x版本的,对于3.0也许不合适了,没有深究. 代码:https://github.com/kenkozheng/cocos2d-js/tree/master/jsbinding(cpp_js%20js_cpp) 1 JS调用C++ 3.0中写这个绑定比较简单,跟ANE调用java如出一辙,一个JSContext,一个jsval,使用cocos2d提供的c++和js变量转换的函数做好转换即可. cocos2

原生js实现数据双向绑定

最近接触了vue,在谈到vue等等的mvvm框架之前,先了解什么是数据双向绑定以及如何利用原生JS实现数据双向绑定 单向数据绑定 指先把模板写好,然后把模板和数据(数据可能来自后台)整合到一起形成HTML代码,然后把这段HTML代码插入到文档流里 缺点:一旦HTML代码生成就没有办法改变,如果有新数据重新传入,就必须重新把模板和数据整合到一起插入到文档流中 数据双向绑定 数据模型和视图之间的双向绑定,用户在视图上的修改会自动同步到数据模型中,同样的,如果数据模型中的值发生变化,也会同步到视图中去

原生js跨浏览事件绑定(移除)/javascript事件绑定(移除)

网上找了半天没看到,都是基于ie attachEvent(有诸多的问题存在)来写的,所以手动写了个js模拟绑定事件希望能帮到需要的童鞋 addEvent = function(obj,type,fn){  if(obj.addEventListener) {//W3C   obj.addEventListener(type,fn,false);  }else if (obj.attachEvent) {//ie(期待它的灭亡)   if(!obj.events) obj.events = {};

JS学习笔记-事件绑定

一.传统事件模型 传统事件模型中存在局限性. 内联模型以HTML标签属性的形式使用,与HTML混写,这种方式无疑造成了修改以及扩展的问题,已经很少使用了. 脚本模型是将事件处理函数写到js文件中,从页面获取元素进行对应事件函数的绑定以触发执行.但也存在不足之处: 1.一个事件绑定多个事件监听函数,后者将覆盖前者. 2.需要限制重复绑定的情况 3.标准化event对象 二.现代事件绑定 DOM2级事件定义了两个方法用于添加.删除事件:addEventListener().removeEventLi

Js为Dom元素绑定事件须知

为异步加载的Dom 元素绑定事件必须在加载完成之后绑定: $('body').load('LearnClickBinding.ashx');$('a').click(function () { alert('I was clicked!'); }); 上面的绑定是无效的,因为异步加载需要时间,而在获取元素之前,早已执行了$('a').click();方法,所以绑定失败. 正确的做法是,等待元素加载完后再执行 $('a').click(); $('body').load('LearnClickBi

Yii ExtendedActiveRecord 增强版 ActiveRecord 增加多数据库连接绑定功能

ExtendedActiveRecord 继承自 CActiveRecord,因此基础功能与 CActiveRecord 无异 为添加对多数据库连接的支持,增加了对 connectionName() 方法的回调,用法跟已有的 tableName() 方法一致,返回数据库连接组件名称的字符串. 如果不定义该方法,则使用默认数据库连接(db) 源码如下: class ExtendedActiveRecord extends CActiveRecord { public static $db = ar

WPF Binding学习(四) 绑定各种数据源

1.集合作为数据源 首先我们先创建一个模型类 public class Student { public int ID { get; set; } public String Name { get; set; } } 然后我们创建我们的页面布局 <StackPanel Width="300" Height="300" HorizontalAlignment="Left"> <ListView Name="listVie

解决pjax重复加载js导致事件重复绑定的问题

个人博客 地址:http://www.wenhaofan.com/article/20180925232057 1.所有js统一在pjax容器外引入 在pjax容器外引入的js只会被引入一次,所以不会出现重复加载的问题,但是该方法仅适用于页面较少的情况,如果页面很多,那么会导致第一次访问时引入大量不一定会被适用到的js,效率低下. 2.将绑定事件和其他事件区分成两个js来引入 在pjax中判断是否已经引入绑定事件的js,如果已经引入则不再重复引入. 3.在js中添加代码判断是否已经被引入 目测采