multiple Lua states and tolua?

Started by
15 comments, last by thehurricane 21 years ago
Computability, the more I think about your approach the more I like it, and not just because I''m planning to move up to Lua 5 (unfortunately a ToLua for v5 has not been written yet, and v4 is not compatible since Lua 5 brings with it extensive changes in the tag/metadata and globals systems).

With your idea you gain the isolation of game objects but with a greater efficiency of memory. Also I like the ability to have a table full of "shared" functions and objects that would always be included in the "global" scope outside of the contained data...I''m starting to see some really interesting possiblities in my game.

Now only if I knew enough about Lua5''s inner workings to program a ToLua binder...
Advertisement
quote:Original post by Sneftel
What about a table generator function?

function charmPerson(caster, target)  spell = {}  spell.caster = caster  spell.target = target  spell.someStateVar = 3  function spell:update()    self.someStateVar = 5    self.target.charmed = true  end  return spellend-- now you can do this:myCastingOfCharmPerson = charmPerson("dave", "fred")myCastingOfCharmPerson.update()    



That is a good idea, but still more complicated from the scripters point of view...
And then there is the discussion about what we should call the table instance, where we should store it etc. Of course each script loaded already has a script id number, so i suppose it could be like

id127 = charmPerson( dave_id, fred_id )

and then if its used again
id135 = charmPerson( dave_id, bad_ass_monster_id)

Ill have to think about it

To Computability:
Thats actually quite brilliant, moving the complications onto the scriptengine...
I suppose i can even solve the problem of multiple instances in a naive fashion like this without making the scripters job harder, by just setting the package name as the (unique) script id...
Very interesting..

Gamedev really is a cool place
I enjoyed seeing the positive feedback on my idea. Here is some code to help you out:


            //setPackage will create a new table with the same name as package_name//It will then set a metatable on the globals table to handle//getting values out of nonexisting keys and setting values for//nonexistant keys.void CLua::setPackage(const char* package_name){		m_packageName = (char*)package_name;	lua_pushstring(m_L,package_name);		//push the key name	lua_rawget(m_L,LUA_GLOBALSINDEX);		//Get the table in the globals table	if (lua_type(m_L,-1) != LUA_TTABLE)		//if it's not a table then it was not found, so create it	{		//create the table		lua_newtable(m_L);					//Create the new table on top of stack		lua_pushstring(m_L,package_name);	//Push the key name		lua_pushvalue(m_L,-2);				//Push the table		lua_rawset(m_L,LUA_GLOBALSINDEX);	//Create the element in the globals table to point to the new table	}	lua_pushstring(m_L,m_packageName);	lua_rawget(m_L,LUA_GLOBALSINDEX);	lua_newtable(m_L);					//pushes the metatable onto the stack			-3	lua_pushstring(m_L,"__newindex");	//pushes the key name for the metatable			-2	lua_pushvalue(m_L,-3);				//push the value of the new key on to the stack -1		lua_rawset(m_L,-3);					//set the metatable event (metatable is now at the top of the stack)	lua_pushstring(m_L,"__index");	lua_pushvalue(m_L,-3);				//push the value of the new key on to the stack -1		lua_rawset(m_L,-3);					//set the metatable event (metatable is now at the top of the stack)	lua_setmetatable(m_L,LUA_GLOBALSINDEX);	//Assign the metatable at the top of the stack to the GLOBALS table	lua_pop(m_L,2);						// Pop the package table and the new metatable}//createPackage will create a package table if one doesn't already//exist. It does not set the current package. Normally you will//not need to use this function but instead just call setPackage(...)//which will create and set the package.//This function is more of a synonym for "createTable(...)" which can be//useful to have.void CLua::createPackage(const char* package_name){		lua_pushstring(m_L,package_name);		//push the key name	lua_rawget(m_L,LUA_GLOBALSINDEX);		//Get the table in the globals table	if (lua_type(m_L,-1) != LUA_TTABLE)		//if it's not a table then it was not found, so create it	{		//create the table		lua_newtable(m_L);					//Create the new table on top of stack		lua_pushstring(m_L,package_name);	//Push the key name		lua_pushvalue(m_L,-2);				//Push the table		lua_rawset(m_L,LUA_GLOBALSINDEX);	//Create the element in the globals table to point to the new table	}	lua_pop(m_L,1);							//Clean up the stack}//Release package will set the specified package table to null and then also//remove the metatable from the GLOBALS table.void CLua::releasePackage(const char* package_name){		lua_pushnil(m_L);	lua_setmetatable(m_L,LUA_GLOBALSINDEX);	lua_pushstring(m_L,package_name);	lua_pushnil(m_L);	lua_settable(m_L,LUA_GLOBALSINDEX);	}//Close package simply removes the metatable from the globals table.//The package table still remains and it is possible from any script//to do something like://	PackageName.myVariable = "hello";void CDysLua::closePackage(void){		lua_pushnil(m_L);	lua_setmetatable(m_L,LUA_GLOBALSINDEX);		}            


Some key points about the above code.
I wrapped Lua using a class named CLua. CLua has the following member variables that need to be declared in the class:

lua_State* m_L; //Pointer to the Lua state
char* m_packageName; //Name of the current package

Trying to read the code is not too easy but hopefully the comments help.

Technically these functions could have been more elegantly implemented in native Lua code and then executed, but I like to think that implementing these functions in C is more efficient and fits better into the engine.

Along with functions for handling packages my wrapper also makes it easy to call Lua functions in scripts from C. It also makes it easy for a C function to easily open up tables and get values and then open tables inside tables, etc. Very fun features but I don't normally allow C functions to work directly with Lua variables but it's nice to know that feature is there If you would like to see the code for the whole wrapper I would be more then willing to post it.

--- COMPUTABILITY ---

[edited by - Computability on April 1, 2003 4:13:13 AM]
--- COMPUTABILITY ---
I think i understand your code ok, but i wouldnt mind seeing the whole thing

It seems it can even impose a security model on the scripts by giving them a different globals table depending on what their permissions are.....

Ok. I went ahead and posted my Lua wrapper. You can get it at:
DysLua - Lua wrapper

CDysLua - added support for calling Lua functions, manipulating the stack, etc.

CDysLuaTable - Allows you to open up tables in the Lua environment and manipulate them.

main.cpp - Testbed for these classes functionality.

Enjoy.





--- COMPUTABILITY ---
--- COMPUTABILITY ---
Thanks for posting your project--I just got it to compile and I''m really going to dig in and see how I can apply it to my game--I''ll let you know how things go.
quote:Original post by thehurricane
Thanks for posting your project--I just got it to compile and I''m really going to dig in and see how I can apply it to my game--I''ll let you know how things go.


Ok great. Definitely let me know how well you can apply it to your game. And if you can think of any improvements please let me know; I''m trying to make the wrapper as complete as possible.



--- COMPUTABILITY ---
--- COMPUTABILITY ---

This topic is closed to new replies.

Advertisement