打算新项目转到cocos2dx v3上了,下载代码浏览过后发现改动真是非常大,结构性调整很多。

比如tolua绑定这一块,就几乎全翻新了。

胶水代码的生成,改成了全自动式的,通过clang来分析c++代码,可以准确的知道每一个类、函数、参数的信息,再也不用手动写pkg文件了。

运行期对象管理这块,似乎也有了不少改动,至少我原来的一些扩展代码运行不了了,还没来得及细看,待看完再一一录下。

先记录一下目前已看清楚的【类名表、类元表、对象实例】之间的关系:

1、类元表:最核心的表,在lua代码里是不可见的。这是在注册每个类的第一步时建立的:

tolua_usertype(tolua_S,"cc.Application");

但其实类元表也就是一个普通的table,只不过它挂在lua registry上,所以说一般的逻辑代码是不会用到它的。类的所有函数、与父类的关系,也都记在这个核心的元表里。

2、类名表:这就是lua代码里要使用该类时所用的名字,也就是:

local app=cc.Application:getInstance()

里cc.Application这个变量对应的表。它是注册类的第二步中建立的:

tolua_cclass(tolua_S,"Application","cc.Application","",nullptr);

【类名表】的元表就是【类元表】。

3、对象实例:每个c++ object被push到lua里,是以一个userdata表示。它的元表被设成【类元表】,所对它调用的各种方法都会索引到相应的c++函数上。它的生成是在以下函数中完成:

void tolua_pushusertype_internal (lua_State* L, void* value, const char* type, int addToRoot)

其实在这里我不是太清楚每个类为什么要有两个表来表示,从功能上说,完全可以合为一个,也就是【类元表】上的所有功能都可以放在【类名表】里实现。也许是因为作者担心类名表存在于普通变量空间里,可能会被无意中修改覆写吧!但分开之后,也明显导致了一些后续处理上的麻烦:比如在给【模块】注册函数时,就要判断当前【模块】是一个【普通模块】(对应于c++里的名字空间)还是一个【类名表】,如果是后者,那函数不能直接挂在它上面,而是要转挂到【类元表】上去,这是在下面函数中处理的:

/* Begin module
* It pushes the module (or class) table on the stack
*/
TOLUA_API void tolua_beginmodule (lua_State* L, const char* name)
{
if (name) { // ... module
//---- now module[name] is a table, get it's metatable to store keys
// get module[name]
lua_pushstring(L,name); // ... module name
lua_rawget(L,-2); // ... module module[name]
// Is module[name] a class table?
lua_pushliteral(L, ".isclass");
lua_rawget(L, -2); // stack: ... module module[name] class_flag
if (lua_isnil(L, -1)) {
lua_pop(L, 1); // stack: ... module module[name]
return; // not a class table, use origin table
}
lua_pop(L, 1); // stack: ... module class_table
// get metatable
if (lua_getmetatable(L, -1)) { // ... module class_table mt
lua_remove(L, -2); // ... module mt
}
//---- by SunLightJuly, 2014.6.5
} else {
lua_pushvalue(L,LUA_GLOBALSINDEX);
}
}

同时这个修改也导致了我之前的一些代码运行失效。因为我会给一些类添加扩展函数,如:

