General questions.

classic Classic list List threaded Threaded
19 messages Options
Reply | Threaded
Open this post in threaded view
|

General questions.

William Roper
I've been reading up as much as I can on Lua the last month or so,
including the book, and I have a project that I am not sure the best
way to go about integrating Lua into it.

Basically what I need to is this.

I have a Singleton Object factory in C++ that creates objects (of
course). What I need is for once these objects are created in C++ pass
them into lua to be stored into a table.
Then my program is going to call a lua script which iterates on the
table of objects and processes scripts for each one in order.

I've figured out how to create instances of a C++ class IN Lua, but I
haven't really seen a way to pass already created class objects into
the Lua environment to be handled by Lua.

I also don't want them garbage collected, since I will handle that in
my script. I understand that probably isn't a problem since Lua didnt
create them, but I wanted to be sure.

Thanks in advance,
Ryan.

Reply | Threaded
Open this post in threaded view
|

Re: General questions.

Peter Bradshaw
(I've only been a lua user for about a month, so I may be about to get
rudely slapped for inaccuracy).

Light userdata sounds like exactly what you want. You just push a
pointer into lua and that's what you get back.

Setting the metatable from C and then checking it seems to be the way
to ensure type safety.

On Tue, 6 Jul 2004 08:18:24 -0700, William Roper <[hidden email]> wrote:
> I've been reading up as much as I can on Lua the last month or so,
> including the book, and I have a project that I am not sure the best
> way to go about integrating Lua into it.
> 
> Basically what I need to is this.
> 
> I have a Singleton Object factory in C++ that creates objects (of
> course). What I need is for once these objects are created in C++ pass
> them into lua to be stored into a table.
> Then my program is going to call a lua script which iterates on the
> table of objects and processes scripts for each one in order.
> 
> I've figured out how to create instances of a C++ class IN Lua, but I
> haven't really seen a way to pass already created class objects into
> the Lua environment to be handled by Lua.
> 
> I also don't want them garbage collected, since I will handle that in
> my script. I understand that probably isn't a problem since Lua didnt
> create them, but I wanted to be sure.
> 
> Thanks in advance,
> Ryan.
>

Reply | Threaded
Open this post in threaded view
|

Re: General questions.

Daniel Silverstone
Peter Bradshaw wrote:
(I've only been a lua user for about a month, so I may be about to get
rudely slapped for inaccuracy).

Light userdata sounds like exactly what you want. You just push a
pointer into lua and that's what you get back.

Setting the metatable from C and then checking it seems to be the way
to ensure type safety.

Erm, Light userdatas can't have metatables.

D.

--
Daniel Silverstone                         http://www.digital-scurf.org/
PGP mail accepted and encouraged.            Key Id: 2BC8 4016 2068 7895

Reply | Threaded
Open this post in threaded view
|

Re: General questions.

Jamie Webb-3
In reply to this post by Peter Bradshaw
On Tue, Jul 06, 2004 at 09:53:28AM -0700, Peter Bradshaw wrote:
> (I've only been a lua user for about a month, so I may be about to get
> rudely slapped for inaccuracy).
> 
> Light userdata sounds like exactly what you want. You just push a
> pointer into lua and that's what you get back.
> 
> Setting the metatable from C and then checking it seems to be the way
> to ensure type safety.

Unfortunately, this won't work, because light userdatas cannot have
metatables. They are intended for internal use by C modules, and
shouldn't generally be shown to Lua code.

The principal is about right though. You want a full userdata that
contains just a pointer. Then you can use a metatable for type
checking and to provide the object with methods.

-- Jamie Webb

Reply | Threaded
Open this post in threaded view
|

Re: General questions.

Salvador Espana
On Tue, 6 Jul 2004, Jamie Webb wrote:

> The principal is about right though. You want a full userdata that
> contains just a pointer. Then you can use a metatable for type
> checking and to provide the object with methods.

If you want an example, (be sure it is not the best, no guarantees)  
you can download:

