Parcourir la source

Print traceback when Lua errors occur

Daniele Bartolini il y a 12 ans
Parent
commit
ea674ec5f3
2 fichiers modifiés avec 60 ajouts et 150 suppressions
  1. 48 131
      engine/lua/LuaEnvironment.cpp
  2. 12 19
      engine/lua/LuaEnvironment.h

+ 48 - 131
engine/lua/LuaEnvironment.cpp

@@ -78,13 +78,9 @@ static int crown_lua_require(lua_State* L)
 }
 }
 
 
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
-LuaEnvironment::LuaEnvironment() :
-	m_state(luaL_newstate()),
-	m_is_used(false)
+LuaEnvironment::LuaEnvironment()
+	: m_state(luaL_newstate()), m_is_used(false)
 {
 {
-	// Open Lua default libraries
-	string::strncpy(m_error_buffer, "", 1024);
-	string::strncpy(m_tmp_buffer, "", 1024);
 }
 }
 
 
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
@@ -114,17 +110,6 @@ void LuaEnvironment::init()
 
 
 	lua_pop(m_state, 1);
 	lua_pop(m_state, 1);
 
 
-	// load_buffer(class_system, string::strlen(class_system));
-	// execute(0, 0);
-	// load_buffer(commands_list, string::strlen(commands_list));
-	// execute(0, 0);
-	// load_buffer(get_cmd_by_name, string::strlen(get_cmd_by_name));
-	// execute(0, 0);
-	// load_buffer(tmp_print_table, string::strlen(tmp_print_table));
-	// execute(0, 0);
-	// load_buffer(count_all, string::strlen(count_all));
-	// execute(0, 0);
-
 	m_is_used = true;
 	m_is_used = true;
 }
 }
 
 
@@ -132,37 +117,57 @@ void LuaEnvironment::init()
 void LuaEnvironment::shutdown()
 void LuaEnvironment::shutdown()
 {
 {
 	lua_close(m_state);
 	lua_close(m_state);
-
 	m_is_used = false;
 	m_is_used = false;
 }
 }
 
 
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
-const char* LuaEnvironment::error()
-{	
-	string::strncpy(m_tmp_buffer, m_error_buffer, 1024);
-	string::strncpy(m_error_buffer, "", 1024);
+bool LuaEnvironment::load_and_execute(const char* res_name)
+{
+	CE_ASSERT_NOT_NULL(res_name);
+
+	ResourceManager* resman = device()->resource_manager();
+
+	// Load the resource
+	ResourceId res_id = resman->load("lua", res_name);
+	resman->flush();
+	LuaResource* lr = (LuaResource*) resman->data(res_id);
+	
+	if (luaL_loadbuffer(m_state, (const char*) lr->code(), lr->size(), res_name) == 0)
+	{
+		if (lua_pcall(m_state, 0, 0, 0) == 0)
+		{
+			// Unloading is OK since the script data has been copied to Lua
+			resman->unload(res_id);
+			return true;
+		}
+	}
 
 
-	return m_tmp_buffer;
+	error();
+	return false;
 }
 }
 
 
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
-void LuaEnvironment::load(const LuaResource* lr)
+void LuaEnvironment::load_module_function(const char* module, const char* name, const lua_CFunction func)
 {
 {
-	CE_ASSERT_NOT_NULL(lr);
+	luaL_Reg entry[2];
 
 
-	if (luaL_loadbuffer(m_state, (const char*) lr->code(), lr->size(), "") != 0)
-	{
-		lua_error();
-	}
+	entry[0].name = name;
+	entry[0].func = func;
+	entry[1].name = NULL;
+	entry[1].func = NULL;
 
 
-	if (lua_pcall(m_state, 0, 0, 0) != 0)
-	{
-		lua_error();
-	}
+	luaL_register(m_state, module, entry);
+}
+
+//-----------------------------------------------------------
+void LuaEnvironment::load_module_enum(const char* /*module*/, const char* name, uint32_t value)
+{
+	lua_pushinteger(m_state, value);
+	lua_setfield(m_state, -2, name);
 }
 }
 
 
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
-void LuaEnvironment::call_global(const char* func, uint8_t argc, ...)
+bool LuaEnvironment::call_global(const char* func, uint8_t argc, ...)
 {
 {
 	CE_ASSERT_NOT_NULL(func);
 	CE_ASSERT_NOT_NULL(func);
 
 
@@ -171,6 +176,8 @@ void LuaEnvironment::call_global(const char* func, uint8_t argc, ...)
 	va_list vl;
 	va_list vl;
 	va_start(vl, argc);
 	va_start(vl, argc);
 
 
+	lua_getglobal(m_state, "debug");
+	lua_getfield(m_state, -1, "traceback");
 	lua_getglobal(m_state, func);
 	lua_getglobal(m_state, func);
 
 
 	for (uint8_t i = 0; i < argc; i++)
 	for (uint8_t i = 0; i < argc; i++)
@@ -193,110 +200,20 @@ void LuaEnvironment::call_global(const char* func, uint8_t argc, ...)
 
 
 	va_end(vl);
 	va_end(vl);
 
 
-	if (lua_pcall(m_state, argc, 0, 0) != 0)
+	if (lua_pcall(m_state, argc, 0, -argc - 2) != 0)
 	{
 	{
-		lua_error();
+		error();
+		return false;
 	}
 	}
-}
 
 
-//-----------------------------------------------------------------------------
-void LuaEnvironment::lua_error()
-{
-	string::strncpy(m_error_buffer, "", 1024);
-	string::strncpy(m_error_buffer, lua_tostring(m_state, -1), 1024);
+	return true;
 }
 }
 
 
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
-void LuaEnvironment::load_module_function(const char* module, const char* name, const lua_CFunction func)
+void LuaEnvironment::error()
 {
 {
-	luaL_Reg entry[2];
-
-	entry[0].name = name;
-	entry[0].func = func;
-	entry[1].name = NULL;
-	entry[1].func = NULL;
-
-	luaL_register(m_state, module, entry);
+	const char* msg = lua_tostring(m_state, -1);
+	Log::e(msg);
 }
 }
 
 
