Looking for a better way with Lua, C++, and static members

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

Looking for a better way with Lua, C++, and static members

Eric Wing-2
Hello, I'm using Lua for a small game and I'm looking
for a better way of implementing something.
In my program, I start in C++, and then launch a Lua
script which takes control of the flow. The script can
then make calls to C++ functions to do various
specialized things for my game like print text to the
screen or draw certain things. All these functions
were declared static because that was the only way I
could get Lua to call a C++ function. My goal was to
make a scripting interface that was very simple to use
and push off all the hard stuff to C++. I designed
this to be procedural driven rather than event driven
so the control flow would be really simple to
understand for the scripter.

Because Lua controls the flow and my application is
single threaded so things like getting input and
drawing cannot happen automatically. Fortunately, it
happens that when the scripter expects the player to
make a choice, I can make this function block and this
is the perfect time to do all the things like get
keyboard inputs and render the scene. This is all
handled by static C++ functions called by a single
registered Lua function (e.g. userChoice =
MakeChoice(...)).

This all works very well for me except for one case.
Because all the hard processing and rendering cannot
happen until "MakeChoice" is called, I have found that
sometimes I need to save information from other Lua
function calls so I can actually act on them later
when "MakeChoice" is actually called. But because all
my functions are declared static, it makes it
impossible to save any information unless I declare
static variables to hold everything.

So for example, in my code, I have declared a bunch of
static variables to hold the data. Things as simple as
what the panel size (e.g. SetPanelSize(...)) should be
or as complicated as creating an animation list are
all declared static. The scripter can then make
function calls to change the panel size or load new
images and create a new animation sequence. All this
data is saved for use in the render stage which is
triggered when the "MakeChoice" is finally called.

So, I generally like the end result, but I'm concerned
about all the static variables I'm using. In addition,
this isn't the only game mode that is used, so it
seems wrong that all these variables are present when
they're not being used. (Incidently, a different game
mode actually uses Lua in an event driven style.) Is
there a better way to do this? My preference would be
to have some regularly declared variables or objects
and pass around some references and let everything
negotiate through that, but the static restriction has
prevented me from using anything that has an instance.

Thank you



__________________________________
Do you Yahoo!?
Yahoo! SiteBuilder - Free, easy-to-use web site design software
http://sitebuilder.yahoo.com

Reply | Threaded
Open this post in threaded view
|

Re: Looking for a better way with Lua, C++, and static members

Diego Nehab-3
Hi,

> Hello, I'm using Lua for a small game and I'm looking
> for a better way of implementing something.
> In my program, I start in C++, and then launch a Lua
> script which takes control of the flow. The script can
> then make calls to C++ functions to do various
> specialized things for my game like print text to the
> screen or draw certain things. All these functions
> were declared static because that was the only way I
> could get Lua to call a C++ function.

You mean you want Lua to call a method of a object? If it is just a C++
function, Lua should have no problem calling it regardless of whether it
is a static or an extern function.

Methods are a little trickier. The way I like doing is to declare a
simple function for each method. Each function is associated with the
object instance in some way. Here there are several options: receive it
as a parameter, retrieve it from an upvalue, take it from a global
variable, get it from the registry etc. When the function is called from
Lua,  it retrieves the pointer to the object and call the appropriate
method.  You can even make it so that you actually "object:method()" in
our Lua script.

toLua does this binding automatically for you.

[]s,
Diego.


Reply | Threaded
Open this post in threaded view
|

Re: Looking for a better way with Lua, C++, and static members

Eric Wing-2
In reply to this post by Eric Wing-2
Hi, thank you for the response. I'm still kind of new
to Lua so if you could provide me a little source code
example, I would appreciate it.

First, I thought I should demonstrate what I'm doing
to give you a feel of what's going on.

Here's a stripped down, trivial example of what I'm
doing. I've registered two functions to Lua,
MakeChoice and SetFontSize. 
As I mentioned before, I have to save values I change
because the render stage doesn't occur until
MakeChoice is called by the scripter. So I have a
variable called font_size. Because my functions are
static, my variable is forced to be static.


class ConversationGameMode
{
public:
    static int MakeChoice(lua_State* ls);
    static int SetFontSize(lua_State* ls);

private:
    // This is what I would like to do but can't
    // int font_size;
}
// This is what I end up doing
static int font_size;

ConversationGameMode::SetFontSize(lua_State* ls)
{
    // get parameter from lua stack here
    font_size = (int)lua_tonumber(ls, // some stack
number);
    // clean up
}