http://www.dsic.upv.es/~sespana/MT.tgz

Best regards,
S.


Reply | Threaded
Open this post in threaded view
|

Re: General questions.

Ben Sunshine-Hill
In reply to this post by Daniel Silverstone
Yep, more likely you'll want to box the pointer into a full userdata
and make sure that the metamethods know to dereference it.

On Tue, 06 Jul 2004 17:59:44 +0100, Daniel Silverstone
<[hidden email]> wrote:
> Peter Bradshaw wrote:
> > (I've only been a lua user for about a month, so I may be about to get
> > rudely slapped for inaccuracy).
> >
> > Light userdata sounds like exactly what you want. You just push a
> > pointer into lua and that's what you get back.
> >
> > Setting the metatable from C and then checking it seems to be the way
> > to ensure type safety.
> 
> Erm, Light userdatas can't have metatables.
> 
> D.
> 
> --
> Daniel Silverstone                         http://www.digital-scurf.org/
> PGP mail accepted and encouraged.            Key Id: 2BC8 4016 2068 7895
>

Reply | Threaded
Open this post in threaded view
|

Re: General questions.

William Roper
In reply to this post by Daniel Silverstone
Ok, since there seems to be some confusion, Ill start over.

I have created a Singleton Object Factory in C++. I ask it to create
me a new instance of a class and it provides me with a pointer to my
new instance.

I already know in lua I can create the binding functions to allow lua
to create instances of my class, but I don't *want* lua to create the
instances. I want my application to create the instances, and handle
their deletion.

I want to pass to lua a "pointer" to the instance I created and be
able to store it in a table, along with other instances.

I then want to be able to call a lua script that iterates over the
table, calling scripts on each instance of the class that has been
created and registered.

When i am done with the object, I will remove the "pointer" from the
table and call a c++ function from lua to clean up the instance.

I hope thats more understandable, I'm not exactly sure what parts I
didn't explain well enough before.

About the light user data, yeah, I read over those and it doesn't seem
like it will work, since you can't use metatables to create methods on
them like full userdata.

Thanks,
Ryan

On Tue, 06 Jul 2004 17:59:44 +0100, Daniel Silverstone
<[hidden email]> wrote:
> Peter Bradshaw wrote:
> > (I've only been a lua user for about a month, so I may be about to get
> > rudely slapped for inaccuracy).
> >
> > Light userdata sounds like exactly what you want. You just push a
> > pointer into lua and that's what you get back.
> >
> > Setting the metatable from C and then checking it seems to be the way
> > to ensure type safety.
> 
> Erm, Light userdatas can't have metatables.
> 
> D.
> 
> --
> Daniel Silverstone                         http://www.digital-scurf.org/
> PGP mail accepted and encouraged.            Key Id: 2BC8 4016 2068 7895
>

Reply | Threaded
Open this post in threaded view
|

Re: General questions.

William Roper
"If you know how to export your object's functionality to Lua then you
know how to do it whether the object already exists or not.  The only
difference is that, rather than allocating the object's memory via
lua_newuserdata, you will allocate space for a pointer to the object
and store the pointer in the userdata."

I just reread this statement, could you elaborate on that a little?
All the examples I can find both in the book and on the wiki deal with
creating new instances of a class in lua, not handling existing
instances of a class from C++.

Thanks,
Ryan