-//-----------------------------------------------------------
-void LuaEnvironment::load_module_enum(const char* /*module*/, const char* name, uint32_t value)
-{
-	lua_pushinteger(m_state, value);
-	lua_setfield(m_state, -2, name);
-}
-
-const char* LuaEnvironment::class_system =  "function class(klass, super) "
-    										"	if not klass then "
-        									"		klass = {} "
-                							"		local meta = {} "
-        									"		meta.__call = function(self, ...) "
-            								"			local object = {} "
-            								"			setmetatable(object, klass) "
-            								"			if object.init then object:init(...) end "
-            								"			return object "
-       										"		end "
-        									"		setmetatable(klass, meta) "
-    										"	end "  
-    										"	if super then "
-        									"		for k,v in pairs(super) do "
-            								"			klass[k] = v "
-        									"		end "
-    										"	end "
-    										"	klass.__index = klass "
-    										"	return klass "
-											"end";
-
-
-const char* LuaEnvironment::commands_list = "function get_all_commands() "
-											"	local cmds = {}; "
-											"	for class_name,class in pairs(_G) do "
-											"		if type(class) == 'table' then "
-			 								"			for func_name,func in pairs(class) do "
-			 								"				if type(func) == 'function' then "
-											"					cmds[#cmds+1] = class_name .. '.' .. func_name "
-											"				end "
-											"			end "
-											"		end "
-											"	end "
-											"	return cmds "
-											"end";
-
-const char* LuaEnvironment::get_cmd_by_name = 	"function get_command_by_name(text) "
-												"	local cmds = get_all_commands() "
-												"	local results = {} "
-												"	local index = 0 "
-												"	for i,cmd in pairs(cmds) do "
-												"		if string.find(cmd, text) then "
-												"			results[index] = cmds[i] "
-												"			index = index + 1 "
-												"		end "
-												"	end "
-												"	return results "
-												"end";
-
-const char* LuaEnvironment::tmp_print_table =	"function print_table(table) "												
-												"	for k,v in pairs(table) do "
-												"		print(v) "
-												"	end "
-												"end";
-
-const char* LuaEnvironment::count_all = 	"function count_all(f) "
-											"	local seen = {} "
-											"	local count_table "
-											"	count_table = function(t) "
-											"		if seen[t] then return end "
-											"		f(t) "
-											"		seen[t] = true "
-											"		for k,v in pairs(t) do "
-											"			if type(v) == 'table' then "
-											"				count_table(v) "
-											"			elseif type(v) == 'userdata' then "
-											"				f(v) "
-											"			end "
-											"		end "
-											"	end "
-											"	count_table(_G) "
-											"end";
-
 } // namespace crown
 } // namespace crown

+ 12 - 19
engine/lua/LuaEnvironment.h

@@ -53,16 +53,9 @@ public:
 	/// Close Lua state and shutdown LuaEnvironment
 	/// Close Lua state and shutdown LuaEnvironment
 	void					shutdown();
 	void					shutdown();
 
 
-	const char*				error();
-
-	/// Loads and execute the given @a lr lua script resource.
-	void					load(const LuaResource* lr);
-
-	/// Calls the global function @a func with @a argc argument number.
-	/// Each argument is a pair (type, value).
-	/// Example call:
-	/// call_global("myfunc", 1, ARGUMENT_FLOAT, 3.14f)
-	void					call_global(const char* func, uint8_t argc, ...);
+	/// Loads and execute the given @a res_name Lua resource, returns
+	/// true if success, false otherwise.
+	bool					load_and_execute(const char* res_name);
 
 
 	/// Load a function which will be used in Lua. @a module is the name of table contenitor,
 	/// Load a function which will be used in Lua. @a module is the name of table contenitor,
 	/// @a name is the name of function in module and @func is the pointer to the function.
 	/// @a name is the name of function in module and @func is the pointer to the function.
@@ -74,9 +67,17 @@ public:
 	/// @a name is module's name that refears _value_ and @value is an unsigned integer
 	/// @a name is module's name that refears _value_ and @value is an unsigned integer
 	void					load_module_enum(const char* module, const char* name, uint32_t value);
 	void					load_module_enum(const char* module, const char* name, uint32_t value);
 
 
+	/// Calls the global function @a func with @a argc argument number.
+	/// Each argument is a pair (type, value).
+	/// Example call:
+	/// call_global("myfunc", 1, ARGUMENT_FLOAT, 3.14f)
+	/// Returns true if success, false otherwise
+	bool					call_global(const char* func, uint8_t argc, ...);
+
+	void					error();
+
 private:
 private:
 
 
-	void					lua_error();
 	// Disable copying
 	// Disable copying
 							LuaEnvironment(const LuaEnvironment&);
 							LuaEnvironment(const LuaEnvironment&);
 	LuaEnvironment& 		operator=(const LuaEnvironment&);
 	LuaEnvironment& 		operator=(const LuaEnvironment&);
@@ -87,14 +88,6 @@ private:
 
 
 	/// LuaEnvironment is used right now?
 	/// LuaEnvironment is used right now?
 	bool					m_is_used;
 	bool					m_is_used;
-
-	char					m_error_buffer[1024];
-	char					m_tmp_buffer[1024];
-	static const char* 		class_system;
-	static const char*		commands_list;
-	static const char*		get_cmd_by_name;
-	static const char*		tmp_print_table;
-	static const char*		count_all;
 };
 };