context.cpp

00001 
00002 /***************************************************************************
00003  *  context.cpp - Fawkes Lua Context
00004  *
00005  *  Created: Fri May 23 15:53:54 2008
00006  *  Copyright  2006-2009  Tim Niemueller [www.niemueller.de]
00007  *
00008  ****************************************************************************/
00009 
00010 /*  This program is free software; you can redistribute it and/or modify
00011  *  it under the terms of the GNU General Public License as published by
00012  *  the Free Software Foundation; either version 2 of the License, or
00013  *  (at your option) any later version.
00014  *
00015  *  This program is distributed in the hope that it will be useful,
00016  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00017  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018  *  GNU Library General Public License for more details.
00019  *
00020  *  Read the full text in the LICENSE.GPL file in the doc directory.
00021  */
00022 
00023 #include <lua/context.h>
00024 #include <lua/context_watcher.h>
00025 #include <core/threading/mutex.h>
00026 #include <core/threading/mutex_locker.h>
00027 #include <core/exceptions/system.h>
00028 #include <core/exceptions/software.h>
00029 #include <utils/logging/liblogger.h>
00030 
00031 #include <algorithm>
00032 #include <tolua++.h>
00033 #include <cstdlib>
00034 #include <cstring>
00035 #include <unistd.h>
00036 
00037 namespace fawkes {
00038 #if 0 /* just to make Emacs auto-indent happy */
00039 }
00040 #endif
00041 
00042 /** @class LuaContext <lua/context.h>
00043  * Lua C++ wrapper.
00044  * This thin wrapper allows for easy integration of Fawkes into other
00045  * applications. It provides convenience methods to some Lua and
00046  * tolua++ features like setting global variables or pushing/popping
00047  * values.
00048  *
00049  * It allows raw access to the Lua state since this class does not and
00050  * should not provide all the features Lua provides. If you use this
00051  * make sure that you lock the Lua context to avoid multi-threading
00052  * problems (if that is a possible concern in your application).
00053  *
00054  * LuaContext can use a FileAlterationMonitor on all added package and
00055  * C package directories. If anything changes in these directories the
00056  * Lua instance is then automatically restarted (closed, re-opened and
00057  * re-initialized).
00058  *
00059  * @author Tim Niemueller
00060  */
00061 
00062 /** Constructor.
00063  * @param watch_dirs true to watch added package and C package dirs for
00064  * changes
00065  * @param enable_tracebacks if true an error function is installed at the top
00066  * of the stackand used for pcalls where errfunc is 0.
00067  */
00068 LuaContext::LuaContext(bool watch_dirs, bool enable_tracebacks)
00069 {
00070   __owns_L = true;
00071   __enable_tracebacks = enable_tracebacks;
00072 
00073   if ( watch_dirs ) {
00074     __fam = new FileAlterationMonitor();
00075     __fam->add_filter("^[^.].*\\.lua$"); 
00076     __fam->add_listener(this);
00077   } else {
00078     __fam = NULL;
00079   }
00080   __lua_mutex = new Mutex();
00081 
00082   __start_script = NULL;
00083   __L = init_state();
00084 }
00085 
00086 
00087 /** Wrapper contstructor.
00088  * This wraps around an existing Lua state. It does not initialize the state in
00089  * the sense that it would add variables etc. It only provides convenient access
00090  * to the state methods via a C++ interface. It's mainly intended to be used to
00091  * create a LuaContext to be passed to LuaContextWatcher::lua_restarted(). The
00092  * state is not closed on destruction as is done when using the other ctor.
00093  * @param L Lua state to wrap
00094  */
00095 LuaContext::LuaContext(lua_State *L)
00096 {
00097   __owns_L = false;
00098   __L = L;
00099   __lua_mutex = new Mutex();
00100   __start_script = NULL;
00101   __fam = NULL;
00102 }
00103 
00104 /** Destructor. */
00105 LuaContext::~LuaContext()
00106 {
00107   __lua_mutex->lock();
00108   delete __fam;
00109   delete __lua_mutex;
00110   if ( __start_script )  free(__start_script);
00111   if ( __owns_L) {
00112     lua_close(__L);
00113   }
00114 }
00115 
00116 
00117 /** Initialize Lua state.
00118  * Initializes the state and makes all necessary initializations.
00119  * @return fresh initialized Lua state
00120  */
00121 lua_State *
00122 LuaContext::init_state()
00123 {
00124   lua_State *L = luaL_newstate();
00125   luaL_openlibs(L);
00126 
00127   if (__enable_tracebacks) {
00128     lua_getglobal(L, "debug");
00129     lua_getfield(L, -1, "traceback");
00130     lua_remove(L, -2);
00131   }
00132 
00133   // Add package paths
00134   for (__slit = __package_dirs.begin(); __slit != __package_dirs.end(); ++__slit) {
00135     do_string(L, "package.path = package.path .. \";%s/?.lua;%s/?/init.lua\"", __slit->c_str(), __slit->c_str());
00136   }
00137 
00138   for (__slit = __cpackage_dirs.begin(); __slit != __cpackage_dirs.end(); ++__slit) {
00139     do_string(L, "package.cpath = package.cpath .. \";%s/?.so\"", __slit->c_str());
00140   }
00141 
00142   // load base packages
00143   for (__slit = __packages.begin(); __slit != __packages.end(); ++__slit) {
00144     do_string(L, "require(\"%s\")", __slit->c_str());
00145   }
00146 
00147   for ( __utit = __usertypes.begin(); __utit != __usertypes.end(); ++__utit) {
00148     tolua_pushusertype(L, __utit->second.first, __utit->second.second.c_str());
00149     lua_setglobal(L, __utit->first.c_str());
00150   }
00151 
00152   for ( __strings_it = __strings.begin(); __strings_it != __strings.end(); ++__strings_it) {
00153     lua_pushstring(L, __strings_it->second.c_str());
00154     lua_setglobal(L, __strings_it->first.c_str());
00155   }
00156 
00157   for ( __booleans_it = __booleans.begin(); __booleans_it != __booleans.end(); ++__booleans_it) {
00158     lua_pushboolean(L, __booleans_it->second);
00159     lua_setglobal(L, __booleans_it->first.c_str());
00160   }
00161 
00162   for ( __numbers_it = __numbers.begin(); __numbers_it != __numbers.end(); ++__numbers_it) {
00163     lua_pushnumber(L, __numbers_it->second);
00164     lua_setglobal(L, __numbers_it->first.c_str());
00165   }
00166 
00167   for ( __integers_it = __integers.begin(); __integers_it != __integers.end(); ++__integers_it) {
00168     lua_pushinteger(L, __integers_it->second);
00169     lua_setglobal(L, __integers_it->first.c_str());
00170   }
00171 
00172   LuaContext *tmpctx = new LuaContext(L);
00173   MutexLocker(__watchers.mutex());
00174   LockList<LuaContextWatcher *>::iterator i;
00175   for (i = __watchers.begin(); i != __watchers.end(); ++i) {
00176     try {
00177       (*i)->lua_restarted(tmpctx);
00178     } catch (...) {
00179       delete tmpctx;
00180       lua_close(L);
00181       throw;
00182     }
00183   }
00184   delete tmpctx;
00185 
00186   if ( __start_script ) {
00187     if (access(__start_script, R_OK) == 0) {
00188       // it's a file and we can access it, execute it!
00189       do_file(L, __start_script);
00190     } else {
00191       do_string(L, "require(\"%s\")", __start_script);
00192     }
00193   }
00194 
00195   return L;
00196 }
00197 
00198 
00199 /** Set start script.
00200  * The script will be executed once immediately in this method, make
00201  * sure you call this after all other init-relevant routines like
00202  * add_* if you need to access these in the start script!
00203  * @param start_script script to execute now and on restart(). If the
00204  * string is the path and name of an accessible file it is loaded via
00205  * do_file(), otherwise it is considered to be the name of a module and
00206  * loaded via Lua's require(). Note however, that if you use a module,
00207  * special care has to be taken to correctly modify the global
00208  * environment!
00209  */
00210 void
00211 LuaContext::set_start_script(const char *start_script)
00212 {
00213   if ( __start_script )  free(__start_script);
00214   if ( start_script ) {
00215     __start_script = strdup(start_script);
00216     if (access(__start_script, R_OK) == 0) {
00217       // it's a file and we can access it, execute it!
00218       do_file(__start_script);
00219     } else {
00220       do_string("require(\"%s\")", __start_script);
00221     }
00222   } else {
00223     __start_script = NULL;
00224   }
00225 }
00226 
00227 
00228 /** Restart Lua.
00229  * Creates a new Lua state, initializes it, anf if this went well the
00230  * current state is swapped with the new state.
00231  */
00232 void
00233 LuaContext::restart()
00234 {
00235   MutexLocker lock(__lua_mutex);
00236   try {
00237     lua_State *L = init_state();
00238     lua_State *tL = __L;
00239     __L = L;
00240     lua_close(tL);
00241 
00242   } catch (Exception &e) {
00243     LibLogger::log_error("LuaContext", "Could not restart Lua instance, an error "
00244                          "occured while initializing new state. Keeping old state.");
00245     LibLogger::log_error("LuaContext", e);
00246   }
00247 }
00248 
00249 
00250 /** Add a Lua package directory.
00251  * The directory is added to the search path for lua packages. Files with
00252  * a .lua suffix will be considered as Lua modules.
00253  * @param path path to add
00254  */
00255 void
00256 LuaContext::add_package_dir(const char *path)
00257 {
00258   MutexLocker lock(__lua_mutex);
00259 
00260   do_string(__L, "package.path = package.path .. \";%s/?.lua;%s/?/init.lua\"", path, path);
00261 
00262   __package_dirs.push_back(path);
00263   if ( __fam )  __fam->watch_dir(path);
00264 }
00265 
00266 
00267 /** Add a Lua C package directory.
00268  * The directory is added to the search path for lua C packages. Files
00269  * with a .so suffix will be considered as Lua modules.
00270  * @param path path to add
00271  */
00272 void
00273 LuaContext::add_cpackage_dir(const char *path)
00274 {
00275   MutexLocker lock(__lua_mutex);
00276 
00277   do_string(__L, "package.cpath = package.cpath .. \";%s/?.so\"", path);
00278 
00279   __cpackage_dirs.push_back(path);
00280   if ( __fam )  __fam->watch_dir(path);
00281 }
00282 
00283 
00284 /** Add a default package.
00285  * Packages that are added this way are automatically loaded now and
00286  * on restart().
00287  * @param package package to add
00288  */
00289 void
00290 LuaContext::add_package(const char *package)
00291 {
00292   MutexLocker lock(__lua_mutex);
00293   if (find(__packages.begin(), __packages.end(), package) == __packages.end()) {
00294     do_string(__L, "require(\"%s\")", package);
00295 
00296     __packages.push_back(package);
00297   }
00298 }
00299 
00300 
00301 /** Get Lua state.
00302  * Allows for raw modification of the used Lua state. Remember proper
00303  * locking!
00304  * @return Currently used Lua state
00305  */
00306 lua_State *
00307 LuaContext::get_lua_state()
00308 {
00309   return __L;
00310 }
00311 
00312 
00313 /** Lock Lua state. */
00314 void
00315 LuaContext::lock()
00316 {
00317   __lua_mutex->lock();
00318 }
00319 
00320 
00321 /** Try to lock the Lua state.
00322  * @return true if the state has been locked, false otherwise.
00323  */
00324 bool
00325 LuaContext::try_lock()
00326 {
00327   return __lua_mutex->try_lock();
00328 }
00329 
00330 
00331 /** Unlock Lua state. */
00332 void
00333 LuaContext::unlock()
00334 {
00335   __lua_mutex->unlock();
00336 }
00337 
00338 
00339 /** Execute file.
00340  * @param filename filet to load and excute.
00341  */
00342 void
00343 LuaContext::do_file(const char *filename)
00344 {
00345   MutexLocker lock(__lua_mutex);
00346   do_file(__L, filename);
00347 }
00348 
00349 
00350 /** Execute file on a specific Lua state.
00351  * @param L Lua state to execute the file in.
00352  * @param filename filet to load and excute.
00353  */
00354 void
00355 LuaContext::do_file(lua_State *L, const char *filename)
00356 {
00357   // Load initialization code
00358   int err = 0;
00359   std::string errmsg;
00360   if ( (err = luaL_loadfile(L, filename)) != 0) {
00361     errmsg = lua_tostring(L, -1);
00362     lua_pop(L, 1);
00363     switch (err) {
00364     case LUA_ERRSYNTAX:
00365       throw SyntaxErrorException("Lua syntax error in file %s: %s", filename, errmsg.c_str());
00366 
00367     case LUA_ERRMEM:
00368       throw OutOfMemoryException("Could not load Lua file %s", filename);
00369 
00370     case LUA_ERRFILE:
00371       throw CouldNotOpenFileException(filename, errmsg.c_str());
00372     }
00373   }
00374 
00375   int errfunc = __enable_tracebacks ? 1 : 0;
00376   if ( (err = lua_pcall(L, 0, LUA_MULTRET, errfunc)) != 0 ) {
00377     // There was an error while executing the initialization file
00378     errmsg = lua_tostring(L, -1);
00379     lua_pop(L, 1);
00380     switch (err) {
00381     case LUA_ERRRUN:
00382       throw LuaRuntimeException("do_file", errmsg.c_str());
00383 
00384     case LUA_ERRMEM:
00385       throw OutOfMemoryException("Could not execute Lua file %s", filename);
00386 
00387     case LUA_ERRERR:
00388       throw LuaErrorException("do_file", errmsg.c_str());
00389 
00390     default:
00391       throw LuaErrorException("do_file/unknown error", errmsg.c_str());
00392     }
00393   }
00394 
00395 }
00396 
00397 
00398 /** Execute string on a specific Lua state.
00399  * @param L Lua state to execute the string in
00400  * @param format format of string to execute, arguments can be the same as
00401  * for vasprintf.
00402  */
00403 void
00404 LuaContext::do_string(lua_State *L, const char *format, ...)
00405 {
00406   va_list arg;
00407   va_start(arg, format);
00408   char *s;
00409   if (vasprintf(&s, format, arg) == -1) {
00410     throw Exception("LuaContext::do_string: Could not form string");
00411   }
00412 
00413   int rv = 0;
00414   int errfunc = __enable_tracebacks ? 1 : 0;
00415   rv = (luaL_loadstring(L, s) || lua_pcall(L, 0, LUA_MULTRET, errfunc));
00416 
00417   free(s);
00418   va_end(arg);
00419 
00420   if (rv != 0) {
00421     std::string errmsg = lua_tostring(L, -1);
00422     lua_pop(L, 1);
00423     throw LuaRuntimeException("do_string", errmsg.c_str());
00424   }
00425 }
00426 
00427 
00428 /** Execute string.
00429  * @param format format of string to execute, arguments can be the same as
00430  * for vasprintf.
00431  */
00432 void
00433 LuaContext::do_string(const char *format, ...)
00434 {
00435   MutexLocker lock(__lua_mutex);
00436   va_list arg;
00437   va_start(arg, format);
00438   char *s;
00439   if (vasprintf(&s, format, arg) == -1) {
00440     throw Exception("LuaContext::do_string: Could not form string");
00441   }
00442 
00443   int rv = 0;
00444   int errfunc = __enable_tracebacks ? 1 : 0;
00445   rv = (luaL_loadstring(__L, s) || lua_pcall(__L, 0, LUA_MULTRET, errfunc));
00446 
00447   free(s);
00448   va_end(arg);
00449 
00450   if ( rv != 0 ) {
00451     std::string errmsg = lua_tostring(__L, -1);
00452     lua_pop(__L, 1);
00453     throw LuaRuntimeException("do_string", errmsg.c_str());
00454   }
00455 }
00456 
00457 
00458 /** Load Lua string.
00459  * Loads the Lua string and places it as a function on top of the stack.
00460  * @param s string to load
00461  */
00462 void
00463 LuaContext::load_string(const char *s)
00464 {
00465   int err;
00466   if ( (err = luaL_loadstring(__L, s)) != 0 ) {
00467     std::string errmsg = lua_tostring(__L, -1);
00468     lua_pop(__L, 1);
00469     switch (err) {
00470     case LUA_ERRSYNTAX:
00471       throw SyntaxErrorException("Lua syntax error in string '%s': %s",
00472                                  s, errmsg.c_str());
00473 
00474     case LUA_ERRMEM:
00475       throw OutOfMemoryException("Could not load Lua string '%s'", s);
00476     }
00477   }
00478 }
00479 
00480 
00481 /** Protected call.
00482  * Calls the function on top of the stack. Errors are handled gracefully.
00483  * @param nargs number of arguments
00484  * @param nresults number of results
00485  * @param errfunc stack index of an error handling function
00486  * @exception Exception thrown for generic runtime error or if the
00487  * error function could not be executed.
00488  * @exception OutOfMemoryException thrown if not enough memory was available
00489  */
00490 void
00491 LuaContext::pcall(int nargs, int nresults, int errfunc)
00492 {
00493   int err = 0;
00494   if ( ! errfunc && __enable_tracebacks )  errfunc = 1;
00495   if ( (err = lua_pcall(__L, nargs, nresults, errfunc)) != 0 ) {
00496     std::string errmsg = lua_tostring(__L, -1);
00497     lua_pop(__L, 1);
00498     switch (err) {
00499     case LUA_ERRRUN:
00500       throw LuaRuntimeException("pcall", errmsg.c_str());
00501 
00502     case LUA_ERRMEM:
00503       throw OutOfMemoryException("Could not execute Lua chunk via pcall");
00504 
00505     case LUA_ERRERR:
00506       throw LuaErrorException("pcall", errmsg.c_str());
00507     }
00508   }
00509 }
00510 
00511 
00512 /** Assert that the name is unique.
00513  * Checks the internal context structures if the name has been used
00514  * already. It will accept a value that has already been set that is of the same
00515  * type as the one supplied. Pass the empty string to avoid this.
00516  * @param name name to check
00517  * @param type type of value
00518  * @exception Exception thrown if name is not unique
00519  */
00520 void
00521 LuaContext::assert_unique_name(const char *name, std::string type)
00522 {
00523   if ( (type != "usertype") && (__usertypes.find(name) != __usertypes.end()) ) {
00524     throw Exception("User type entry already exists for name %s", name);
00525   }
00526   if ( (type != "string") && (__strings.find(name) != __strings.end()) ) {
00527     throw Exception("String entry already exists for name %s", name);
00528   }
00529   if ( (type != "boolean") && (__booleans.find(name) != __booleans.end()) ) {
00530     throw Exception("Boolean entry already exists for name %s", name);
00531   }
00532   if ( (type != "number") && (__numbers.find(name) != __numbers.end()) ) {
00533     throw Exception("Number entry already exists for name %s", name);
00534   }
00535   if ( (type != "integer") && (__integers.find(name) != __integers.end()) ) {
00536     throw Exception("Integer entry already exists for name %s", name);
00537   }
00538 }
00539 
00540 
00541 /** Assign usertype to global variable.
00542  * @param name name of global variable to assign the value to
00543  * @param data usertype data
00544  * @param type_name type name of the data
00545  * @param name_space C++ namespace of type, prepended to type_name
00546  */
00547 void
00548 LuaContext::set_usertype(const char *name, void *data,
00549                           const char *type_name, const char *name_space)
00550 {
00551   MutexLocker lock(__lua_mutex);
00552 
00553   std::string type_n = type_name;
00554   if ( name_space ) {
00555     type_n = std::string(name_space) + "::" + type_name;
00556   }
00557 
00558   assert_unique_name(name, "usertype");
00559 
00560   __usertypes[name] = std::make_pair(data, type_n);
00561 
00562   tolua_pushusertype(__L, data, type_n.c_str());
00563   lua_setglobal(__L, name);
00564 }
00565 
00566 
00567 /** Assign string to global variable.
00568  * @param name name of global variable to assign the value to
00569  * @param value value to assign
00570  */
00571 void
00572 LuaContext::set_string(const char *name, const char *value)
00573 {
00574   MutexLocker lock(__lua_mutex);
00575   assert_unique_name(name, "string");
00576 
00577   __strings[name] = value;
00578 
00579   lua_pushstring(__L, value);
00580   lua_setglobal(__L, name);
00581 }
00582 
00583 
00584 /** Assign boolean to global variable.
00585  * @param name name of global variable to assign the value to
00586  * @param value value to assign
00587  */
00588 void
00589 LuaContext::set_boolean(const char *name, bool value)
00590 {
00591   MutexLocker lock(__lua_mutex);
00592   assert_unique_name(name, "boolean");
00593 
00594   __booleans[name] = value;
00595 
00596   lua_pushboolean(__L, value ? 1 : 0);
00597   lua_setglobal(__L, name);
00598 }
00599 
00600 
00601 /** Assign number to global variable.
00602  * @param name name of global variable to assign the value to
00603  * @param value value to assign
00604  */
00605 void
00606 LuaContext::set_number(const char *name, lua_Number value)
00607 {
00608   MutexLocker lock(__lua_mutex);
00609   assert_unique_name(name, "number");
00610 
00611   __numbers[name] = value;
00612 
00613   lua_pushnumber(__L, value);
00614   lua_setglobal(__L, name);
00615 }
00616 
00617 
00618 /** Assign integer to global variable.
00619  * @param name name of global variable to assign the value to
00620  * @param value value to assign
00621  */
00622 void
00623 LuaContext::set_integer(const char *name, lua_Integer value)
00624 {
00625   MutexLocker lock(__lua_mutex);
00626   assert_unique_name(name, "integer");
00627 
00628   __integers[name] = value;
00629 
00630   lua_pushinteger(__L, value);
00631   lua_setglobal(__L, name);
00632 }
00633 
00634 
00635 /** Push boolean on top of stack.
00636  * @param value value to push
00637  */
00638 void
00639 LuaContext::push_boolean(bool value)
00640 {
00641   MutexLocker lock(__lua_mutex);
00642   lua_pushboolean(__L, value ? 1 : 0);
00643 }
00644 
00645 
00646 /** Push formatted string on top of stack.
00647  * @param format string format
00648  * @see man 3 sprintf
00649  */
00650 void
00651 LuaContext::push_fstring(const char *format, ...)
00652 {
00653   MutexLocker lock(__lua_mutex);
00654   va_list arg;
00655   va_start(arg, format);
00656   lua_pushvfstring(__L, format, arg);
00657   va_end(arg);
00658 }
00659 
00660 
00661 /** Push integer on top of stack.
00662  * @param value value to push
00663  */
00664 void
00665 LuaContext::push_integer(lua_Integer value)
00666 {
00667   MutexLocker lock(__lua_mutex);
00668   lua_pushinteger(__L, value);
00669 }
00670 
00671 
00672 /** Push light user data on top of stack.
00673  * @param p pointer to light user data to push
00674  */
00675 void
00676 LuaContext::push_light_user_data(void *p)
00677 {
00678   MutexLocker lock(__lua_mutex);
00679   lua_pushlightuserdata(__L, p);
00680 }
00681 
00682 
00683 /** Push substring on top of stack.
00684  * @param s string to push
00685  * @param len length of string to push
00686  */
00687 void
00688 LuaContext::push_lstring(const char *s, size_t len)
00689 {
00690   MutexLocker lock(__lua_mutex);
00691   lua_pushlstring(__L, s, len);
00692 }
00693 
00694 
00695 /** Push nil on top of stack.
00696  */
00697 void
00698 LuaContext::push_nil()
00699 {
00700   MutexLocker lock(__lua_mutex);
00701   lua_pushnil(__L);
00702 }
00703 
00704 
00705 /** Push number on top of stack.
00706  * @param value value to push
00707  */
00708 void
00709 LuaContext::push_number(lua_Number value)
00710 {
00711   MutexLocker lock(__lua_mutex);
00712   lua_pushnumber(__L, value);
00713 }
00714 
00715 
00716 /** Push string on top of stack.
00717  * @param value value to push
00718  */
00719 void
00720 LuaContext::push_string(const char *value)
00721 {
00722   MutexLocker lock(__lua_mutex);
00723   lua_pushstring(__L, value);
00724 }
00725 
00726 
00727 /** Push thread on top of stack.
00728  */
00729 void
00730 LuaContext::push_thread()
00731 {
00732   MutexLocker lock(__lua_mutex);
00733   lua_pushthread(__L);
00734 }
00735 
00736 
00737 /** Push a copy of the element at the given index on top of the stack.
00738  * @param idx index of the value to copy
00739  */
00740 void
00741 LuaContext::push_value(int idx)
00742 {
00743   MutexLocker lock(__lua_mutex);
00744   lua_pushvalue(__L, idx);
00745 }
00746 
00747 
00748 /** Push formatted string on top of stack.
00749  * @param format string format
00750  * @param arg variadic argument list
00751  * @see man 3 sprintf
00752  */
00753 void
00754 LuaContext::push_vfstring(const char *format, va_list arg)
00755 {
00756   MutexLocker lock(__lua_mutex);
00757   lua_pushvfstring(__L, format, arg);
00758 }
00759 
00760 
00761 /** Push usertype on top of stack.
00762  * @param data usertype data
00763  * @param type_name type name of the data
00764  * @param name_space C++ namespace of type, prepended to type_name
00765  */
00766 void
00767 LuaContext::push_usertype(void *data, const char *type_name,
00768                           const char *name_space)
00769 {
00770   MutexLocker lock(__lua_mutex);
00771 
00772   std::string type_n = type_name;
00773   if ( name_space ) {
00774     type_n = std::string(name_space) + "::" + type_name;
00775   }
00776 
00777   tolua_pushusertype(__L, data, type_n.c_str());
00778 }
00779 
00780 
00781 /** Pop value(s) from stack.
00782  * @param n number of values to pop
00783  */
00784 void
00785 LuaContext::pop(int n)
00786 {
00787   MutexLocker lock(__lua_mutex);
00788   if (__enable_tracebacks && (n >= stack_size())) {
00789     throw LuaRuntimeException("pop", "Cannot pop traceback function, invalid n");
00790   }
00791   lua_pop(__L, n);
00792 }
00793 
00794 /** Remove value from stack.
00795  * @param idx index of element to remove
00796  */
00797 void
00798 LuaContext::remove(int idx)
00799 {
00800   MutexLocker lock(__lua_mutex);
00801   if (__enable_tracebacks && ((idx == 1) || (idx == -stack_size()))) {
00802     throw LuaRuntimeException("pop", "Cannot remove traceback function");
00803   }
00804   lua_remove(__L, idx);
00805 }
00806 
00807 
00808 /** Get size of stack.
00809  * @return number of elements on the stack
00810  */
00811 int
00812 LuaContext::stack_size()
00813 {
00814   return lua_gettop(__L);
00815 }
00816 
00817 
00818 /** Create a table on top of the stack.
00819  * @param narr number of array elements
00820  * @param nrec number of non-array elements
00821  */
00822 void
00823 LuaContext::create_table(int narr, int nrec)
00824 {
00825   lua_createtable(__L, narr, nrec);
00826 }
00827 
00828 
00829 /** Set value of a table.
00830  * Sets value t[k] = v. t is the table at the given index, by default it is the
00831  * third-last entry (index is -3). v is the value at the top of the stack, k
00832  * is the element just below the top.
00833  * @param t_index index of the table on the stack
00834  */
00835 void
00836 LuaContext::set_table(int t_index)
00837 {
00838   lua_settable(__L, t_index);
00839 }
00840 
00841 
00842 /** Set field of a table.  Does the equivalent to t[k] = v, where t is
00843  * the value at the given valid index and v is the value at the top of
00844  * the stack.  This function pops the value from the stack. As in Lua,
00845  * this function may trigger a metamethod for the "newindex" event.
00846  * @param key key of the field to set @param t_index index of the
00847  * table on the stack, defaults to the element just below the value to
00848  * set (-2, second last element on the stack).
00849  */
00850 void
00851 LuaContext::set_field(const char *key, int t_index)
00852 {
00853   lua_setfield(__L, t_index, key);
00854 }
00855 
00856 
00857 /** Set a global value.
00858  * Sets the global variable with the given name to the value currently on top
00859  * of the stack. No check whatsoever regarding the name is done.
00860  * @param name name of the variable to assign
00861  */
00862 void
00863 LuaContext::set_global(const char *name)
00864 {
00865   lua_setglobal(__L, name);
00866 }
00867 
00868 
00869 /** Get value from table.
00870  * Assumes that an index k is at the top of the stack. Then t[k] is retrieved,
00871  * where t is a table at the given index idx. The resulting value is pushed
00872  * onto the stack, while the key k is popped from the stack, thus the value
00873  * replaces the key.
00874  * @param idx index of the table on the stack
00875  */
00876 void
00877 LuaContext::get_table(int idx)
00878 {
00879   lua_gettable(__L, idx);
00880 }
00881 
00882 
00883 /** Get named value from table.
00884  * Retrieves the t[k], where k is the given key and t is a table at the given
00885  * index idx. The value is pushed onto the stack.
00886  * @param idx index of the table
00887  * @param k key of the table entry
00888  */
00889 void
00890 LuaContext::get_field(int idx, const char *k)
00891 {
00892   lua_getfield(__L, idx, k);
00893 }
00894 
00895 
00896 /** Set value without invoking meta methods.
00897  * Similar to set_table(), but does raw access, i.e. without invoking meta-methods.
00898  * @param idx index of the table
00899  */
00900 void
00901 LuaContext::raw_set(int idx)
00902 {
00903   lua_rawset(__L, idx);
00904 }
00905 
00906 
00907 /** Set indexed value without invoking meta methods.
00908  * Sets t[n]=v, where t is a table at index idx and v is the value at the
00909  * top of the stack.
00910  * @param idx index of the table
00911  * @param n index in the table
00912  */
00913 void
00914 LuaContext::raw_seti(int idx, int n)
00915 {
00916   lua_rawseti(__L, idx, n);
00917 }
00918 
00919 
00920 /** Get value without invoking meta methods.
00921  * Similar to get_table(), but does raw access, i.e. without invoking meta-methods.
00922  * @param idx index of the table
00923  */
00924 void
00925 LuaContext::raw_get(int idx)
00926 {
00927   lua_rawget(__L, idx);
00928 }
00929 
00930 
00931 /** Get indexed value without invoking meta methods.
00932  * Pushes t[n] onto the stack, where t is a table at index idx.
00933  * @param idx index of the table
00934  * @param n index in the table
00935  */
00936 void
00937 LuaContext::raw_geti(int idx, int n)
00938 {
00939   lua_rawgeti(__L, idx, n);
00940 }
00941 
00942 
00943 /** Get global variable.
00944  * @param name name of the global variable
00945  */
00946 void
00947 LuaContext::get_global(const char *name)
00948 {
00949   lua_getglobal(__L, name);
00950 }
00951 
00952 
00953 /** Remove global variable.
00954  * Assigns nil to the given variable and removes it from internal
00955  * assignment maps.
00956  * @param name name of value to remove
00957  */
00958 void
00959 LuaContext::remove_global(const char *name)
00960 {
00961   MutexLocker lock(__lua_mutex);
00962 
00963   __usertypes.erase(name);
00964   __strings.erase(name);
00965   __booleans.erase(name);
00966   __numbers.erase(name);
00967   __integers.erase(name);
00968 
00969   lua_pushnil(__L);
00970   lua_setglobal(__L, name);
00971 }
00972 
00973 
00974 /** Retrieve stack value as number.
00975  * @param idx stack index of value
00976  * @return value as number
00977  */
00978 lua_Number
00979 LuaContext::to_number(int idx)
00980 {
00981   return lua_tonumber(__L, idx);
00982 }
00983 
00984 
00985 /** Retrieve stack value as integer.
00986  * @param idx stack index of value
00987  * @return value as integer
00988  */
00989 lua_Integer
00990 LuaContext::to_integer(int idx)
00991 {
00992   return lua_tointeger(__L, idx);
00993 }
00994 
00995 
00996 /** Retrieve stack value as boolean.
00997  * @param idx stack index of value
00998  * @return value as boolean
00999  */
01000 bool
01001 LuaContext::to_boolean(int idx)
01002 {
01003   return lua_toboolean(__L, idx);
01004 }
01005 
01006 
01007 /** Retrieve stack value as string.
01008  * @param idx stack index of value
01009  * @return value as string
01010  */
01011 const char *
01012 LuaContext::to_string(int idx)
01013 {
01014   return lua_tostring(__L, idx);
01015 }
01016 
01017 
01018 /** Check if stack value is a boolean.
01019  * @param idx stack index of value
01020  * @return true if value is a boolean, false otherwise
01021  */
01022 bool
01023 LuaContext::is_boolean(int idx)
01024 {
01025   return lua_isboolean(__L, idx);
01026 }
01027 
01028 
01029 /** Check if stack value is a C function.
01030  * @param idx stack index of value
01031  * @return true if value is a C function, false otherwise
01032  */
01033 bool
01034 LuaContext::is_cfunction(int idx)
01035 {
01036   return lua_iscfunction(__L, idx);
01037 }
01038 
01039 
01040 /** Check if stack value is a function.
01041  * @param idx stack index of value
01042  * @return true if value is a function, false otherwise
01043  */
01044 bool
01045 LuaContext::is_function(int idx)
01046 {
01047   return lua_isfunction(__L, idx);
01048 }
01049 
01050 
01051 /** Check if stack value is light user data.
01052  * @param idx stack index of value
01053  * @return true if value is light user data , false otherwise
01054  */
01055 bool
01056 LuaContext::is_light_user_data(int idx)
01057 {
01058   return lua_islightuserdata(__L, idx);
01059 }
01060 
01061 
01062 /** Check if stack value is nil.
01063  * @param idx stack index of value
01064  * @return true if value is nil, false otherwise
01065  */
01066 bool
01067 LuaContext::is_nil(int idx)
01068 {
01069   return lua_isnil(__L, idx);
01070 }
01071 
01072 
01073 /** Check if stack value is a number.
01074  * @param idx stack index of value
01075  * @return true if value is a number, false otherwise
01076  */
01077 bool
01078 LuaContext::is_number(int idx)
01079 {
01080   return lua_isnumber(__L, idx);
01081 }
01082 
01083 
01084 /** Check if stack value is a string.
01085  * @param idx stack index of value
01086  * @return true if value is a string, false otherwise
01087  */
01088 bool
01089 LuaContext::is_string(int idx)
01090 {
01091   return lua_isstring(__L, idx);
01092 }
01093 
01094 
01095 /** Check if stack value is a table.
01096  * @param idx stack index of value
01097  * @return true if value is a table, false otherwise
01098  */
01099 bool
01100 LuaContext::is_table(int idx)
01101 {
01102   return lua_istable(__L, idx);
01103 }
01104 
01105 
01106 /** Check if stack value is a thread.
01107  * @param idx stack index of value
01108  * @return true if value is a thread, false otherwise
01109  */
01110 bool
01111 LuaContext::is_thread(int idx)
01112 {
01113   return lua_isthread(__L, idx);
01114 }
01115 
01116 
01117 /** Get object length
01118  * @param idx stack index of value
01119  * @return size of object
01120  */
01121 size_t
01122 LuaContext::objlen(int idx)
01123 {
01124   return lua_objlen(__L, idx);
01125 }
01126 
01127 
01128 /** Set function environment.
01129  * Sets the table on top of the stack as environment of the function
01130  * at the given stack index.
01131  * @param idx stack index of function
01132  */
01133 void
01134 LuaContext::setfenv(int idx)
01135 {
01136   lua_setfenv(__L, idx);
01137 }
01138 
01139 
01140 /** Add a context watcher.
01141  * @param watcher watcher to add
01142  */
01143 void
01144 LuaContext::add_watcher(fawkes::LuaContextWatcher *watcher)
01145 {
01146   __watchers.push_back_locked(watcher);
01147 }
01148 
01149 
01150 /** Remove a context watcher.
01151  * @param watcher watcher to remove
01152  */
01153 void
01154 LuaContext::remove_watcher(fawkes::LuaContextWatcher *watcher)
01155 {
01156   __watchers.remove_locked(watcher);
01157 }
01158 
01159 
01160 
01161 /** Process FAM events. */
01162 void
01163 LuaContext::process_fam_events()
01164 {
01165   if ( __fam)  __fam->process_events();
01166 }
01167 
01168 
01169 void
01170 LuaContext::fam_event(const char *filename, unsigned int mask)
01171 {
01172   restart();
01173 }
01174 
01175 
01176 } // end of namespace fawkes

Generated on 1 Mar 2011 for Fawkes API by  doxygen 1.6.1