23 #include <lua/context.h> 24 #include <lua/context_watcher.h> 25 #include <core/threading/mutex.h> 26 #include <core/threading/mutex_locker.h> 27 #include <core/exceptions/system.h> 28 #include <core/exceptions/software.h> 29 #include <logging/liblogger.h> 69 __enable_tracebacks = enable_tracebacks;
73 __lua_mutex =
new Mutex();
75 __start_script = NULL;
91 __lua_mutex =
new Mutex();
92 __start_script = NULL;
103 __fam_thread->
join();
107 if ( __start_script ) free(__start_script);
127 __fam->add_filter(
"^[^.].*\\.lua$");
129 __fam->add_listener(
this);
133 __fam_thread->
start();
154 LuaContext::init_state()
156 lua_State *L = luaL_newstate();
159 if (__enable_tracebacks) {
160 lua_getglobal(L,
"debug");
161 lua_getfield(L, -1,
"traceback");
166 for (__slit = __package_dirs.begin(); __slit != __package_dirs.end(); ++__slit) {
167 do_string(L,
"package.path = package.path .. \";%s/?.lua;%s/?/init.lua\"", __slit->c_str(), __slit->c_str());
170 for (__slit = __cpackage_dirs.begin(); __slit != __cpackage_dirs.end(); ++__slit) {
171 do_string(L,
"package.cpath = package.cpath .. \";%s/?.so\"", __slit->c_str());
175 for (__slit = __packages.begin(); __slit != __packages.end(); ++__slit) {
176 do_string(L,
"require(\"%s\")", __slit->c_str());
179 for ( __utit = __usertypes.begin(); __utit != __usertypes.end(); ++__utit) {
180 tolua_pushusertype(L, __utit->second.first, __utit->second.second.c_str());
181 lua_setglobal(L, __utit->first.c_str());
184 for ( __strings_it = __strings.begin(); __strings_it != __strings.end(); ++__strings_it) {
185 lua_pushstring(L, __strings_it->second.c_str());
186 lua_setglobal(L, __strings_it->first.c_str());
189 for ( __booleans_it = __booleans.begin(); __booleans_it != __booleans.end(); ++__booleans_it) {
190 lua_pushboolean(L, __booleans_it->second);
191 lua_setglobal(L, __booleans_it->first.c_str());
194 for ( __numbers_it = __numbers.begin(); __numbers_it != __numbers.end(); ++__numbers_it) {
195 lua_pushnumber(L, __numbers_it->second);
196 lua_setglobal(L, __numbers_it->first.c_str());
199 for ( __integers_it = __integers.begin(); __integers_it != __integers.end(); ++__integers_it) {
200 lua_pushinteger(L, __integers_it->second);
201 lua_setglobal(L, __integers_it->first.c_str());
204 for ( __cfuncs_it = __cfuncs.begin(); __cfuncs_it != __cfuncs.end(); ++__cfuncs_it)
206 lua_pushcfunction(L, __cfuncs_it->second);
207 lua_setglobal(L, __cfuncs_it->first.c_str());
213 for (i = __watchers.begin(); i != __watchers.end(); ++i) {
215 (*i)->lua_restarted(tmpctx);
224 if ( __start_script ) {
225 if (access(__start_script, R_OK) == 0) {
229 do_string(L,
"require(\"%s\")", __start_script);
251 if ( __start_script ) free(__start_script);
252 if ( start_script ) {
253 __start_script = strdup(start_script);
254 if (access(__start_script, R_OK) == 0) {
258 do_string(
"require(\"%s\")", __start_script);
261 __start_script = NULL;
275 lua_State *L = init_state();
282 "occured while initializing new state. Keeping old state.");
298 do_string(__L,
"package.path = package.path .. \";%s/?.lua;%s/?/init.lua\"", path, path);
300 __package_dirs.push_back(path);
301 if ( __fam ) __fam->watch_dir(path);
315 do_string(__L,
"package.cpath = package.cpath .. \";%s/?.so\"", path);
317 __cpackage_dirs.push_back(path);
318 if ( __fam ) __fam->watch_dir(path);
331 if (find(__packages.begin(), __packages.end(), package) == __packages.end()) {
332 do_string(__L,
"require(\"%s\")", package);
334 __packages.push_back(package);
398 if ( (err = luaL_loadfile(L, filename)) != 0) {
399 errmsg = lua_tostring(L, -1);
413 int errfunc = __enable_tracebacks ? 1 : 0;
414 if ( (err = lua_pcall(L, 0, LUA_MULTRET, errfunc)) != 0 ) {
416 errmsg = lua_tostring(L, -1);
445 va_start(arg, format);
447 if (vasprintf(&s, format, arg) == -1) {
448 throw Exception(
"LuaContext::do_string: Could not form string");
452 int errfunc = __enable_tracebacks ? 1 : 0;
453 rv = (luaL_loadstring(L, s) || lua_pcall(L, 0, LUA_MULTRET, errfunc));
459 std::string errmsg = lua_tostring(L, -1);
475 va_start(arg, format);
477 if (vasprintf(&s, format, arg) == -1) {
478 throw Exception(
"LuaContext::do_string: Could not form string");
482 int errfunc = __enable_tracebacks ? 1 : 0;
483 rv = (luaL_loadstring(__L, s) || lua_pcall(__L, 0, LUA_MULTRET, errfunc));
489 std::string errmsg = lua_tostring(__L, -1);
504 if ( (err = luaL_loadstring(__L, s)) != 0 ) {
505 std::string errmsg = lua_tostring(__L, -1);
532 if ( ! errfunc && __enable_tracebacks ) errfunc = 1;
533 if ( (err = lua_pcall(__L, nargs, nresults, errfunc)) != 0 ) {
534 std::string errmsg = lua_tostring(__L, -1);
559 LuaContext::assert_unique_name(
const char *name, std::string type)
561 if ( (type ==
"usertype") && (__usertypes.find(name) != __usertypes.end()) ) {
562 throw Exception(
"User type entry already exists for name %s", name);
564 if ( (type ==
"string") && (__strings.find(name) != __strings.end()) ) {
565 throw Exception(
"String entry already exists for name %s", name);
567 if ( (type ==
"boolean") && (__booleans.find(name) != __booleans.end()) ) {
568 throw Exception(
"Boolean entry already exists for name %s", name);
570 if ( (type ==
"number") && (__numbers.find(name) != __numbers.end()) ) {
571 throw Exception(
"Number entry already exists for name %s", name);
573 if ( (type ==
"integer") && (__integers.find(name) != __integers.end()) ) {
574 throw Exception(
"Integer entry already exists for name %s", name);
576 if ( (type ==
"cfunction") && (__cfuncs.find(name) != __cfuncs.end()) ) {
577 throw Exception(
"C function entry already exists for name %s", name);
590 const char *type_name,
const char *name_space)
594 std::string type_n = type_name;
596 type_n = std::string(name_space) +
"::" + type_name;
599 assert_unique_name(name,
"usertype");
601 __usertypes[name] = std::make_pair(data, type_n);
603 tolua_pushusertype(__L, data, type_n.c_str());
604 lua_setglobal(__L, name);
616 assert_unique_name(name,
"string");
618 __strings[name] = value;
620 lua_pushstring(__L, value);
621 lua_setglobal(__L, name);
633 assert_unique_name(name,
"boolean");
635 __booleans[name] = value;
637 lua_pushboolean(__L, value ? 1 : 0);
638 lua_setglobal(__L, name);
650 assert_unique_name(name,
"number");
652 __numbers[name] = value;
654 lua_pushnumber(__L, value);
655 lua_setglobal(__L, name);
667 assert_unique_name(name,
"integer");
669 __integers[name] = value;
671 lua_pushinteger(__L, value);
672 lua_setglobal(__L, name);
684 assert_unique_name(name,
"cfunction");
688 lua_pushcfunction(__L, f);
689 lua_setglobal(__L, name);
700 lua_pushboolean(__L, value ? 1 : 0);
713 va_start(arg, format);
714 lua_pushvfstring(__L, format, arg);
726 lua_pushinteger(__L, value);
737 lua_pushlightuserdata(__L, p);
749 lua_pushlstring(__L, s, len);
770 lua_pushnumber(__L, value);
781 lua_pushstring(__L, value);
802 lua_pushvalue(__L, idx);
815 lua_pushvfstring(__L, format, arg);
826 const char *name_space)
830 std::string type_n = type_name;
832 type_n = std::string(name_space) +
"::" + type_name;
835 tolua_pushusertype(__L, data, type_n.c_str());
846 lua_pushcfunction(__L, f);
857 if (__enable_tracebacks && (n >=
stack_size())) {
870 if (__enable_tracebacks && ((idx == 1) || (idx == -
stack_size()))) {
873 lua_remove(__L, idx);
883 return lua_gettop(__L);
894 lua_createtable(__L, narr, nrec);
907 lua_settable(__L, t_index);
922 lua_setfield(__L, t_index, key);
934 lua_setglobal(__L, name);
948 lua_gettable(__L, idx);
961 lua_getfield(__L, idx, k);
972 lua_rawset(__L, idx);
985 lua_rawseti(__L, idx, n);
996 lua_rawget(__L, idx);
1008 lua_rawgeti(__L, idx, n);
1018 lua_getglobal(__L, name);
1032 __usertypes.erase(name);
1033 __strings.erase(name);
1034 __booleans.erase(name);
1035 __numbers.erase(name);
1036 __integers.erase(name);
1037 __cfuncs.erase(name);
1040 lua_setglobal(__L, name);
1051 return lua_tonumber(__L, idx);
1062 return lua_tointeger(__L, idx);
1073 return lua_toboolean(__L, idx);
1084 return lua_tostring(__L, idx);
1095 return lua_isboolean(__L, idx);
1106 return lua_iscfunction(__L, idx);
1117 return lua_isfunction(__L, idx);
1128 return lua_islightuserdata(__L, idx);
1139 return lua_isnil(__L, idx);
1150 return lua_isnumber(__L, idx);
1161 return lua_isstring(__L, idx);
1172 return lua_istable(__L, idx);
1183 return lua_isthread(__L, idx);
1194 return lua_objlen(__L, idx);
1206 lua_setfenv(__L, idx);
1216 __watchers.push_back_locked(watcher);
1226 __watchers.remove_locked(watcher);
1235 if ( __fam) __fam->process_events();
void restart()
Restart Lua.
void push_thread()
Push thread on top of stack.
File could not be opened.
void push_light_user_data(void *p)
Push light user data on top of stack.
void setup_fam(bool auto_restart, bool conc_thread)
Setup file alteration monitor.
void push_vfstring(const char *format, va_list arg)
Push formatted string on top of stack.
bool is_light_user_data(int idx)
Check if stack value is light user data.
bool is_number(int idx)
Check if stack value is a number.
void push_integer(lua_Integer value)
Push integer on top of stack.
void raw_geti(int idx, int n)
Get indexed value without invoking meta methods.
Fawkes library namespace.
void unlock()
Unlock the mutex.
bool is_thread(int idx)
Check if stack value is a thread.
void pop(int n)
Pop value(s) from stack.
void push_lstring(const char *s, size_t len)
Push substring on top of stack.
void remove(int idx)
Remove value from stack.
void set_cfunction(const char *name, lua_CFunction f)
Assign cfunction to global variable.
void add_cpackage_dir(const char *path)
Add a Lua C package directory.
void raw_seti(int idx, int n)
Set indexed value without invoking meta methods.
virtual void fam_event(const char *filename, unsigned int mask)
Event has been raised.
void load_string(const char *s)
Load Lua string.
void remove_watcher(LuaContextWatcher *watcher)
Remove a context watcher.
bool is_cfunction(int idx)
Check if stack value is a C function.
bool try_lock()
Try to lock the Lua state.
void set_field(const char *key, int t_index=-2)
Set field of a table.
void set_table(int t_index=-3)
Set value of a table.
void add_package(const char *package)
Add a default package.
void unlock()
Unlock Lua state.
static void log_error(const char *component, const char *format,...)
Log error message.
void push_value(int idx)
Push a copy of the element at the given index on top of the stack.
void push_nil()
Push nil on top of stack.
int stack_size()
Get size of stack.
void pcall(int nargs=0, int nresults=0, int errfunc=0)
Protected call.
bool is_nil(int idx)
Check if stack value is nil.
Base class for exceptions in Fawkes.
lua_Number to_number(int idx)
Retrieve stack value as number.
void push_cfunction(lua_CFunction f)
Push C function on top of stack.
void do_string(const char *format,...)
Execute string.
void do_file(const char *filename)
Execute file.
void set_number(const char *name, lua_Number value)
Assign number to global variable.
LuaContext(bool enable_tracebacks=true)
Constructor.
void setfenv(int idx=-2)
Set function environment.
void get_field(int idx, const char *k)
Get named value from table.
void set_integer(const char *name, lua_Integer value)
Assign integer to global variable.
Monitors files for changes.
lua_Integer to_integer(int idx)
Retrieve stack value as integer.
void set_usertype(const char *name, void *data, const char *type_name, const char *name_space=0)
Assign usertype to global variable.
void push_usertype(void *data, const char *type_name, const char *name_space=0)
Push usertype on top of stack.
bool try_lock()
Tries to lock the mutex.
void set_string(const char *name, const char *value)
Assign string to global variable.
void push_string(const char *value)
Push string on top of stack.
bool is_table(int idx)
Check if stack value is a table.
void cancel()
Cancel a thread.
RefPtr< FileAlterationMonitor > get_fam() const
Get file alteration monitor.
void process_fam_events()
Process FAM events.
void set_boolean(const char *name, bool value)
Assign boolean to global variable.
RefPtr<> is a reference-counting shared smartpointer.
bool is_string(int idx)
Check if stack value is a string.
void get_global(const char *name)
Get global variable.
void push_boolean(bool value)
Push boolean on top of stack.
void set_start_script(const char *start_script)
Set start script.
bool is_function(int idx)
Check if stack value is a function.
bool to_boolean(int idx)
Retrieve stack value as boolean.
lua_State * get_lua_state()
Get Lua state.
void join()
Join the thread.
void get_table(int idx)
Get value from table.
FileAlterationMonitor thread wrapper.
void lock()
Lock this mutex.
void lock()
Lock Lua state.
void remove_global(const char *name)
Remove global variable.
Mutex mutual exclusion lock.
void set_global(const char *name)
Set a global value.
void add_package_dir(const char *path)
Add a Lua package directory.
void create_table(int narr=0, int nrec=0)
Create a table on top of the stack.
void push_number(lua_Number value)
Push number on top of stack.
const char * to_string(int idx)
Retrieve stack value as string.
void raw_get(int idx)
Get value without invoking meta methods.
size_t objlen(int idx)
Get object length.
System ran out of memory and desired operation could not be fulfilled.
void start(bool wait=true)
Call this method to start the thread.
void add_watcher(LuaContextWatcher *watcher)
Add a context watcher.
bool is_boolean(int idx)
Check if stack value is a boolean.
void push_fstring(const char *format,...)
Push formatted string on top of stack.
void raw_set(int idx)
Set value without invoking meta methods.