In this article, we will detail how Lua can access Kigs framework features (CoreModifiable attributes / methods ...) and how Kigs framework can access Lua features.
Table of Contents
In this article, we will see how to enhance the Kigs framework, and particularly CoreModifiable
classes with Lua.
Lua (5.3.5) programming language is embedded in the framework here:
With minor changes for Universal Windows Platform build.
The same directory also contains LuaIntf: A binding between C++11 and Lua language:
To learn more about Lua, look here: https://www.lua.org.
Here is the list of bound classes and their accessible methods from Lua:
-
CoreModifiable
:
name()
: Return instance name addItem(CMSP item)
: Add a CoreModifiable
instance smart pointer (CMSP
) to another (see CoreModifiable
article) removeItem(CMSP item)
: Remove an instance smart pointer (CMSP
) from another (see CoreModifiable
article) aggregateWith(CMSP item)
: Aggregate a CoreModifiable
instance smart pointer (CMSP
) to another (see CoreModifiable
article) removeAggregateWith(CMSP item)
: Remove an aggregate (see CoreModifiable
article) parents()
: Get parents list childs()
or items()
: Get children list getSonsByType(type)
: Get list of children of given type getSonsByName(name)
: Get list of children with given name init()
: Call CoreModifiable
Init uid()
: Get instance unique id type()
: Get instance exact type isSubType(type)
: Check if instance is of the given type addAttribute(val)
: Add a dynamic attribute of the type of the given val (bool
, float
, string
or vector
) onEvent(method_name or Lua function,notification_name)
: Add an observer on notification_name
to call method_name
or directly Lua function. getByPath(path)
: Search an instance by path importAsSon(filename)
: Import the given file and add CoreModifiable
tree to calling CoreModifiable
instance emit(signal_name)
: Emit a signal with given name
-
CMSP
:
get()
: get CoreModifiable
instance pointed by the smart pointer
-
v2f, v3f and v4f
: 2D, 3D or 4D vectors
Dot(v1,v2)
: static method, return dot product of v1 and v2 Cross(v1,v2)
: static method, return cross product of v1 and v2 (not available on v4f) Norm(v1)
: static method, return norm of v1 NormSquare(v1)
: static method, return squared norm of v1 normalize()
: normalize vector normalized()
: return a copy of the normalized vector copy()
: return a copy of the vector - members can be accessed with
.x
, .y
, .z
(for v3f
and v4f
), .w
(for v4f
) - vector standard operation :
* + - /
are also available
-
mat3x4
: 3 x 4 matrix (3D transform matrix)
setRotationX(angle)
: Set current matrix to be a X axis rotation matrix of given angle setRotationY(angle)
: Set current matrix to be a Y axis rotation matrix of given angle setRotationZ(angle)
: Set current matrix to be a Z axis rotation matrix of given angle preRotateX(angle)
: Pre rotate current matrix around X axis with given angle preRotateY(angle)
: Pre rotate current matrix around Y axis with given angle preRotateZ(angle)
: Pre rotate current matrix around Z axis with given angle postRotateX(angle)
: Post rotate current matrix around X axis with given angle postRotateY(angle)
: Post rotate current matrix around Y axis with given angle postRotateZ(angle)
: Post rotate current matrix around Z axis with given angle setScale(sx,sy,sz)
: Set current matrix to be a scale matrix with given scale on each axis preScale(sx,sy,sz)
: Pre scale current matrix with given scale on each axis postScale(sx,sy,sz)
: Post scale current matrix with given scale on each axis setTranslation(v)
: Set current matrix to be a translation matrix of given v3f
vector preTranslate(v)
: Pre translate current matrix with given v3f
vector postTranslate(v)
: Post translate current matrix with given v3f
vector setRotationXYZ(aX,aY,aZ)
: Set current matrix to be a rotation matrix with angles aX, aY, aZ. Rotations are applied in order X, then Y, then Z setRotationZYX(aX,aY,aZ)
: Set current matrix to be a rotation matrix with angles aX, aY, aZ. Rotations are applied in order Z, then Y, then X preRotateXYZ(aX,aY,aZ)
: Pre rotate current matrix (Rotations are applied in order X, then Y, then Z) preRotateZYX(aX,aY,aZ)
: Pre rotate current matrix (Rotations are applied in order Z, then Y, then X) postRotateXYZ(aX,aY,aZ)
: Post rotate current matrix (Rotations are applied in order X, then Y, then Z) postRotateZYX(aX,aY,aZ)
: Post rotate current matrix (Rotations are applied in order Z, then Y, then X) setIdentity()
: Set matrix to identity setNull()
: Set each matrix member to 0 isIdentity()
: Return true
if the matrix is identity transformPoint(v)
: Transform given v3f
vector as a point with the current matrix (apply translation) transformPoints(list_of_v)
: Transform each v3f
vector in the given list as a point with current matrix (apply translation) transformVector(v)
: Transform given v3f
vector with current matrix (translation is not applied) transformVectors(list_of_v)
: Transform each v3f
vector in the given list with current matrix (translation is not applied) copy()
: Return a copy of the current matrix
-
core
:
ByName(name)
: Returns the list of CoreModifiable
with the given name ByType(type)
: Returns the list of CoreModifiable
with the given type GetFirstInstanceByName(name)
: Returns the first CoreModifiable
found with the given name GetModule(name)
: Returns the module (CoreModifiable
) with the given name PostNotification(name,sender,data)
: Post notification with the given name. sender and data are optional CoreModifiable
parameters AddAutoUpdate(instance)
: Add given CoreModifiable
instance to auto-update mechanism RemoveAutoUpdate(instance)
: Remove given CoreModifiable
instance from auto-update mechanism SID(string)
: Return KigsID
(unsigned int) for the given string Connect(sender,signal,receiver,slot)
: Connect CoreModifiable
sender's signal to CoreModifiable
receiver's slot Disconnect(sender,signal,receiver,slot)
: Disconnect CoreModifiable
sender's signal to CoreModifiable
receiver's slot Import(filename)
: Import filename as CoreModifiable
tree and returns CMSP
root
On Lua side, generic functionalities of the framework are available:
local logoSP = CoreModifiable("logo","UIImage")
local logo=logoSP:get()
logo.Texture = "KigsHD.png"
logo.Dock = {0.5,0.5}
logo.Anchor = {0.5,0.5}
logo.Priority = 10
logo:init()
CoreModifiable
attributes are accessed directly by their name preceded by a dot '.
'.
local rotate = logo.RotationAngle
rotate = rotate + 0.1
logo.RotationAngle = rotate
Bound methods or CoreModifiable
methods are accessed the classic Lua way with a ':' ( except for static
methods, were '.
' should be used ) :
target:HelloFromLua()
It's possible to just execute some Lua code from a file in C++ :
auto lua = KigsCore::GetModule<LuaKigsBindModule>();
bool result=lua->ExecuteLuaFile("myCode.lua");
Or to execute some code when importing an XML file by adding a "Lua" item to an instance:
<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>
or:
<Lua N="someCode" V="#someCode.lua"/>
In XML, it's also possible to add a Lua function (as a CoreModifiable
method) to a CoreModifiable
instance:
<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>
The LuaBehaviour
class is used to add functionalities to an instance using the Lua language.
The easy way to do it is to add this kind of item directly in XML to the targeted instance:
<Inst N="testLua" T="LuaBehaviour" Aggregate="true">
<Attr N="Script" V="#test.lua"/>
</Inst>
The LuaBehaviour
must be added as an aggregate to its parent instance.
Here, the "Script
" attribute value is "#test.lua
". The starting '#
' indicates a filename to load. So here, the "test.lua" file is loaded (if found) and its content is interpreted as Lua.
The code can also be embedded in the XML file as CDATA
:
<Inst N="testLua" T="LuaBehaviour" Aggregate="true">
<Attr N="Script">
<![CDATA[
</Attr>
</Inst>
Of course, LuaBehaviour
instance can be created using framework code, the "classic" way :
CMSP behaviour = KigsCore::GetInstanceOf("behaviour", "LuaBehaviour");
behaviour->setValue("Script", "#ScriptOnApp.lua");
aggregateWith(behaviour);
behaviour->Init();
Lua code must have the following form:
local behaviourObjectName = { var1 = 0; var2 = "two" }
function behaviourObjectName:doSomething(param1)
self.var1 = param1
end
return behaviourObjectName
The methods "init()
", "update(current_time)
", "destroy()
", "addItem(other)
", "removeItem(other)
" are called automatically when aggregate is initialized, update...
Adding a CoreModifiable
Lua method directly in Lua is possible using WRAP_METHODS
table in the object declaration:
local Sample7Script = { logo=0; startingTime=0; WRAP_METHODS = {"reset"}; }
function Sample7Script:reset(current_time)
self.startingTime = current_time
end
Or directly by adding a Lua function to the target object in init
function:
function Sample7Script:init()
self.target.reset = function (current_time)
self.startingTime = current_time
end
end
So on the C++ side, the Lua reset
method can be called like another CoreModifiable
method:
instance->SimpleCall("reset",GetApplicationTimer()->GetTime());
LuaBehaviour
functions can use self.target
to access the CoreModifiable
instance aggregated to LuaBehaviour
:
local logoSP = CoreModifiable("logo","UIImage")
self.target:addItem(logoSP)
It's also possible to import CoreModifiable
trees created in Lua using LuaImporter
class.
In XML, add the following item to import "scene.lua" file and add it in the current XML hierarchy:
<Inst N="lua" T="LuaImporter">
<Attr N="Script" V="scene.lua"/>
</Inst>
The syntax of a Lua file aimed at import looks like that:
local result =
{
item("itemName1", "itemType1", {attributeName1=0,... }).items(
item("itemName2", "itemType2", { attributeName1=true, ... } ),
item("itemName3", "itemType3", { attributeName1=32, ... } ),
...
)
}
return result
"item
" keyword creates a CoreModifiable
instance. The first two parameters are instance name and instance type, then the list of attributes to initialize with given values.
To add sons to an item, use the ".items
" keyword.
In the previous example, itemName2
and itemName3
are sons of itemName1
.
As it's Lua code, it's possible to define functions and call them as helpers to create objects with the same type or initialize attributes:
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
It's also possible to import an item from another XML or Lua file:
local result =
{
item("itemName1", "itemType1", {Param1=-1, Param2=-1}).items(
xml("item2FromXML", "item2.xml",{Param1 = 5}),
lua("item3FromExternLua", "item3.lua"),
)
}
return result
Or to reference an already loaded item with the "ref
" keyword:
item("itemName1", "itemType1", {Param1=-1, Param2=-1}).items(
ref("refName", "refType")
)
And finally, it's also possible to connect a signal and slot:
item("button", "UIButtonImage", {Priority=10, UpTexture="Up.png",
DownTexture="Down.png",Dock={0.9,0.1}}).items(
connect("this","ClickUp" ,"../UIItem:panel","Click")
)
And to add an instance to auto-update mechanism:
item("itemName1", "itemType1", {attributeName1=0,... }).items(core.AddAutoUpdate)
Find all the sample code from this wiki section in Sample7 project (browse the code).
- Kigs Framework Introduction (1/8) - Overview
- Kigs Framework Introduction (2/8) - CoreModifiable
- Kigs Framework Introduction (3/8) - Attributes
- Kigs Framework Introduction (4/8) - Methods
- Kigs Framework Introduction (5/8) - CoreItem
- Kigs Framework Introduction (6/8) - Signal, Slot, Notification
- Kigs Framework Introduction (7/8) - Lua Binding
- Kigs Framework Introduction (8/8) - Data Driven Application
- 5th March, 2020: Initial version
- 17th June, 2020 : Added final article of the series
- 1st March, 2023 : Article updated after framework refactory