On Tue, 6 Jul 2004 10:29:00 -0700, William Roper <[hidden email]> wrote:
> Ok, since there seems to be some confusion, Ill start over.
> 
> I have created a Singleton Object Factory in C++. I ask it to create
> me a new instance of a class and it provides me with a pointer to my
> new instance.
> 
> I already know in lua I can create the binding functions to allow lua
> to create instances of my class, but I don't *want* lua to create the
> instances. I want my application to create the instances, and handle
> their deletion.
> 
> I want to pass to lua a "pointer" to the instance I created and be
> able to store it in a table, along with other instances.
> 
> I then want to be able to call a lua script that iterates over the
> table, calling scripts on each instance of the class that has been
> created and registered.
> 
> When i am done with the object, I will remove the "pointer" from the
> table and call a c++ function from lua to clean up the instance.
> 
> I hope thats more understandable, I'm not exactly sure what parts I
> didn't explain well enough before.
> 
> About the light user data, yeah, I read over those and it doesn't seem
> like it will work, since you can't use metatables to create methods on
> them like full userdata.
> 
> Thanks,
> Ryan
> 
> 
> 
> On Tue, 06 Jul 2004 17:59:44 +0100, Daniel Silverstone
> <[hidden email]> wrote:
> > Peter Bradshaw wrote:
> > > (I've only been a lua user for about a month, so I may be about to get
> > > rudely slapped for inaccuracy).
> > >
> > > Light userdata sounds like exactly what you want. You just push a
> > > pointer into lua and that's what you get back.
> > >
> > > Setting the metatable from C and then checking it seems to be the way
> > > to ensure type safety.
> >
> > Erm, Light userdatas can't have metatables.
> >
> > D.
> >
> > --
> > Daniel Silverstone                         http://www.digital-scurf.org/
> > PGP mail accepted and encouraged.            Key Id: 2BC8 4016 2068 7895
> >
>

Reply | Threaded
Open this post in threaded view
|

Re: General questions.

Jamie Webb-3
On Tue, Jul 06, 2004 at 10:32:00AM -0700, William Roper wrote:
> "If you know how to export your object's functionality to Lua then you
> know how to do it whether the object already exists or not.  The only
> difference is that, rather than allocating the object's memory via
> lua_newuserdata, you will allocate space for a pointer to the object
> and store the pointer in the userdata."
> 
> I just reread this statement, could you elaborate on that a little?
> All the examples I can find both in the book and on the wiki deal with
> creating new instances of a class in lua, not handling existing
> instances of a class from C++.

// Create your class instance
MyClass* instance = new MyClass();

// Create a Lua userdata to point to your object
MyClass** ptr = (MyClass**) lua_newuserdata(L, sizeof(MyClass*));

// Make ptr point to your object
*ptr = instance;

Now you have a userdata representing a pointer to your object sitting
on the Lua stack. You'll need to set its metatable using the
techniques described in the book and wiki, and then return that value
to Lua.

Your methods will be created exatly is described in the book and wiki,
except that you will need to extract the pointer from the userdata and
dereference it in order to get your object, rather than the userdata
itself being the object.

-- Jamie Webb

Reply | Threaded
Open this post in threaded view
|

Re: General questions.

William Roper
In reply to this post by Jamie Webb-3
Ok, I think I've got it now.

I need to create a wrapper class that will be the userdata.
Inside the wrapper class will at least contain a pointer to my
instanced class and a function wrapper for each function I need to
call in the instanced class from Lua.

Then after I create my instanced class, the factory needs to call a
function that creates the new userdata, then sets the user datas
pointer to instanced class.
I also create a metatable for the userdata that has the methods I need
to call on my instanced class and point them to the wrapper functions
for each of those.

Wow, its a lot to get your head wrapped around at first.
It's interesting how few tutorials there are for Lua on the net.

Let me know if I am on the wrong track, if not, thanks for pointing me
in the right direction everyone.

Ryan.

Reply | Threaded
Open this post in threaded view
|

RE: General questions.

Nick Trout
In reply to this post by William Roper