ConversationGameMode::MakeChoice(lua_State* ls)
{
    // First sort out lua stack
    while( choice_not_made )
    {
        choice_not_made = GetInput();
	// Use the font_size here
        DrawText(font_size);
        DrawOtherStuff();
    }
}


So in the Lua code, the scripter can write:

-- do stuff here
SetFontSize(20)
MakeChoice("Option 1", "Option 2", "Option 3")
-- more stuff happens here


In this example, I would like a way to encapsulate
font_size so it isn't a static (or global) variable.
These methods didn't really need to be embedded in a
class, but it just kind of worked out that way when I
started trying to encapsulate things, not knowing at
the time that I had to declare things as static.
However, even as regular C/C++ functions, I still
don't know how to make font_size accessable without
making it static or global.

In my real code, I have other things I need to store,
from window pane sizes and colors to lists of images
to control flip book type animation. So my number of
static variables has been increasing which is starting
to concern me. I was hoping to find a cleaner way to
do what I have done without burdening the scripter
with extra stuff to worry about. 

Thank you again

> From: Diego Nehab 
> You mean you want Lua to call a method of a object?
> If it is just a C++
> function, Lua should have no problem calling it
> regardless of whether it
> is a static or an extern function.
> 
> Methods are a little trickier. The way I like doing
> is to declare a
> simple function for each method. Each function is
> associated with the
> object instance in some way. Here there are several
> options: receive it
> as a parameter, retrieve it from an upvalue, take it
> from a global
> variable, get it from the registry etc. When the
> function is called from
> Lua,  it retrieves the pointer to the object and
> call the appropriate
> method.  You can even make it so that you actually
> "object:method()" in
> our Lua script.
> 
> toLua does this binding automatically for you.
> 
> []s,
> Diego.
> 


__________________________________
Do you Yahoo!?
Yahoo! SiteBuilder - Free, easy-to-use web site design software
http://sitebuilder.yahoo.com

Reply | Threaded
Open this post in threaded view
|

Interaction between Lua / C++

Jacky Buyck
Hi all.
	I profit of the fact that a therat regarding C+ and Lua have
been recently posted to open another one not totally similar but really
close in my opinion.

	In fact something disturb me when I look that we integrat
directly Lua C API elements in our C++ classes. We see the integration
of lua_State directly in our classes definition. Is disturb me because
it turn our classes dependant of the Lua system so all our dev will be
dependant of it. Of course I know that, during the analyse of the
development choice must be made and once they've been made
implementation follow. 

	But is there a way to associate Lua system to a classe without
directly integrate Lua functions in our classes definition ?
	Is there a way to define an "Interface" classe that take Lua
fonctionnality and will be responsible of method to export ?

Any ideas or advices on this ?

Thanks.
JB


Reply | Threaded
Open this post in threaded view
|

Re: Interaction between Lua / C++

Daniel Wallin-2
At 12:27 2003-08-15, Jacky Buyck wrote:
Hi all.
        I profit of the fact that a therat regarding C+ and Lua have
been recently posted to open another one not totally similar but really
close in my opinion.

        In fact something disturb me when I look that we integrat
directly Lua C API elements in our C++ classes. We see the integration
of lua_State directly in our classes definition. Is disturb me because
it turn our classes dependant of the Lua system so all our dev will be
dependant of it. Of course I know that, during the analyse of the
development choice must be made and once they've been made
implementation follow.

        But is there a way to associate Lua system to a classe without
directly integrate Lua functions in our classes definition ?
        Is there a way to define an "Interface" classe that take Lua
fonctionnality and will be responsible of method to export ?

Any ideas or advices on this ?

