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