6------cocos2dx-------3.3<LUA>官网英文版
来源:互联网 发布:颈椎牵引器 淘宝 编辑:程序博客网 时间:2024/06/03 19:08
LUA
version: Cocos2d-x v3.3 and higher
- Lua
- Call custom c++ from Lua
- Call the class member function
- Call global functions
- Call OpenGL functions
- Bind a c++ class to lua by bindings-generator automatically
- Create a custom class
- Add a new cocos2dx_custom.ini file
- Subclassing
- Memory Management
- Simple Test Case
- Memory Management for Class Object
- The Class Members of Ref Class for Memory Management
- Create a Ref object from Lua
- The Release of the Userdata
- Memory Management for Lua Callback Function
- Add a reference for Lua Callback Function
- Remove a reference for Lua Callback Function
- References
- Call custom c++ from Lua
Call custom c++ from Lua
Cocos2d-x lua binds c++ classes, class functions, enums and some global functions to lua by using the bindings-generator (tools/bindings-generator) and by manual bindings. This allows you to call custom c++ from lua conveniently.
Call the class member function
Open lua-empty-test/src/hello.lua
and you will see many function calls like cc.***
. They are actually calling the class member functions. This is the initGLView
function:
The relationship between lua function call and the c++ function call as follow:
From this table, we can see that the functions called in lua are very similar with the functions called in c++. These are some key points that we need to pay attention to:
cc
is a module name like namespace name in c++,it is cocos2d-x 3.0 new features. The relation between lua modules and c++ namespaces is as follow:
- static and non-static c++ functions are called in lua using
:
cc.ResolutionPolicy.NO_BORDER
corresponds toResolutionPolicy::NO_BORDER
which is enum value in the c++.enum
values are bound to lua by manual.
Different modules use different lua files to keep the bindings value:
- For some functions, their parameters include
cocos2d::Vec2
,cocos2d::Vec3
we should do a conversion to call c++ function.For example:
In c++, we should call this function like this:
In lua, we should call the function like this:
cc.p(0.0, 0.0)
is to construct an anonymous table like this {x = 0, y =0}
The other parametric types that should be converted are:
Call global functions
cocos2d-x v3 also binds some global functions to lua manually, such as kmGLPushMatrix
,kmGLTranslatef
and kmGLLoadMatrix
. We can call these global functions in lua as follows:
Call OpenGL functions
cocos2d-x v3 binds some OpenGL functions to lua. All the OpenGL functions are in the gl
module and can be called as follows:
You can refer to lua-tests/DrawPrimitiveTest
and lua-tests/OpenGLTest
for more information.
Bind a c++ class to lua by bindings-generator automatically
Since cocos2d-x v3.0, there is a tools called bindings-generator to bind c++ class to lua automatically.
The bindings-generator is based on tolua++. There is an ini file in the tools/tolua
directory and then run the genbindings.py script to generate the binding code.
Create a custom class
Consider this code:
Note:
- the cpp file was omitted because the bindings-generator only scan the header files
- The custom class should be inherited from the
Ref
class, this is mainly due to the destructor ofRef
callingremoveScriptObjectByObject
to reduce the reference count of userdata which gets created in the c++ automatically to avoid memory leak.
Add a new cocos2dx_custom.ini file
In tools/lua folder create a new file named cocos2dx_custom.ini as:
All of the config files under tools/tolua use the same format. Here is a list which you should consult when writing your own ini file:
- [title]: To config the title which will by used by the tools/tolua/gengindings.py scripts. Generally, the title could be the file name.
- prefix: To config the prefix of a function name, generally, we also use the file name as the prefix.
- target_namespace: To config the module name in lua. Here we use the
cc
as the module name, when you want to useCustomClass
in lua, you must put a prefix namedcc
in front of the name. For example, theCustomClass
could be reference ascc.CustomClass
. - headers: To config all the header files needed for parsing and the %(cocosdir)s is the engine root path of cocos2d-x.
- classes: To config all the classes needed to bind. Here it supports regular expression. So we could set MyCustomClass.* here. For looking more specified usage, you could ref to
tools/tolua/cocos2dx.ini
. skip: To config the functions needed to be omit. Now the bindings-generator can't parse
void*
type and also the delegate type, so these types needed to be bind manually. And at this circumstance, you should omit all these types first and then to bind them manually. You could ref to the config files under pathcocos/scripting/lua-bindings/auto
.rename_functions: To config the functions need to be renamed in the scripting layer. Due to some reasons, developers want more scripting friendly API, so the config option is for this purpose.
rename_classes: Not used any more.
remove_prefix: Not used any more.
classes_have_no_parents: To config the parent class needed to be filter. This option is seldom modified.
abstract_classes: To config the classes whose public constructor don't need to be exported.
script_control_cpp:yes. To config whether the scripting layer manage the object life time or not. If no, then the c++ layer cares about their life time. Now, it is imperfect to control native object's life time in scripting layer. So you could simply leave it to no.
Subclassing
Sometimes we want to add some new functions to extend the bindings, think inheritance in c++. Through class(classname, super)
function in the cocos/scripting/lua-bindings/script/cocos2d/extern.lua
, we can realize this requirement easily. The details function are as follow:
Through this function, we can see inheritance easily. Example, if we want to derive from cc.Node
:
- Define a subclass by
class
function
- Create a object of subclass and use it:
Note: new
is implemented by default in the class
function. Since the type of the second parameter is function
, when we call new
, this is what happens:
The object created by new
have all the properties and behaviors of the cc.Node
object. It also has the properties of the SubNode
as it is derived from cc.Node
:
If we still need to call the function of the same name of super class:
- The override functions of inherited class in lua can't be called in the c++.
Memory Management
Cocos2d-x v3.x uses the memory management and garbage collection of lua itself except the release of userdata
. If the corresponding classes are derived from Ref
the release of userdata
is managed in c++ by the register table namedtoluafix_refid_ptr_mapping
and tolua_value_root
.
Simple Test Case
Create a
Sprite
in the head ofcreateDog
functionThen call the
Sprite
in thetick
function as follow:After a period of time, we will see the error message as follows:
This error is triggered because the testsprite didn't add any other node as a child after creation. The corresponding c++ object was released at the end of the frame.
Memory Management for Class Object
The Class Members of Ref Class for Memory Management
In CCRef.h
we see the usage of CC_ENABLE_SCRIPT_BINDING
:
Notice _ID
and _luaID
, are very important when you push a Ref
object to lua by callingtoluafix_pushusertype_ccobject
to store a key-value table named toluafix_refid_ptr_mapping
in the registry. The _ID
is key and the related c++ object pointer is value. The related code fragment in the toluafix_pushusertype_ccobject
is:
Notes:
TOLUA_REFID_PTR_MAPPING
is macro definition represent for "toluafix_refid_ptr_mapping"LUA_REGISTRYINDEX
is definition ofPseudo-Index
for registry of Luarefid
is value of_ID
vPtr
is value of related c++ object pointer
Create a Ref object from Lua
Call the
cocos2d::Sprite::create("res/land.png")
by lua bindings to create a Sprite object and push it into lua stack:Call
toluafix_pushusertype_ccobject
when push created object to lua stack
In the toluafix_pushusertype_ccobject
, we will use two tables named "toluafix_refid_ptr_mapping" and "toluafix_refid_type_mapping" in lua's registry to store the two key-value pairs about _ID
-object pointer
and _ID
-object type name
.The details are as follow:
- Call
tolua_pushusertype_internal
to determine whether to create a new userdata, or just update the userdata.
We use a table named ubox
to store key-value pairs about userdata
and object pointer
. This table would be used in the destruction of the object.
- Call
tolua_add_value_to_root
to add a reference count foruserdata
in lua by thetolua_value_root
table in lua registry. The mechanism will make the object in lua wouldn't collected by lua gc. Example:lua local node = cc.Node:create() node.extendValue = 10000 nodeParent:addChild(node, 0 , 9999)
This code creates anode
object and extends the attributes of the node object dynamically by lua's feature. When we want to get this node and its extended attribute somewhere, we can do as follows:lua local child = lnodeParent:getChildByTag(9999) print(child.extendValue)
If we don't call the tolua_add_value_to_root
, the result of print(child.extendValue)
would be uncertain. Sometimes the result would be 10000 and sometimes it would be nil
. This is because we wouldn't control lua's automatic gc effectively. When lua gc thinks there are no other references for this userdata it will collect this userdata. When we call getChildByTag
to get a node object, it would create a new userdata and the extended attributes would disapper. We add a reference count for the userdata tolua_value_root
table in lua registry in the c++ to avoid generating this error.
The Release of the Userdata
When calling the desturctor of Ref
, it will trigger the release of the userdata.
In the destructor of Ref, we can see:
After we push a c++ object to lua, the related _luaID would be not 0. We now can callremoveScriptObjectByObject
The removeScriptObjectByObject
called would trigger the call oftoluafix_remove_ccobject_by_refid
, and this function would call some lua c APIs to operate the table like toluafix_refid_ptr_mapping
, toluafix_refid_type_mapping
and tolua_value_root
table in the registry.
The specific implementation of toluafix_remove_ccobject_by_refid
is as follows:
The steps are as follows:
Get related object pointer stored in the
toluafix_refid_ptr_mapping
table by the value of_luaID
. Store it.Remove reference relationship of the object pointer from
toluafix_refid_ptr_mapping
table by_luID
Get related type name stored in the
tolua_refid_type_mapping
table by the value of_luaID
,then store itRemove reference relationship of type name from
tolua_refid_type_mapping
table by_luID
Get the related metatable by the type name
Get the
ubox
tableRemove reference relationship of userdata from
tolua_value_root
table by the object pointer got in the upper stepClean userdata and remove reference relationship of uesrdata from
ubox
by the object pointer got in the upper step.Note:To destroy a object cited by lua, we only called '*ud = NULL;'
Through the above steps,the refernce relationships in thetoluafix_refid_ptr_mapping
、tolua_refid_type_mapping
and tolua_refid_type_mapping
table in the registry would be removed, release the userdata
which is created when push c++ object to lua stack, and when lua gc trigger, the related object would be collected if there is no other place refer
to it.
Memory Management for Lua Callback Function
Cocos2dx have been used toluafix_refid_function_mapping
table in the registry to manage the gc of lua callback function
Add a reference for Lua Callback Function
When we define a lua function which would be called throuch c++ codes, we whould store the pointer of this function in the toluafix_refid_function_mapping
table by calling toluafix_ref_function
function in the tolua_fix.cpp
.Cocos2d-x bound
a series of functions like registerScriptHandler
and addEventListener
to finish this work.
Let's use registerScriptHandler
of Node
as a sample,we could use it as follows in lua:
The related bindings function is named tolua_cocos2d_Node_registerScriptHandler
in thelua_cocos2dx_manual.cpp
,the most important sections are as follows:
toluafix_ref_function
is implemented to store the related function pointer intotoluafix_refid_function_mapping
table in the registry with a static variable nameds_function_ref_id
.This operation makes lua function avoid being collected by lua gc because thattoluafix_refid_function_mapping
table have a reference of this function. The details are as follow:
addObjectHandler
is used to stored the map of object pointer and pair ofs_function_ref_id
and handler type.
Remove a reference for Lua Callback Function
If lua callback function become useless, we should remove the reference in thetoluafix_refid_function_mapping
table in the registry. Cocos2d-x provided thetoluafix_remove_function_by_refid
function to realize it. This function could be called byremoveScriptHandler
of LuaStack
、removeScriptHandler
of LuaEngine
or directly. The details are as follows:
Note:
refid
is the corresponding value ofs_function_ref_id
.- For Ref object,we would call
ScriptHandlerMgr::getInstance()->removeObjectAllHandlers
to remove all the reference function relationship which added by theScriptHandlerMgr::getInstance()->addObjectHandler
automatically - Because Cocos2d-x v3.x support the features of c++ 11, we can call the related remove function through the lambda function. For example:
By the mechanism of the lambda, we could get the value of handler which represents the corresponding value of s_function_ref_id
. When we finish calling lua callback function,we could call LuaEngine::getInstance()->removeScriptHandler(handler)
directly to remove the reference of lua callback function.
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
官网的文档,拿过来看看。
原文链接:http://www.cocos2d-x.org/wiki/Lua
- 6------cocos2dx-------3.3<LUA>官网英文版
- Cocos2dx(3.3)绑定lua
- 【cocos2dx 3.3 lua】09 lua配置文件读写
- cocos2dx 3.3 lua 绑定类
- 【Cocos2dx 3.3 Lua】定时器事件
- cocos2dx lua
- cocos2dx+lua
- cocos2dx-lua
- Cocos2dx lua
- [cocos2dx lua]cocos2dx lua入门
- [cocos2dx笔记018]cocos2dx 2.2.6 lua版控件回调
- quick-cocos2dx cocos2dx.lua
- lua: cocos2dx lua 加密
- [cocos2dx笔记017]cocos2dx 2.2.6 lua的类型转换
- cocos2dx 3.3 Lua 实现倒计时功能
- quick-cocos2dx 3.3 c++绑定到Lua
- cocos2dx 3.3 scrollView lua 版本幻灯片效果
- 【cocos2dx 3.3 lua】05 环绕倒计时效果
- android studio降低编译版本出错
- CCLuaObjcBridge - Lua 与 Objective-C 互操作的简单解决方案
- MAC下 查看隐藏文件
- Android高效加载大图、多图解决方案,有效避免程序OOM
- 自定义View系列教程02--onMeasure源码详尽分析
- 6------cocos2dx-------3.3<LUA>官网英文版
- 【Algothm】动态规划实例6
- 剑指offer|从上往下打印二叉树
- Android_关于Activity的生命周期及一些理解
- Android 图片选择器
- Ryan的OC学习总结-----9 Foundation框架
- emacs中出现调用wakatime的错误
- Python 键盘鼠标监听
- 支付宝和微信移动支付的个人总结