Kigs框架介绍 (7/8) - Lua绑定






2.09/5 (3投票s)
一个多用途、跨平台的免费开源 C++ 框架。Lua 绑定功能
目录
引言
在本文中,我们将了解如何增强 Kigs 框架,特别是使用 Lua 增强 CoreModifiable
类。
Lua (5.3.5) 编程语言已嵌入到此框架中
为通用 Windows 平台构建进行了少量修改。
同一目录还包含 LuaIntf:C++11 和 Lua 语言之间的绑定
要了解更多关于 Lua 的信息,请访问:https://lua.ac.cn。
绑定的框架类和方法
以下是与 Lua 绑定的类及其可访问方法的列表
-
CoreModifiable
:name()
: 返回实例名称addItem(CMSP item)
: 向另一个CoreModifiable
实例智能指针 (CMSP
) 添加一个 (参见CoreModifiable
文章)removeItem(CMSP item)
: 从另一个CoreModifiable
实例智能指针 (CMSP
) 中移除一个 (参见CoreModifiable
文章)aggregateWith(CMSP item)
: 将一个CoreModifiable
实例智能指针 (CMSP
) 聚合到另一个 (参见CoreModifiable
文章)removeAggregateWith(CMSP item)
: 移除聚合 (参见CoreModifiable
文章)parents()
: 获取父项列表childs()
或items()
: 获取子项列表getSonsByType(type)
: 获取给定类型的子项列表getSonsByName(name)
: 获取给定名称的子项列表init()
: 调用CoreModifiable
的 Inituid()
: 获取实例的唯一 IDtype()
: 获取实例的确切类型isSubType(type)
: 检查实例是否为给定类型addAttribute(val)
: 添加一个动态属性,类型由给定的 val (bool
,float
,string
或vector
) 决定onEvent(method_name or Lua function,notification_name)
: 在notification_name
上添加一个观察者,以调用method_name
或直接的 Lua 函数。getByPath(path)
: 通过路径搜索实例importAsSon(filename)
: 导入给定文件,并将CoreModifiable
树添加到调用CoreModifiable
实例中emit(signal_name)
: 发出具有给定名称的信号
-
CMSP
:get()
: 获取智能指针指向的CoreModifiable
实例
-
v2f, v3f 和 v4f
: 2D、3D 或 4D 向量Dot(v1,v2)
: 静态方法,返回 v1 和 v2 的点积Cross(v1,v2)
: 静态方法,返回 v1 和 v2 的叉积 (v4f 不可用)Norm(v1)
: 静态方法,返回 v1 的范数NormSquare(v1)
: 静态方法,返回 v1 的范数的平方normalize()
: 归一化向量normalized()
: 返回归一化向量的副本copy()
: 返回向量的副本- 成员可以通过
.x
,.y
,.z
(用于v3f
和v4f
),.w
(用于v4f
) 访问 - 向量的标准运算:
* + - /
也可用
-
mat3x4
: 3 x 4 矩阵 (3D 变换矩阵)setRotationX(angle)
: 将当前矩阵设置为给定角度的 X 轴旋转矩阵setRotationY(angle)
: 将当前矩阵设置为给定角度的 Y 轴旋转矩阵setRotationZ(angle)
: 将当前矩阵设置为给定角度的 Z 轴旋转矩阵preRotateX(angle)
: 在当前矩阵的 X 轴上以给定角度预先旋转preRotateY(angle)
: 在当前矩阵的 Y 轴上以给定角度预先旋转preRotateZ(angle)
: 在当前矩阵的 Z 轴上以给定角度预先旋转postRotateX(angle)
: 在当前矩阵的 X 轴上以给定角度后置旋转postRotateY(angle)
: 在当前矩阵的 Y 轴上以给定角度后置旋转postRotateZ(angle)
: 在当前矩阵的 Z 轴上以给定角度后置旋转setScale(sx,sy,sz)
: 将当前矩阵设置为在每个轴上具有给定比例的缩放矩阵preScale(sx,sy,sz)
: 在每个轴上以给定比例预先缩放当前矩阵postScale(sx,sy,sz)
: 在每个轴上以给定比例后置缩放当前矩阵setTranslation(v)
: 将当前矩阵设置为给定v3f
向量的平移矩阵preTranslate(v)
: 用给定的v3f
向量预先平移当前矩阵postTranslate(v)
: 用给定的v3f
向量后置平移当前矩阵setRotationXYZ(aX,aY,aZ)
: 将当前矩阵设置为具有角度 aX, aY, aZ 的旋转矩阵。旋转按 X、然后 Y、然后 Z 的顺序应用setRotationZYX(aX,aY,aZ)
: 将当前矩阵设置为具有角度 aX, aY, aZ 的旋转矩阵。旋转按 Z、然后 Y、然后 X 的顺序应用preRotateXYZ(aX,aY,aZ)
: 预先旋转当前矩阵 (旋转按 X、然后 Y、然后 Z 的顺序应用)preRotateZYX(aX,aY,aZ)
: 预先旋转当前矩阵 (旋转按 Z、然后 Y、然后 X 的顺序应用)postRotateXYZ(aX,aY,aZ)
: 后置旋转当前矩阵 (旋转按 X、然后 Y、然后 Z 的顺序应用)postRotateZYX(aX,aY,aZ)
: 后置旋转当前矩阵 (旋转按 Z、然后 Y、然后 X 的顺序应用)setIdentity()
: 将矩阵设置为单位矩阵setNull()
: 将矩阵的每个成员设置为 0isIdentity()
: 如果矩阵是单位矩阵,则返回true
transformPoint(v)
: 使用当前矩阵转换给定的v3f
向量作为一个点 (应用平移)transformPoints(list_of_v)
: 使用当前矩阵转换给定列表中的每个v3f
向量作为一个点 (应用平移)transformVector(v)
: 使用当前矩阵转换给定的v3f
向量 (不应用平移)transformVectors(list_of_v)
: 使用当前矩阵转换给定列表中的每个v3f
向量 (不应用平移)copy()
: 返回当前矩阵的副本
-
核心
:ByName(name)
: 返回具有给定名称的CoreModifiable
列表ByType(type)
: 返回具有给定类型的CoreModifiable
列表GetFirstInstanceByName(name)
: 返回找到的第一个具有给定名称的CoreModifiable
实例GetModule(name)
: 返回具有给定名称的模块 (CoreModifiable
)PostNotification(name,sender,data)
: 发布具有给定名称的通知。sender 和 data 是可选的CoreModifiable
参数AddAutoUpdate(instance)
: 将给定的CoreModifiable
实例添加到自动更新机制RemoveAutoUpdate(instance)
: 从自动更新机制中移除给定的CoreModifiable
实例SID(string)
: 返回给定字符串的KigsID
(无符号整数)Connect(sender,signal,receiver,slot)
: 将CoreModifiable
发送方的信号连接到CoreModifiable
接收方的槽Disconnect(sender,signal,receiver,slot)
: 断开CoreModifiable
发送方的信号与CoreModifiable
接收方的槽的连接Import(filename)
: 导入文件名为CoreModifiable
树,并返回CMSP
根
从 Lua 访问 Kigs 框架
在 Lua 端,框架的通用功能是可用的
-- create an UIImage instance named logo (get a smart pointer)
local logoSP = CoreModifiable("logo","UIImage")
local logo=logoSP:get()
-- set CoreModifiable attributes directly
logo.Texture = "KigsHD.png"
logo.Dock = {0.5,0.5}
logo.Anchor = {0.5,0.5}
logo.Priority = 10
-- and init logo
logo:init()
CoreModifiable
属性可以直接通过其名称后跟点 '.
' 来访问。
local rotate = logo.RotationAngle
rotate = rotate + 0.1
logo.RotationAngle = rotate
绑定的方法或 CoreModifiable
方法通过经典的 Lua 方式使用 ':' (静态方法除外,静态方法应使用 '.
')
-- call CoreModifiable method "HelloFromLua" defined on target object
target:HelloFromLua()
从 Kigs 框架访问 Lua
执行 Lua 代码
可以直接从 C++ 中的文件执行一些 Lua 代码
auto lua = KigsCore::GetModule<LuaKigsBindModule>();
bool result=lua->ExecuteLuaFile("myCode.lua");
或者在导入 XML 文件时通过向实例添加 "Lua" 项来执行一些代码
<Lua N="someCode">
-- code is executed when XML file is imported
local panel=core.GetFirstInstanceByName("panel")
panel.Color={1.0,0.0,0.0}
</Lua>
或
<Lua N="someCode" V="#someCode.lua"/>
向实例添加 Lua 方法
在 XML 中,也可以将 Lua 函数 (作为 CoreModifiable
方法) 添加到 CoreModifiable
实例
<Lua N="Click">
-- here self is the current CoreModifiable
return function(self)
local currentColor=self.Color
self.Color={1.0-currentColor.x,0.0,0.0}
end
</Lua>
LuaBehaviour 类
LuaBehaviour
类用于使用 Lua 语言向实例添加功能。
序列化
最简单的方法是直接在 XML 中将此类项添加到目标实例
<Inst N="testLua" T="LuaBehaviour" Aggregate="true">
<Attr N="Script" V="#test.lua"/>
</Inst>
LuaBehaviour
必须作为聚合项添加到其父实例。
在此,"Script
" 属性的值为 "#test.lua
"。开头的 '#
' 表示要加载的文件名。因此,此处会加载 (如果找到) "test.lua" 文件,并将其内容解释为 Lua。
代码也可以作为 CDATA
嵌入到 XML 文件中
<Inst N="testLua" T="LuaBehaviour" Aggregate="true">
<Attr N="Script">
<![CDATA[
local Sample7Script = {}
Sample7Script.logo=0
function Sample7Script:init()
local logoSP = CoreModifiable("logo","UIImage")
self.logo=logoSP:get()
self.logo.Texture = "KigsHD.png"
self.logo.Dock = {0.5,0.5}
self.logo.Anchor = {0.5,0.5}
self.logo.Priority = 10
self.target:addItem(logoSP)
self.logo:init()
end
return Sample7Script
]]>
</Attr>
</Inst>
在 C++ 代码中
当然,可以使用框架代码以 "经典" 方式创建 LuaBehaviour
实例
CMSP behaviour = KigsCore::GetInstanceOf("behaviour", "LuaBehaviour");
behaviour->setValue("Script", "#ScriptOnApp.lua");
// aggregate LuaBehaviour with this
aggregateWith(behaviour);
behaviour->Init();
Lua 端语法
行为代码
Lua 代码必须是以下形式
-- you can call it whatever you want
local behaviourObjectName = { var1 = 0; var2 = "two" }
-- Insert methods here
function behaviourObjectName:doSomething(param1)
self.var1 = param1
end
return behaviourObjectName
当聚合项初始化、更新等时,"init()
", "update(current_time)
", "destroy()
", "addItem(other)
", "removeItem(other)
" 这些方法会被自动调用
在 Lua 中直接添加 CoreModifiable
Lua 方法,可以使用对象声明中的 WRAP_METHODS
表。
-- reset is wrapped so C++ can call directly the reset method on target object
local Sample7Script = { logo=0; startingTime=0; WRAP_METHODS = {"reset"}; }
-- the reset method
function Sample7Script:reset(current_time)
self.startingTime = current_time
end
或者直接在 `init` 函数中向目标对象添加 Lua 函数
function Sample7Script:init()
-- add reset function to target
self.target.reset = function (current_time)
self.startingTime = current_time
end
end
因此,在 C++ 端,可以像调用其他 CoreModifiable
方法一样调用 Lua 的 reset
方法
// instance is the object aggregated with LuaBehaviour
instance->SimpleCall("reset",GetApplicationTimer()->GetTime());
从 LuaBehaviour 访问 CoreModifiable 实例
LuaBehaviour
函数可以使用 self.target
来访问聚合到 LuaBehaviour
的 CoreModifiable
实例
-- create an UIImage instance named logo (get a smart pointer)
local logoSP = CoreModifiable("logo","UIImage")
-- then add logo (smart pointer) to target
self.target:addItem(logoSP)
LuaImporter 类
也可以使用 LuaImporter
类导入用 Lua 创建的 CoreModifiable
树。
在 XML 中,添加以下项以导入 "scene.lua" 文件并将其添加到当前 XML 层级结构中
<Inst N="lua" T="LuaImporter">
<Attr N="Script" V="scene.lua"/>
</Inst>
用于导入的 Lua 文件的语法如下
local result =
{
item("itemName1", "itemType1", {attributeName1=0,... }).items(
item("itemName2", "itemType2", { attributeName1=true, ... } ),
item("itemName3", "itemType3", { attributeName1=32, ... } ),
...
)
}
return result
"item
" 关键字创建 CoreModifiable
实例。前两个参数是实例名称和实例类型,然后是要用给定值初始化的属性列表。
要向项添加子项,请使用 ".items
" 关键字。
在上面的示例中,itemName2
和 itemName3
是 itemName1
的子项。
由于是 Lua 代码,可以定义函数并调用它们作为辅助函数,以创建相同类型的对象或初始化属性
local specialNode3D = function(name)
return item(name, "Node3D", {Show=false, IgnoreBBox=true, CollideMask=0}).items(
item("nodepth", "RenderingCustomizer", {OverrideDepthTest=0, RenderPassMask=16})
)
end
local result =
{
specialNode3D("node1").items(
specialNode3D("node2"),
specialNode3D("node3")
)
}
return result
也可以从另一个 XML 或 Lua 文件导入项
local result =
{
item("itemName1", "itemType1", {Param1=-1, Param2=-1}).items(
xml("item2FromXML", "item2.xml",{Param1 = 5}),
lua("item3FromExternLua", "item3.lua"),
)
}
return result
或者使用 "ref
" 关键字引用已加载的项:
item("itemName1", "itemType1", {Param1=-1, Param2=-1}).items(
ref("refName", "refType")
)
最后,还可以连接信号和槽
item("button", "UIButtonImage", {Priority=10, UpTexture="Up.png",
DownTexture="Down.png",Dock={0.9,0.1}}).items(
connect("this","ClickUp" ,"../UIItem:panel","Click")
)
并将实例添加到自动更新机制
item("itemName1", "itemType1", {attributeName1=0,... }).items(core.AddAutoUpdate)
在此 Wiki 部分找到所有示例代码,位于 Sample7 项目中 (浏览代码)。
已在此系列中发布
- Kigs框架介绍 (1/8) - 概述
- Kigs框架介绍 (2/8) - CoreModifiable
- Kigs框架介绍 (3/8) - 属性
- Kigs框架介绍 (4/8) - 方法
- Kigs框架介绍 (5/8) - CoreItem
- Kigs框架介绍 (6/8) - 信号,槽,通知
- Kigs框架介绍 (7/8) - Lua绑定
- Kigs框架介绍 (8/8) - 数据驱动应用程序
历史
- 2020 年 3 月 5 日:初始版本
- 2020 年 6 月 17 日:添加了该系列的最后一篇文章
- 2023 年 3 月 1 日:框架重构后更新了文章