lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]

> >From: Falko Poiker <>

> >The other reason I don't want to use tolua, and this seems to be a
> >with lua in general, is that it creates wrapper functions for every
> >and object/structure element accessed by lua.
> No really. You only need to create wrapper functions for each *type*.
> Variables are exported to Lua as userdata, and variables of the same type
> have the same tag, so that they can share the get/setglobal tag methods.
> This is exactly what tolua does.
Hmmm... That doesn't seem to be what I'm experiencing.  I have a large
number of variables in my tolua.pkg file, and tolua creates a
toluaI_set_<varname> and a toluaI_get_<varname> function for every one,
whether the variable is a float, int or a user defined type (in the example
below, the vector4 class).

> If you need concrete examples of how to do all this, post some
> declarations of your variables and I'll send you some sample code.
Okay, in my tolua.pkg file I have (among other things) the following:

class vector4 {
    float x;
	float y;
	float z;
	float w;
	vector4() {}
    vector4(float _x, float _y, float _z, float _w) { x = _x; y = _y; z =
_z; w = _w; }

    void set(float _x, float _y, float _z, float _w) { x = _x; y = _y; z =
_z; w = _w; }

	// some other methods

    Pieplate tweakables:
extern int twkPiePieces;
extern int twkHorizonPieces;
extern real32 twkPieClosestDistance;
extern real32 twkMaxMovementDist;
extern real32 twkHorizontalHashMarkLength;
extern real32 twkVerticalHashMarkLength;
extern real32 twkHeightSnap;
extern real32 twkShipCloseToPlaneDistance;
extern real32 twkPieCircleSizeMax;       
extern real32 twkPieCircleSizeMin;       
extern real32 twkHeightFactor;

extern vector4 test;
extern vector4 twkInnerPieColour;
extern vector4 twkRangePieColour;
extern vector4 twkOuterPieColour;
extern vector4 twkMoveToDiscColour;
extern vector4 twkMoveToPlanarDiscColour;
extern vector4 twkShipOnPlaneColour;
extern vector4 twkClosestShipOnPlaneColour;

This package file creates 2 functions for every variable (registered
internally to tolua using the functions calls "tolua_tablevar" and
"tolua_globalvar").  For example, for the "test" variable, the
tolua_XXX_open function has the line


and the functions

/* get function: test */
static void toluaI_get_test(void)

/* set function: test */
static void toluaI_set_test(void)
  if (!tolua_istype(1,tolua_tag_vector4,0))
   tolua_error("#vinvalid type in variable assignment.");
  test = *((vector4*)  tolua_getusertype(1,0));

> >Homeworld (our last game) had
> >over 10,000 tweakables, so exposing this number of variables to lua would
> >result in over 1 megabyte of memory usage simply for the function
> Do you really have 10,000 different *types*?
No, 10,000 different variables.  Very few types - most are real, int, char
or vector.

> >So I've been considering another option - modifying the lua code so that
> >modifies the game variables directly.
> You could do this of course, although I don't see you can avoid having
> types in the Value union.
> >1. there is no need to pre-register any of the game's variables with Lua
> >the variables are accessed on a "need to know" basis.
> Again, I don't see you can avoid this.
Well, I've been poking around a bit, and here's a code snippet of what it
would look like:

// From lvm.c  of version 3.2

void luaV_setglobal (TaggedString *ts) {
  // Falko's modification
  //was: TObject *oldvalue = &ts->u.s.globalval;
  TObject *oldvalue = getGameGlobal(ts->str, &ts->u.s.globalval);

  TObject *im = luaT_getimbyObj(oldvalue, IM_SETGLOBAL);
  if (ttype(im) == LUA_T_NIL)  /* is there a tag method? */
      // added by Falko
      setGameGlobal(ts->str, L->>value.n);
    luaS_rawsetglobal(ts, --L->;
  else {
    /* WARNING: caller must assure stack space */
    struct Stack *S = &L->stack;
    TObject newvalue;
    newvalue = *(S->top-1);
    ttype(S->top-1) = LUA_T_STRING;
    tsvalue(S->top-1) = ts;
    *S->top++ = *oldvalue;
    *S->top++ = newvalue;
    luaD_callTM(im, 3, 0);

getGameGlobal compares "ts->str" with its internal list of variable names -
if it finds a game variable of the same name, it creates a "TObject" with
the correct value and returns it, if not, it returns 
setGameGlobal does the same, but sets the game variable and returns nothing.

Note that the number parameter of setGameGlobal (L->>value.n) is
only temporary.  I imagine that "setGameGlobal" would accept the value enum
directly and extract what it needs in C.

Later iterations of getGameGlobal and setGameGlobal would somehow get around
doing a string compare every time by creating a pointer to any variable
accessed to create a shortcut to that variable (possibly by defining a "game
variable" type in the Value union or something like that).

By the way, I'm only suggesting doing this because I thought I could
eliminate a bunch of work on my part.  If Lua provides a mechanism to do
this easily without modifying the lua code, I would be very pleased to know

Thanks for your help!!