More amazing things you can do with Lua in Leadwerks 5
Our implementation of Lua in Leadwerks 5 is shaping up to be a dream come true. Below are some of the great improvements that are being made.
Access STL Containers in Lua
You can access STL containers directly from Lua:
for n = 1, #entity.kids do entity.kids[n]:Move(1,0,0) end
while #entity.kids > 0 do entity.kids[1]:SetParent(nil) end
In fact, verbose commands like CountChildren() and GetChild() are no longer needed at all. On the C++ side you can use this:
for (int n=0; n<entity->kids.size(); n++) { entity->kids[n]->Move(1,0,0); }
while (entity->kids.size()) { entity->kids[0]->SetParent(nullptr); }
Note that in C++ arrays start with 0 and in Lua they start with 1.
This also allows us to return STL contains from functions or accept them as arguments. No more ForEachEntity... callbacks are needed:
local aabb = AABB(-10,10,0,5,-10,10) local entities = world:GetEntitiesInAABB(aabb) for n=1,#entities do entities[n]:AddForce(0,10,0) end
Super Pro User-defined Values
There will be no more self.entity or entity.script conventions in Leadwerks 5. Functions and user-defined values will be attached directly to the entity itself. The example below shows user-defined values that persist even when the entity goes out of scope of the Lua virtual machine:
--Create child local a = CreateBox(world,1,1,1) --Set a user-defined value a.health = 100 --Create parent local b = CreateBox(world,1,1,1) --Set parent a:SetParent(b,true) --Let child go out of scope (parent keeps it from being deleted in C++) a = nil --Collect garbage collectgarbage() --Get the child local c = b.kids[1] --Check the value print(c.health) --prints '100'
In Leadwerks 4 an entity script might look like this:
function Script:Update() self.entity:Turn(self.speed,0,0) end
In Leadwerks 5 it is simpler because self is the actual entity:
function Entity:Update() self:Turn(self.speed,0,0) end
In Leadwerks 4 you have to check to see if an entity has a script attached and us that to store all user-defined values:
if world:Pick(v1,v2,pickinfo) then if pickinfo.entity.script~=nil then if type(pickinfo.entity.script.TakeDamage)=="function" then pickinfo.entity.script:TakeDamage(10) end end end
Leadwerks 5 is a lot simpler. You just check if the functions exists on the entity and then call it:
if world:Pick(v1,v2,pickinfo) then if type(pickinfo.entity.TakeDamage)=="function" then pickinfo.entity:TakeDamage(10) end end
You can even assign custom properties to entities without worrying whether they have a script attached:
function Entity:Collision( collidedentity, position, normal, speed ) collidedentity.lasthitobject = self --No script? No problem! end
In fact all a script does is attach some functions and values to an entity and then it is gone. There is no fundamental difference between a scripted and non-scripted entity.
Casting Objects
Casting objects in Leadwerks 4 uses syntax that is a little awkward. I actually had to look up the tolua.cast function just now because I couldn't remember the order of the arguments:
local a = Model:Box() local b = Model:Box() a:SetParent(b) local entity = b:GetChild(0) local model = tolua.cast(entity,"Model")
Casting is simpler and more intuitive in Leadwerks 5:
local a = CreateBox() local b = CreateBox() a:SetParent(b) local entity = b:kids[1] local model = Model(entity)
If the entity is not a model then the casting function will just return nil.
A big thanks goes out to the developers of sol2, an awesome modern Lua binding library with support for C++11 smart pointers.
- 2
6 Comments
Recommended Comments