Jump to content

Entity pointers in C++ and toLua++


Roland
 Share

Recommended Posts

I have successfully managed to use toLua++ in order to expose my C++ classes to LUA. All works fine and dandy, however I have to use void* pointers in functions where there is a Entity* pointer. Its really no big problem but I would like to now if any one else know something about this. Example:

 

 

class MyClass
{
public:
   MyClass();
   void some_function( Leadwerks::Entity* e );
}

 

That one causes a crash in LUA when some_function is called

 

function Script.Start()
   myclass = MyClass:new() -- OK
   myclass:some_function( self.entity ) -- KRASH
end

 

 

Now if I instead use a void* all works great

 

class MyClass
{
public:
   MyClass();
   void some_function( void* e );
}

 

This one works in LUA when some_function is called

 

function Script.Start()
   myclass = MyClass:new() -- OK
   myclass:some_function( self.entity ) -- OK
end

 

I can understand that toLua++ apparently doesn't handle the Leadwerks::Entity* as expected. Is there anyone that have come across this little problem and if so how to fix it? I couldn't come up with something. Meanwhile I can live with the void* although I don't like it.

Roland Strålberg
Website: https://rstralberg.com

Link to comment
Share on other sites

I don't know, just a guess... but maybe you can't pass light user data as an argument since it technically has no type? try doing a tolua.cast on the entitiy.

 

myclass::some_function(tolua.cast(self.entity, "Entity"))

 

But again, just my best guess off the top of my head, assuming 'self.entity' exists.

That would also explain why void* pointer version works, because you're passing a type-less argument.

Link to comment
Share on other sites

You can't pass entity objects from Lua to C++. I recommend setting a UUID field on the Key map for Entities and loop through all entities in World to get the entity in C++.

Of course you can pass Entitys from LUA to C++. Here is a fictional example on how I do that. Say we have a LUA script containing some Entity, say a Box Shape. Now we want to pass this Script and its entity to a C++ class for some work. I type in this just from my head so there might be some minor errors but you get the idea.

What was talking about was those void* pointers. That works but it would have been nicer to use Leadwerks::Entity* pointers which they really are.

 

RotatingBox.lua: LUA Script

Script.TheBox box = nil --entity "The Box"

Script.Speed speed = 0.5 --float "Speed"

 

Script.cppworker = nil

 

function Script.Start()

cpp = CppWorker:new( self.entity ) -- passing our self to C++

end

 

function Script:Update()

cpp:rotate( self.box ) -- passing the box entity to C++

end

 

 

CppWorker.h: C++ Class Header

#pragma once

#include "Leadwerks.h"

 

class CppWorker

{

float _speed;

 

public:

// Have to use void* instead of Leadwerks::Entity*

CppWorker( void* luascript_entity );

 

// Same here. Have to use void* instead of Leadwerks::Entity*

void rotate(void* entity);

};

 

CppWorker.cpp: C++ Class Source

#include "CppWorker.h"

 

CppWorker::CppWorker( void* luascript_entity )

{

Leadwerks::Entity* luaentity = reinterpret_cast<Leadwerks::Entity*>(luascript_entity); //Script Entity from LUA

 

// reading speed from LUA

 

int stacksize = Leadwerks::Interpreter::GetStackSize();

luaentity->Push();

Leadwerks::Interpreter::GetField("script");

if (Leadwerks::Interpreter::IsTable())

{

Leadwerks::Interpreter::GetField("Speed");

_speed = atof(Leadwerks::Interpreter::GetVariableValue().c_str());

 

}

Leadwerks::Interpreter::SetStackSize(stacksize);

}

 

void CppWorker::rotate(void* entity)

{

Leadwerks::Entity* e = reinterpret_cast<Leadwerks::Entity*>(entity);

e->Turn( 0, Leadwerks::Time::GetSpeed() * _speed, 0 );

}

 

CppWorker: ToLua++ Source

$#include "Leadwerks.h"

$#include "CppWorker.h"

 

class CppWorker

{

public:

CppWorker( void* luascript_entity );

void rotate(void* entity);

};

 

tolua++ -o CppWorker_.cpp -n CppWorker -H CppWorker_.h CppWorker.pkg

 

Compilation

Add CppWorker_.h and CppWorker_.cpp to the project and in App.cpp add #include "CppWorker_.h" at the top and then add this line at some convinient place in your App.cpp, something like this

...

tolua_FpsPlayer_open(Leadwerks::Interpreter::L);

if (!Interpreter::ExecuteFile(scriptpath))

...

..

 

Test

Add the script RotatingBox.lua to some Entity in you scene and if your the

box will rotate. The CppWorker does the rotation of the Lua Entity 'box'

using the Lua value 'speed'.

 

 

PS:

Oh how I hate this forum editor that removes the tab-indentations in code

Roland Strålberg
Website: https://rstralberg.com

Link to comment
Share on other sites

I mean entity pointers should work just fine with ToLua++.

Really. Could you give a simple example.

 

class Test
{
public:
Test( Leadwerks::Entity* e );
};

 

gives an error at runtime saying that argument #2 is a Leadwerks::Model

 

This works though

 

class Test
{
public:
Test( void* e );
};

 

 

in LUA

Script.cpp = nil

function Script:Start()
cpp = Test:new( self.entity)
end

Roland Strålberg
Website: https://rstralberg.com

Link to comment
Share on other sites

Thanks Josh. That changed nothing.

However I have found that the reason why its working for you is that you are having

"using namespace Leadwerks;" in your headers. I tested by adding that to my example

 

Doesn't work

 

#include "Leadwerks.h"//lua
class Test
{
public:
Test( Leadwerks::Entity* e);//lua
};

 

This works

#include "Leadwerks.h"//lua
using namespace Leadwerks;
class Test
{
public
Test(Entity* e);//lua
};

 

Pgk-file (same in both cases)

$#include "Leadwerks.h"
$#include "Test.h"

class Test
{
Test(Entity* ent );
};

 

 

I don't like to have 'using' in my headers but I'll guess I can live with that for my Lua-exposed classes wink.png so I guess we can say its solved then. Thanks for taking the time.

  • Upvote 2

Roland Strålberg
Website: https://rstralberg.com

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   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.

 Share

×
×
  • Create New...