一、总原则:c++对象的生命期不依赖lua gc管理,手动创建的对象要手动销毁

二、引擎层在设计上就是支持脚本概念的(也就是说脚本的使用是“侵入式”的),与lua打交道的代码都封在CCLuaEngine,引擎各处模块都通过它来调用脚本,如CNode::update会调用CCLuaEngine->executeSchedule来调用脚本的update handler,再如CNode::onEnter/onExit/onCleanup等都会调用CCLuaEngine->executeNodeEvent来调用脚本的event handler。

三、lua脚本封装模块:

  scripting/lua/tolua:

    这是tolua++自己的运行层代码,各种基础函数,用来操作c++数据与lua数据

  scripting/lua/lua|luajit:

    这是lua和luajit的源码

  scripting/lua/cocos2dx_support/tolua_fix.h|c:

    这是cocos2d为实现自定义数据类型操作而添加的tolua扩展代码,具体见下

  scripting/lua/cocos2dx_support/LuaCocos2d.h|cpp:

    由tolua++解析pkg文件生成的粘合代码,几万行,包括了大量要导出的cocos2d逻辑类

  scripting/lua/cocos2dx_support/CLuaEngine/Value/Stack/Bridge.h|cpp:

    这些都是cocos2d自己处理与lua虚拟机交互的类了

  scripting/lua/cocos2dx_support/Lua_web_socket/Lua_extensions_CCB/CCBProxy.h|cpp:

    这些看起来像是各种扩展库的粘合代码,与LuaCocos2d.h性质一样,但是是手写的,至于为什么用这种形式,有什么特殊的地方,我还没搞清楚。

四、每个c++对象在lua里以一个userdata表示,这个userdata上绑定了很多重要信息,如对象的类型,所有方法都是挂在类型上的。当多次将同一个c++ obj返回给lua时,为了避免创建多个不同的userdata,用了一个弱表来记录所有已进入过脚本的obj,即 objmap[ptr]=obj-userdata,第二次返回同一对象时查表可得。但由于这是一个弱表,里面的表项不是永久存在的,这极易引发一个经典bug:

local spt = CCSprite:create("ui/green_btn.png")

spt:setPosition(320,100);

base_layer:addChild(spt)

base_layer:registerScriptTouchHandler(function(et,x,y)

  --gc()

  --gc()

  local children = base_layer:getChildren()

  local cnt = children:count()

  for i=0,cnt-1 do

    local c = children:objectAtIndex(i)

    print("child ",i,tostring(c))

    local s = c:getContentSize()

    。。。

  end

end)

  spt做为局部对象,在外层函数返回后就失去引用了,虽然它代表的c++ obj通过addChild的方式被其parent(也就是base_layer)引用住了,但是在脚本里这个类型为CCSprite的userdata一旦被gc后,在上述事件响应函数里通过children:objectAtIndex(i)再次获取该c++ obj时,因为在弱表里找不到记录,就会重新生成userdata,而这一次userdata的类型为CCObject!在它上面调getContentSize显然是找不到的。通常这种错误会因为gc的非即时性而掩盖一时,等到报错的时候反让人摸不着头脑了。测试的方法很简单,在获取对象之前强制gc一次,那么下面的代码当场就会报错了。

  解决的办法,要么把spt记在其它对象身上关联起来不被gc,要么在每次获取时,执行强制类型转换(但跟c++层的dynamic_cast一样易出弊端):

  c = tolua.cast(c,"CCNode")

……

待续

注:以上结论是错的,纯属未认真读代码就想当然了(主要是以前我自己做封装的时候是这么搞)。关于cocos2dx-lua里对象的生命期,请见我后面更新的文章(那个是认真读过代码后写的了。。。)

cocos2dx之lua绑定简析的更多相关文章

  1. cocos2dx的lua绑定

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

  2. cocos2dx 关于lua 绑定的环境配置官方文档翻译与 将自己定义c++方法绑定到lua的的方法

    网上有好多写如何讲自己定义的方法绑定到lua的文章,当中都仅仅对环境配置做了简单的介绍,看到有的帖子写在绑定中遇到了各种各样的error.大部分是因为环境配置不对导致的,下面是官方的文档有标准的说明, ...

  3. cocos2dx v3.x lua绑定分析

    打算新项目转到cocos2dx v3上了,下载代码浏览过后发现改动真是非常大,结构性调整很多. 比如tolua绑定这一块,就几乎全翻新了. 胶水代码的生成,改成了全自动式的,通过clang来分析c++ ...

  4. 【转】Cocos2d-x下Lua调用自定义C++类和函数的最佳实践

    转自:http://segmentfault.com/blog/hongliang/1190000000631630 关于cocos2d-x下Lua调用C++的文档看了不少,但没有一篇真正把这事给讲明 ...

  5. cocos2d-x lua绑定解析

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

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

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

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

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

  8. win7系统cocos2dx 3.4 绑定自定义类到Lua

    Cocos2d-x 3.0开始使用bindings-generator来生成c++类的lua绑定.bindings-generator基于tolua++,通过配置tools/tolua中的ini文件以 ...

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

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

随机推荐

  1. DEV开发之控件XtraTabbedMdiManager

    使用的时候要先设置窗体的IsMdiZContainer属性为True然后再窗体上新增XtraTabbedMdiManager控件 设置属性:HeaderLocation为bottomClosePage ...

  2. leetcode 889. Spiral Matrix III

    On a 2 dimensional grid with R rows and C columns, we start at (r0, c0) facing east. Here, the north ...

  3. java入门了解14

    GUI 1.分类: 一.AWT(Abstract Window Toolkit):抽象窗体工具集 java.awt.*适合做简单的图像用户界面,复杂的不行,基于底层操作系统,所以不同的操作系统显示的界 ...

  4. stdcall、cdecl详解(以及WINAPI和CALLBACK之类的宏对应什么)

    转自:http://blog.csdn.net/huanjieshuijing/article/details/5822942 对_stdcall 的理解在C语言中,假设我们有这样的一个函数:int ...

  5. Kafka- Kafka架构功能

    Kafka是一个高吞吐量的分布式消息系统,一个分布式的发布-订阅消息系统.Kafka是一种快速,可拓展的,设计内在就是分布式的,分区的可复制的提交日志服务. Apache Kafka与传统消息系统相比 ...

  6. 用 CSS3 创建一个漂亮的多种色彩的菜单

    1. [图片] thumb.png ​2. [代码][HTML]代码 <!DOCTYPE html><html lang="en" >    <hea ...

  7. POJ 2421 Constructing Roads(Kruskal算法)

    题意:给出n个村庄之间的距离,再给出已经连通起来了的村庄.求把所有的村庄都连通要修路的长度的最小值. 思路:Kruskal算法 课本代码: //Kruskal算法 #include<iostre ...

  8. GeoServer基础教程(二):GeoServer的Web管理界面快速入门

    转载:http://blog.163.com/daimiao_study/blog/static/248923117201542522742373/ GeoServer的控制和管理是基于网页形式,所有 ...

  9. Git_错误_02_error: src refspec master does not match any

    现象:在一个目录下初始化仓库之后,就开始push到github,结果出现了这个错误. 错因:初始化仓库之后,并没有使用git add,git commit 命令将文件添加到git仓库中,所以仓库为空, ...

  10. hdu Digital Square(广搜)

    题目:给出n,求出最小的m,满足m^2  % 10^k = n,其中k=0,1,2 http://acm.hdu.edu.cn/showproblem.php?pid=4394 只要有一个x满足条件便 ...