🎉 Celebrating 25 Years of GameDev.net! 🎉

Not many can claim 25 years on the Internet! Join us in celebrating this milestone. Learn more about our history, and thank you for being a part of our community!

Lua C-API

Started by
5 comments, last by Biorobic 20 years, 4 months ago
Hello everyone... i started to check out LUA these days because i want to implent a scripting language to my simple OpenGL engine. i read the manual and tutorials (few..) and i think i got a good overview now. so i started to code some simple things with C++ and the lua api ... now i got a simple question: i also want to use lua to load my settings.. in my game directory, i got this file: settings.lua ... which could look like this: - fullscreen = 1; resolution = {800, 600, 32}; - now, back in c++, i want to read this values and store them in a struct or something.. here's what i got:

   lua_State* luaVM = lua_open();
 
   if (NULL == luaVM)
   {
      printf("Error Initializing lua\n");
			return;
   }
 
   // initialize lua standard library functions

   lua_baselibopen(luaVM);
   lua_iolibopen(luaVM);
   lua_strlibopen(luaVM);
   lua_mathlibopen(luaVM);
 
   lua_dofile(luaVM, "setting.lua");

	 /* (the same, work both..)
	 lua_getglobal(luaVM, "fullscreen");
	 SETTING.bFullscreen = lua_toboolean(luaVM, -1);
	 lua_pop(luaVM, 1);
	 */
	 lua_pushstring(luaVM, "fullscreen");
	 lua_gettable(luaVM, LUA_GLOBALSINDEX);
 	 SETTING.bFullscreen = lua_toboolean(luaVM, -1);
         lua_pop(luaVM, 1);

	 lua_pushstring(luaVM, "resolution");
	 lua_gettable(luaVM, LUA_GLOBALSINDEX);
	 lua_gettable(luaVM, LUA_GLOBALSINDEX);
 	 SETTING.x = lua_tonumber(luaVM, -1);
 
   lua_close(luaVM);

	 printf("fullscreen: %d\n", SETTING.bFullscreen);
	 printf("x: %d\n", SETTING.x);
	 printf("y: %d\n", SETTING.y);
	 printf("b: %d\n", SETTING.b);
now my simple question: how can i get the 3 values of "resolution" (-> 800, 600 and 32). i searched a lot but i cant find some examples of reading table values out of lua (the other way around works fine). i think i have to push the index of the value to the stack or something... please help me! tia, bio [edited by - Biorobic on February 25, 2004 6:25:10 AM]
Advertisement
The following snippet was modified from chapter 22 of the draft of 'Programming in Lua' dated January 22, 2003

-- Lua
resolution = {x = 800, y = 600, d = 32};

// C++
lua_getglobal(L, "resolution");
if (!lua_istable(L, -1))
error("‘resolution' is not a valid color table");
else {
x = getfield("x");
y = getfield("y");
depth = getfield("d");
}

Although it is possible to use lua this way I strongly recommend using a higher level approach to binding your data structures. Have a look in the scripting forum

[edited by - XXX_Andrew_XXX on February 25, 2004 6:36:55 AM]
quote: Although it is possible to use lua this way I strongly recommend using a higher level approach to binding your data structures. Have a look in the scripting forum


first, thanks for your answer are you talking about libs like luabind or tolua? i already got them downloaded and i read some articles about them, but first, before really starting, i''d like to test what "lua-only" can do.

to you code: can you tell me what happens in getfield() because this is no lua api ... ?
Whoops, sorry about that.

int getfield (const char *key) {
int result;
lua_pushstring(L, key);
lua_gettable(L, -2); /* get resolution[key] */
if (!lua_isnumber(L, -1))
error("invalid component in resolution");
result = (int)lua_tonumber(L, -1);
lua_pop(L, 1);
return result;
}
I usually take a different approach, and structure the Lua settings file as a Lua program. When interfaces and systems are initialized, the configuration file is executed as a script, looping through the configuration table and setting the various parameters. Here is a simple example:
ConfigTable={}ConfigTable[ "ScriptPath"]=             "data/scripts/"ConfigTable[ "ScreenWidth"]=            "800"ConfigTable[ "ScreenHeight"]=           "600"ConfigTable[ "BitsPerColorComponent"]=  "8"ConfigTable[ "UseFullScreen"]=          "0"ConfigTable[ "UseDepthBuffer"]=         "1"ConfigTable[ "FrameInterval"]=          "0.04"for i,j in ConfigTable do ConfigurationInterface:SetParam(i, j)end 

It''s a little bit hacky, but it works great. All configuration parameters are stored in an std::map pairing string keys with string values, and special accessor functions can query values in different formats (string, int, float, etc...) using the key name.

ConfigurationInterface:SetParam() is a function defined in C++ and exported by tolua that takes a given pair of strings (key, value) and sets an entry in the std::map held by the ConfigurationInterface.

Thereafter, whenever I need a value such as screen width, I call something like int screenwidth=ConfigurationInterface::GetIntValue("ScreenWidth"); which will convert the string value of the parameter to an int value.


Golem
Blender--The Gimp--Python--Lua--SDL
Nethack--Crawl--ADOM--Angband--Dungeondweller
I''m just getting started with scripting, and looking at Lua as an option. This thread has raised a question that is close to being on topic, so here goes.

How would you deal with saving preferences when a user changes a setting? (Like changing the default from full screen to windowed mode). Can Lua (or any mainstream script system) scripts be self modifying on disk, or would you need to write a new file if things change at run time?

I had been assuming that a Lua config file like those described here would only be good for ''constant'' settings.


Cheers,

Atlay
In my system, I have implemented a function as part of the ConfigurationInterface:: interface which will open up the config file and dump the current configuration settings, rebuilding the file with the user''s preferences.

Basically, configuration is stored in a file such as I posted earlier. Upon initialization, this file is executed as a script to set the various parameters then exit. If the user changes a parameter in-game, then the function will re-write this file with the current (changed) set of configuration data so that the next time the game loads it uses the updated configuration.

The configuration parameters themselves are stored in a std::map in C++ so that the user can change them on the fly if allowed, and see the results. Each time a parameter is changed, the settings are "saved" back into the config file.

The file is basically built by opening it up, writing the string "ConfigTable={}\n\n", then iterating through the std::map of values. For each, the value and key are composed into a string such as "ConfigTable[key]=value\n" and written to the file. Then a final string "\nfor i,j in ConfigTable do\n ConfigurationInterface:SetParam(i, j)\nend" is written, and the file is closed. Voila... an updated configuration script. It''s not very sophisticated, since every time a parameter is modified the entire file is re-written, but it works. I use it for remembering volume settings, fullscreen/windowed, graphic mode selection, Ogg Vorbis playlist settings, etc...



Golem
Blender--The Gimp--Python--Lua--SDL
Nethack--Crawl--ADOM--Angband--Dungeondweller

This topic is closed to new replies.

Advertisement