> -----Original Message-----
> From: [hidden email] [[hidden email]
> [hidden email]] On Behalf Of Jamie Webb
> Sent: Tuesday, July 06, 2004 11:17 AM
> To: Lua list
> Subject: Re: General questions.
> 
> On Tue, Jul 06, 2004 at 10:32:00AM -0700, William Roper wrote:
> > "If you know how to export your object's functionality to Lua then
you
> > know how to do it whether the object already exists or not.  The
only
> > difference is that, rather than allocating the object's memory via
> > lua_newuserdata, you will allocate space for a pointer to the object
> > and store the pointer in the userdata."
> >
> > I just reread this statement, could you elaborate on that a little?
> > All the examples I can find both in the book and on the wiki deal
with
> > creating new instances of a class in lua, not handling existing
> > instances of a class from C++.
> 
> // Create your class instance
> MyClass* instance = new MyClass();
> 
> // Create a Lua userdata to point to your object
> MyClass** ptr = (MyClass**) lua_newuserdata(L, sizeof(MyClass*));
> 
> // Make ptr point to your object
> *ptr = instance;
> 
> Now you have a userdata representing a pointer to your object sitting
> on the Lua stack. You'll need to set its metatable using the
> techniques described in the book and wiki, and then return that value
> to Lua.
> 
> Your methods will be created exatly is described in the book and wiki,
> except that you will need to extract the pointer from the userdata and
> dereference it in order to get your object, rather than the userdata
> itself being the object.

You could use the box and unbox pointer macros... (This pointer to
pointer stuff can be a read head spinner!)

#define lua_boxpointer(L,u) \
	(*(void **)(lua_newuserdata(L, sizeof(void *))) = (u))

#define lua_unboxpointer(L,i)	(*(void **)(lua_touserdata(L, i)))

Nick



Reply | Threaded
Open this post in threaded view
|

Re: General questions.

Peter Bradshaw
In reply to this post by Jamie Webb-3
Apologies to all, and thanks everyone for setting me right. I'll get my coat

I guess tolua's hiding a lot of stuff from me. which is nice.

Reply | Threaded
Open this post in threaded view
|

Re: General questions.

Jamie Webb-3
In reply to this post by William Roper
On Tue, Jul 06, 2004 at 11:26:37AM -0700, William Roper wrote:
> Ok, I think I've got it now.
> 
> I need to create a wrapper class that will be the userdata.
> Inside the wrapper class will at least contain a pointer to my
> instanced class and a function wrapper for each function I need to
> call in the instanced class from Lua.

You could do that, but you don't actually need to create a wrapper
class. Just the wrapper functions. If you look at the example code I
posted earlier, I'm just storing a pointer directly in the userdata.

> Then after I create my instanced class, the factory needs to call a
> function that creates the new userdata, then sets the user datas
> pointer to instanced class.

Yes.

> I also create a metatable for the userdata that has the methods I need
> to call on my instanced class and point them to the wrapper functions
> for each of those.

Yes. Note that you only need to create the metatable for each class
once, and then you use the same metatable for each instance of that
class.

-- Jamie Webb

Reply | Threaded
Open this post in threaded view
|

Re: General questions.

William Roper
Jamie,

Yeah, I posted my last message before I recieved your explanation.

The reason I suggested a wrapper class, is just that I find it easier
if all the functions and data are wrapped up together in a nice class.
Just personal preference. The examples in the book use structs to
store user data.

But anyway, thank you again, I get it now I think.

Ryan.

On Tue, 6 Jul 2004 19:38:54 +0100, Jamie Webb <[hidden email]> wrote:
> On Tue, Jul 06, 2004 at 11:26:37AM -0700, William Roper wrote:
> > Ok, I think I've got it now.
> >
> > I need to create a wrapper class that will be the userdata.
> > Inside the wrapper class will at least contain a pointer to my
> > instanced class and a function wrapper for each function I need to
> > call in the instanced class from Lua.
> 
> You could do that, but you don't actually need to create a wrapper
> class. Just the wrapper functions. If you look at the example code I
> posted earlier, I'm just storing a pointer directly in the userdata.
> 
> > Then after I create my instanced class, the factory needs to call a
> > function that creates the new userdata, then sets the user datas
> > pointer to instanced class.
> 
> Yes.
> 
> > I also create a metatable for the userdata that has the methods I need
> > to call on my instanced class and point them to the wrapper functions
> > for each of those.
> 
> Yes. Note that you only need to create the metatable for each class
> once, and then you use the same metatable for each instance of that
> class.
> 
> -- Jamie Webb
>

