lua-users home
lua-l archive

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

On Thu, Jun 13, 2002 at 10:51:38AM +0100, Daniel Silverstone wrote:
> Unfortunately you ultimately need the relationship which you have for
> cLuaState->lua_State to work back the other way for lua_State->cLuaState
> Your choices really are:
>      1. Alter lua_State to include a cLuaState*
>      2. Create a static mapping somewhere from lua_State* to cLuaState*

You need the mapping,  but I believe there is a third option.

What if you store the cLuaState not as a field in lua_State,
but as an userdata object inside the lua_State itself?
This is not the most efficient way to get it done,  but requires
no fiddling with the internals of lua.

I've had to this last week, in a module of our system.  I wanted to
use an independent lua_State to parse a configuration script, since we
may have to be able to have multiple instances of this module at the
same time.  Requires this lua_State->instance mapping just the same way.

Abbreviating parts of the code:

MarkerHandler::read_file(std::string fname)
  lua_State *lua_s = lua_open(0);

  lua_pushusertag(lua_s, static_cast<void*>(this), LUA_ANYTAG);
  lua_setglobal (lua_s, "MARKERHANDLERPTR");

  lua_register(lua_s,"markers", MarkerHandler::general_frame_marker);

  lua_dofile(lua_s, fname.c_str());


In this case the file has multiple calls to the static method

/* static */ int
MarkerHandler::general_frame_marker(lua_State *lua_s)
  //// ... do a lot of stuff with the parameters

  /// This figures out the actual instance of the MarkerHandler.

  lua_getglobal(lua_s, "MARKERHANDLERPTR");
  MarkerHandler *mh = static_cast<MarkerHandler*>(lua_touserdata  (lua_s, 3));

  //  access the method of the right instance.
  mh->set_frame_markers(frame_number, vecmark); 

  // no return value for the lua interpreter 
  return 0;

> unfortunately that's it. Now either you map it inside the cLuaState object,
> or you'll have to map it elsewhere.
> The only other option is to make all the functions which need the cLuaState
> pointer use a userdata to pass that in as a closure value.
> The last option is perhaps what you'll end up doing, but isn't the most
> elegant due to a need to remember to do that for each function you register
> D.
> -- 
> Daniel Silverstone                     
> Hostmaster, Webmaster, and Chief Code Wibbler          Digital-Scurf Unlimited
> GPG Public key available from               KeyId: 20687895
> You will be winged by an anti-aircraft battery.

Siome Klein Goldenstein