Jump to content

Lua binding in Leadwerks 5


Josh

11,580 views

 Share

The Leadwerks 5 API uses C++11 smart pointers for all complex objects the user interacts with. This design replaces the manual reference counting in Leadwerks 4 so that there is no Release() or AddRef() method anymore. To delete an object you just set all variables that reference that object to nullptr:

auto model = CreateBox();
model = nullptr; //poof!

In Lua this works the same way, with some caveats:

local window = CreateWindow()
local context = CreateContext(window)
local world = CreateWorld()

local camera = CreateCamera(world)
camera:SetPosition(0,0,-5)

local model = CreateBox()

while true do
	if window:KeyHit(KEY_SPACE) then
		model = nil
	end
	world:Render()
end

In the above example you would expect the box to disappear immediately, right? But it doesn't actually work that way. Lua uses garbage collection, and unless you are constantly calling the garbage collector each frame the model will not be immediately collected. One way to fix this is to manually call the garbage collector immediately after setting a variable to nil:

if window:KeyHit(KEY_SPACE) then
	model = nil
	collectgarbage()
end

However, this is not something I recommend doing. Instead, a change in the way we think about these things is needed. If we hide an entity and then set our variable to nil we can just defer the garbage collection until enough memory is accrued to trigger it:

if window:KeyHit(KEY_SPACE) then
	model:Hide()-- out of sight, out of mind
	model = nil
end

I am presently investigating the sol2 library for exposing the C++ API to Lua. Exposing a new class to Lua is pretty straightforward:

lua.new_usertype<World>("World", "Render", &World::Render, "Update", &World::Update);
lua.set_function("CreateWorld",CreateWorld);

However, there are some issues like downcasting shared pointers. Currently, this code will not work with sol2:

local a = CreateBox()
local b = CreateBox()
a:SetParent(b)-- Entity:SetParent() expects an Entity, not a Model, even though the Model class is derived from Entity

There is also no support for default argument values like the last argument has in this function:

Entity::SetPosition(const float x,const float y,const float z,const bool global=false)

This can be accomplished with overloads, but it would require A LOT of extra function definitions to mimic all the default arguments we use in Leadwerks.

I am talking to the developer now about these issues and we'll see what happens.

  • Like 1
 Share

54 Comments


Recommended Comments



Lua copies objects by reference.

In C++ you might do it like this:

class Thing
{
    weak_ptr<Entity> target;
};

void UpdateMe() {
    shared_ptr<Entity> the_target = this->target.lock() //creates a shared pointer which prevents object from being deleted during this function
    if (the_target != nullptr)
    {
        //do some stuff
    }
}// shared pointer goes out of scope, object can once again be deleted

 

Link to comment

Here's an idea:

I will probably have to make a pre-processor anyways to handle comparison of derived objects with base objects. You can read this discussion on Github if you want.

What if the pre-processor also looks for code like this:

model:Reset()

and replaces it with this:

__RESET_SMART_POINTER__(model) model = nil

Of course this does not solve the problem described previously, but it does allow you to instantly set a smart pointer to null.

Link to comment

That's interesting. Wasn't aware you have to create a pre-processor. That could for sure work then. I'd use something like Destroy() or Delete() though as Reset() makes it seem like it'll go back to the values it had on map load (which might be a cool side feature to have actually).

Link to comment

Eh, you still have this problem:

local a = CreateBox()
local b = a
Reset(a) --converts to: "__RESET_SMART_POINTER__(a) a = nil"
b:SetPosition(0,0,0) --zombie object, not alive yet not dead

 

Link to comment

Guest
Add a comment...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...