rawset(ccui.Widget,"set_enable", function(self, v)
  self:setTouchEnabled(v)
  self:setBright(v)
end

按上述逻辑,实例对象的元表直接指向类元表,也就是说完全绕过了类名表(类名表实际只在创建对象时起个提供类变量的引子作用),而rawset在类名表上的扩展函数自然也被忽略了。

修改办法也很简单,去掉rawset,直接往类名表上写就行了,这会导致其通过元表上的class_newindex_event函数,把数据改记到类元表上,从而符合了实例对象的属性访问流程。

至于之前为什么用一个rawset多此一举?那也是无奈之法,因为上一版本的cocos2dx在lua绑定实现上就是有点问题,不用rawset的话直接就挂了。所以说它现在又改好了,也算是回归自然吧。

cocos2dx v3.x lua绑定分析的更多相关文章

  1. Cocos2d-x v3.3 lua绑定c++类方法总结

    网上有很多cocos2d-x lua绑定c++类的接口教程,这篇文章也是总结他们的经验. 其中重点参考了 http://cn.cocos2d-x.org/tutorial/show?id=1295, ...

  2. 使用cocos2d-x v3.1开发小游戏(基本框架)

    小游戏的组成 欢迎界面 在游戏资源未全部加载完之前就需要载入,避免进入游戏会有一段黑屏时间. 可以用来展示游戏名称或者开发者logo. 开始菜单界面 一般用于显示游戏名称和关卡选择(或者称游戏难度选择 ...

  3. cocos2dx的lua绑定

    一.cocos2dx对tolua++绑定的修正 A.c对lua回调函数的引用 在使用cocos2dx编写游戏时,我们经常会设置一些回调函数(时钟.菜单选择等).如果采用脚本方式编写游戏的话,这些回调函 ...

  4. cocos2d-x lua绑定解析

    花了几天时间看了下cocos2d-x lua绑定那块,总算是基本搞明白了,下面分三部分解析lua绑定: 一.lua绑定主要用到的底层函数 lua绑定其本质就是有一个公用的lua_Stack来进行C和L ...

  5. cocos2dx lua 绑定之二:手动绑定自定义类中的函数

    cococs2dx 3.13.1 + vs2013 + win10 1.首先按照<cocos2dx lua 绑定之一:自动绑定自定义类>绑定Student类 2.在Student类中增加一 ...

  6. cocos2dx lua 绑定之一:自动绑定自定义类中的函数

    cococs2dx 3.13.1 + vs2013 + win10 1.首先定义C++类Student 在cocos2d-x\cocos文件夹下新建一个user_define的文件夹放置两个文件. 注 ...

  7. 开源基于lua gc管理c++对象的cocos2dx lua绑定方案

    cocos2dx目前lua对应的c++对象的生命周期管理,是基于c++析构函数的,也就是生命周期可能存在不一致,比如c++对象已经释放,而lua对象还存在,如果这时候再使用,会有宕机的风险,为此我开发 ...

  8. Cocos2d-x v3.6制作射箭游戏(二)

    原文 Cocos2d-x v3.6制作射箭游戏(二) 六 24, 2015by RENSHANin COCOS2D-X 上章我们创建并加载了游戏地图,接下来的两章我们将实现如下的效果. 在开始之前,先 ...

  9. Cocos2D-X v3.0 alpha1环境搭建

    周末看了下Cocos2D,感觉用起来还是挺爽的样子,跨平台,支持Windows, Linux, Mac, IOS, Android,WP...N多平台..还是C++开源滴,果断下下来研究下.. 最新版 ...

随机推荐

  1. 【leetcode刷题笔记】Reverse Nodes in k-Group

    Given a linked list, reverse the nodes of a linked list k at a time and return its modified list. If ...

  2. stm32非操作系统开发和带uCos的开发的区别,及一些解析

    从文件角度来看core_cm4.h和stm32f4xx.h分别从内核寄存器和外设寄存器来定义其地址和结构体,是用c语言访问硬件必须的文件,所以这两个文件不论是否带操作系统,都是必须包含进工程的. re ...

  3. P3988 [SHOI2013]发牌

    题目 P3988 [SHOI2013]发牌 做法 我们切牌时的状态: 手玩几次后我们发现切\(K\)次牌就是求堆顶一下的\(K+1\)大值,套上主席树就好了 My complete code #inc ...

  4. django使用html模板减少代码

    看下面两个页面: —————————————————————————————————————————————————————————————————————————————————— 一个显示文章列表 ...

  5. django admin后台显示H5颜色选项卡

    一般使用django后台,特别是有颜色的字段的时候避免手动输入一大推的颜色,可以使用h5颜色选项卡,这样用户就直接可以通过选项卡来选择自己所需的颜色.这个时候可以通过后台admin form来进行定制 ...

  6. Java企业微信开发_07_JSSDK多图上传

    一.本节要点 1.1可信域名 所有的JS接口只能在企业微信应用的可信域名下调用(包括子域名),可在企业微信的管理后台“我的应用”里设置应用可信域名.这个域名必须要通过ICP备案,不然jssdk会配置失 ...

  7. jquery 整理笔记(一)

    this:表示当前的上下文对象是一个html对象,可以调用html对象所拥有的属性,方法 $(this),代表的上下文对象是一个jquery的上下文对象,可以调用jquery的方法和属性值. each ...

  8. Oracle--存储过程和自定义函数

    一.相关概念 1.存储过程和存储函数 ~指存储在数据库中供所有用户程序调用的子程序 ~存储过程和存储函数的相同点:完成特定功能的程序 ~存储过程和存储函数区别:是否用return语句返回值 2.创建和 ...

  9. Json解析方式

    http://blog.sina.com.cn/s/blog_628cc2b70101dydc.html

  10. ffmpeg捕捉摄像头发送rtmp

    打印 DirectShow 支持的设备列表(true 可用1替换): ffmpeg -list_devices true -f dshow -i dummy 本计算机打印出的信息如下:[dshow @ ...