Have you looked at luabind? (http://luabind.sf.net)

---
Daniel Wallin


Reply | Threaded
Open this post in threaded view
|

RE : Interaction between Lua / C++

Jacky Buyck
This is just what I'm looking now. I've some difficulties but I'll try
to play with it.
In fact I want to have the vision of people that use Lua for long ot the
vision of people that have already make implement something with this
kind of consideration.

-----Message d'origine-----
De : [hidden email]
[[hidden email]] De la part de Daniel Wallin
Envoyé : vendredi 15 août 2003 12:44
À : Lua list
Objet : Re: Interaction between Lua / C++


At 12:27 2003-08-15, Jacky Buyck wrote:
>Hi all.
>         I profit of the fact that a therat regarding C+ and Lua have 
>been recently posted to open another one not totally similar but really

>close in my opinion.
>
>         In fact something disturb me when I look that we integrat 
>directly Lua C API elements in our C++ classes. We see the integration 
>of lua_State directly in our classes definition. Is disturb me because 
>it turn our classes dependant of the Lua system so all our dev will be 
>dependant of it. Of course I know that, during the analyse of the 
>development choice must be made and once they've been made 
>implementation follow.
>
>         But is there a way to associate Lua system to a classe without

>directly integrate Lua functions in our classes definition ?
>         Is there a way to define an "Interface" classe that take Lua 
>fonctionnality and will be responsible of method to export ?
>
>Any ideas or advices on this ?

Have you looked at luabind? (http://luabind.sf.net)

---
Daniel Wallin


Reply | Threaded
Open this post in threaded view
|

Re: Looking for a better way with Lua, C++, and static members

Jules Bean
In reply to this post by Eric Wing-2
On Fri, Aug 15, 2003 at 02:19:34AM -0700, Eric Wing wrote:
> Hi, thank you for the response. I'm still kind of new
> to Lua so if you could provide me a little source code
> example, I would appreciate it.

Your problem seems to be a C++ problem not a lua problem.

> variable called font_size. Because my functions are
> static, my variable is forced to be static.

Well yes.  Do you want your functions to be static or not?

> 
> 
> class ConversationGameMode
> {
> public:
>     static int MakeChoice(lua_State* ls);
>     static int SetFontSize(lua_State* ls);
> 
> private:
>     // This is what I would like to do but can't
>     // int font_size;
> }
> // This is what I end up doing
> static int font_size;

So do this:

class ConversationGameMode
{
public:
    static int MakeChoice(lua_State* ls);
    static int SetFontSize(lua_State* ls);

private:
    static int font_size;
}

??

> In this example, I would like a way to encapsulate
> font_size so it isn't a static (or global) variable.

Static variables can be hidden inside classes, as I showed.


> These methods didn't really need to be embedded in a
> class, but it just kind of worked out that way when I
> started trying to encapsulate things, not knowing at
> the time that I had to declare things as static.
> However, even as regular C/C++ functions, I still
> don't know how to make font_size accessable without
> making it static or global.

Well, there's global scope or file scope.

Or you can have static local variables in your functions. This
probably isn't what you want, though.

Jules

Reply | Threaded
Open this post in threaded view
|

Re: Looking for a better way with Lua, C++, and static members

Jeff Williams
In reply to this post by Eric Wing-2
------------------------------
> 
> Message: 16
> Date: Fri, 15 Aug 2003 02:19:34 -0700 (PDT)
> From: Eric Wing <[hidden email]>
> Subject: Re: Looking for a better way with Lua, C++, and static
> 	members


Here is a technique I use:

struct foo
{
   static int set_i(lua_State* L);
   int i;
};

int foo::set_i(lua_State* L)
{
  foo* pFoo = reinterpret_cast<foo*>(lua_touserdata(L, lua_upvalue(1));
  pFoo->i = lua_tonumber(L, 1);
  return 0;
}

// Code to register the function and class instance with lua
foo f;

lua_State* L = lua_open();
lua_pushstring(L, "set_i");
lua_pushlightuserdata(L, &f);
lua_pushclosure(L, foo::set_i, 1);
lua_settable(L, LUA_GLOBALSINDEX);

lua_dofile(L, "foo.lua");

lua_close(L);

contents of foo.lua
-------------------
set_i(666);




Reply | Threaded
Open this post in threaded view
|

Re: Looking for a better way with Lua, C++, and static members

Eric Wing-2
In reply to this post by Eric Wing-2
Thank you Jeff! I think this is exactly what I need.

Thanks again to everybody who answered me!
-Eric


> Date: Fri, 15 Aug 2003 14:11:21 -0400
> From: Jeff Williams <[hidden email]>
> Here is a technique I use:
> 
> struct foo
> {
>    static int set_i(lua_State* L);
>    int i;
> };
> 
> int foo::set_i(lua_State* L)
> {
>   foo* pFoo =
> reinterpret_cast<foo*>(lua_touserdata(L,
> lua_upvalue(1));
>   pFoo->i = lua_tonumber(L, 1);
>   return 0;
> }
> 
> // Code to register the function and class instance
> with lua
> foo f;
> 
> lua_State* L = lua_open();
> lua_pushstring(L, "set_i");
> lua_pushlightuserdata(L, &f);
> lua_pushclosure(L, foo::set_i, 1);
> lua_settable(L, LUA_GLOBALSINDEX);
> 
> lua_dofile(L, "foo.lua");
> 
> lua_close(L);
> 
> contents of foo.lua
> -------------------
> set_i(666);
> 


__________________________________
Do you Yahoo!?
Yahoo! SiteBuilder - Free, easy-to-use web site design software
http://sitebuilder.yahoo.com