Reply | Threaded
Open this post in threaded view
|

Re: General questions.

Jonathan Jacobs
William Roper wrote:
The reason I suggested a wrapper class, is just that I find it easier
if all the functions and data are wrapped up together in a nice class.
Just personal preference. The examples in the book use structs to
store user data.

I enjoyed using luabind (http://luabind.sourceforge.net/), probably because it had a Boost.Python (http://www.boost.org/) feel to it.

However, I wasn't phased by performance issues or size...so you might find luabind generates bulkier and/or slower code. It's certainly easier to use for exposing C++ code, as is, to Lua.

Hope this helps,
Regards
--
Jonathan Jacobs
Developer

Reply | Threaded
Open this post in threaded view
|

Re: General questions.

William Roper
On Wed, 07 Jul 2004 11:37:43 +0200, Jonathan Jacobs
<[hidden email]> wrote:
> I enjoyed using luabind (http://luabind.sourceforge.net/), probably
> because it had a Boost.Python (http://www.boost.org/) feel to it.

I looked into luabind a while ago, and they were extremely unhelpful.
I use Borland's compiler and they said "It doesn't work and we aren't
going to waste time fixing it."

I have looked a little at tolua, but from what it looks like I need to
do it might be easier for me just to create the binding.

Thanks,
Ryan.

Reply | Threaded
Open this post in threaded view
|

Re: General questions.

Daniel Wallin-2
William Roper wrote:
On Wed, 07 Jul 2004 11:37:43 +0200, Jonathan Jacobs
<[hidden email]> wrote:

I enjoyed using luabind (http://luabind.sourceforge.net/), probably
because it had a Boost.Python (http://www.boost.org/) feel to it.

I looked into luabind a while ago, and they were extremely unhelpful.
I use Borland's compiler and they said "It doesn't work and we aren't
going to waste time fixing it."

Please understand that we are doing this work (and it's a LOT of work)
for free and simply don't have enough free time to fix all the problems
with highly deficient compilers. There's nothing to stop you from making
a contribution though.. or just use a less deficient compiler.

--
Daniel Wallin

Reply | Threaded
Open this post in threaded view
|

Re: General questions.

William Roper
In reply to this post by Jonathan Jacobs
On Wed, 07 Jul 2004 11:37:43 +0200, Jonathan Jacobs
<[hidden email]> wrote:
> I enjoyed using luabind (http://luabind.sourceforge.net/), probably
> because it had a Boost.Python (http://www.boost.org/) feel to it.

I looked into luabind a while ago, and they were extremely unhelpful.
I use Borland's compiler and they said "It doesn't work and we aren't
going to waste time fixing it."

I have looked a little at tolua, but from what it looks like I need to
do it might be easier for me just to create the binding.

Thanks,
Ryan.

Reply | Threaded
Open this post in threaded view
|

Re: General questions.

William Roper
In reply to this post by Daniel Wallin-2
On Wed, 07 Jul 2004 18:01:31 +0200, Daniel Wallin
<[hidden email]> wrote:
> William Roper wrote:
> > On Wed, 07 Jul 2004 11:37:43 +0200, Jonathan Jacobs
> > <[hidden email]> wrote:
> Please understand that we are doing this work (and it's a LOT of work)
> for free and simply don't have enough free time to fix all the problems
> with highly deficient compilers. There's nothing to stop you from making
> a contribution though.. or just use a less deficient compiler.
> 
> --
> Daniel Wallin
> 

I have no problem contributing, but noone even wanted to take the time
to talk about the problems in order to point me in the direction of
fixing it myself. I've never used the boost library, and the
experience left a very sour taste in my mouth.

I'm not going to get into compiler wars with you. Most compilers are
deficient in one way or another. He made a suggestion and I replied
with my experience in the matter.

Thanks,
Ryan.