Просмотр исходного кода

implement Lua chunks in LuaEnvironment

mikymod 12 лет назад
Родитель
Сommit
7fefbf53cf
5 измененных файлов с 141 добавлено и 62 удалено
  1. 0 26
      src/ConsoleServer.cpp
  2. 0 2
      src/ConsoleServer.h
  3. 5 6
      src/Device.cpp
  4. 99 8
      src/lua/LuaEnvironment.cpp
  5. 37 20
      src/lua/LuaEnvironment.h

+ 0 - 26
src/ConsoleServer.cpp

@@ -39,22 +39,6 @@ namespace crown
 static IntSetting g_read_port("read_port", "port used for reading", 10000, 9999, 65535);
 static IntSetting g_write_port("write_port", "port used for writing", 10001, 9999, 65535);
 
-
-//-----------------------------------------------------------------------------
-const char* ConsoleServer::init_console = 	"cmd = ""; "
-											"local i = 0; "
-											"for name,class in pairs(_G) do "
-											"	if type(class) == 'table' then "
-			 								"		for func_name,func in pairs(class) do "
-			 								"			if type(func) == 'function' then "
-			 								"				i = i + 1 "
-											"				cmd = cmd .. name .. '.' .. func_name "
-											"			end "
-											"		end "
-											"	end "
-											"end";
-
-
 //-----------------------------------------------------------------------------
 ConsoleServer::ConsoleServer() :
 	m_active(false),
@@ -69,9 +53,6 @@ void ConsoleServer::init()
 {
 	LuaEnvironment* lua = device()->lua_environment();
 
-	//lua->load_buffer(init_console, string::strlen(init_console));
-	//lua->execute(0, 0);
-
 	m_active = true;
 }
 
@@ -80,17 +61,12 @@ void ConsoleServer::shutdown()
 {
 	m_active = false;
 
-	// TMP FIX
 	m_socket.close();
 }
 
 //-----------------------------------------------------------------------------
 void ConsoleServer::read_eval_loop()
 {
-	m_socket.open(g_read_port);
-
-	LuaEnvironment* lua = device()->lua_environment();
-
 	char cmd[1024];
 
 	while (m_active)
@@ -141,8 +117,6 @@ void ConsoleServer::send(const void* data, size_t size)
 void ConsoleServer::receive(char* data, size_t size)
 {
 	int32_t bytes_read = m_socket.receive(data, size);
-
-	// FIX: parse json (JSONParser needs rework)
 }
 
 //-----------------------------------------------------------------------------

+ 0 - 2
src/ConsoleServer.h

@@ -72,8 +72,6 @@ private:
 
 	char 					m_err_buffer[1024];
 
-	/// Lua script which initializes ConsoleServer
-	static const char*		init_console;
 };
 
 } // namespace crown

+ 5 - 6
src/Device.cpp

@@ -49,7 +49,6 @@ OTHER DEALINGS IN THE SOFTWARE.
 #include "JSONParser.h"
 #include "DiskFile.h"
 #include "Memory.h"
-#include "Game.h"
 #include "LuaEnvironment.h"
 #include "ConsoleServer.h"
 
@@ -134,7 +133,7 @@ bool Device::init(int argc, char** argv)
 	Log::i("Initializing Game...");
 
 	// Initialize the game through init game function
-	m_lua_environment->init();
+	m_lua_environment->game_init();
 
 	m_is_init = true;
 
@@ -158,7 +157,7 @@ void Device::shutdown()
 	}
 
 	// Shutdowns the game
-	m_lua_environment->shutdown();
+	m_lua_environment->game_shutdown();
 
 	Log::i("Releasing ConsoleServer...");
 	if (m_console_server)
@@ -171,7 +170,7 @@ void Device::shutdown()
 	Log::i("Releasing LuaEnvironment...");
 	if (m_lua_environment)
 	{
-		m_lua_environment->stop();
+		m_lua_environment->shutdown();
 		
 		CE_DELETE(m_allocator, m_lua_environment);
 	}
@@ -357,7 +356,7 @@ void Device::frame()
 	m_window->frame();
 	m_input_manager->frame();
 
-	m_lua_environment->frame(last_delta_time());
+	m_lua_environment->game_frame(last_delta_time());
 
 	m_console_server->execute();
 
@@ -471,7 +470,7 @@ void Device::create_lua_environment()
 {
 	m_lua_environment = CE_NEW(m_allocator, LuaEnvironment)();
 
-	m_lua_environment->start();
+	m_lua_environment->init();
 
 	Log::d("Lua environment created.");
 }

+ 99 - 8
src/lua/LuaEnvironment.cpp

@@ -26,6 +26,7 @@ OTHER DEALINGS IN THE SOFTWARE.
 
 
 #include "Device.h"
+#include "OS.h"
 #include "Assert.h"
 #include "Log.h"
 #include "LuaEnvironment.h"
@@ -36,30 +37,48 @@ namespace crown
 {
 
 StringSetting g_boot("boot_file", "lua main file", "lua/game.raw");
+/*
+*N.B: Lua garbage collection is actually disabled
+*/
 
 //-----------------------------------------------------------------------------
 LuaEnvironment::LuaEnvironment() :
-	m_state(luaL_newstate())
+	m_state(luaL_newstate()),
+	m_is_used(false),
+	m_thread(LuaEnvironment::background_thread, (void*)this, "lua-environment-thread")
 {
 	// Open Lua default libraries
-	luaL_openlibs(m_state);
-
 	string::strncpy(m_error_buffer, "", 1024);
 
 	string::strncpy(m_tmp_buffer, "", 1024);
 }
 
 //-----------------------------------------------------------------------------
-void LuaEnvironment::start()
+void LuaEnvironment::init()
 {
+	// Open default libraries
+	luaL_openlibs(m_state);
 	// Open Crown library
 	lua_cpcall(m_state, luaopen_libcrown, NULL);
+
+	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);
+
+	m_is_used = true;
 }
 
 //-----------------------------------------------------------------------------
-void LuaEnvironment::stop()
+void LuaEnvironment::shutdown()
 {
 	lua_close(m_state);
+
+	m_is_used = false;
 }
 
 //-----------------------------------------------------------------------------
@@ -129,7 +148,24 @@ void LuaEnvironment::execute(int32_t args, int32_t results)
 }
 
 //-----------------------------------------------------------------------------
-void LuaEnvironment::init()
+void LuaEnvironment::collect_garbage()
+{
+	uint64_t start = os::milliseconds();
+
+	while ((os::milliseconds() - start) < device()->last_delta_time() && !m_is_used)
+	{
+		lua_gc(m_state, LUA_GCSTEP, 0);
+	}
+}
+
+//-----------------------------------------------------------------------------
+void* LuaEnvironment::background_thread(void* thiz)
+{
+	((LuaEnvironment*)thiz)->collect_garbage();	
+}
+
+//-----------------------------------------------------------------------------
+void LuaEnvironment::game_init()
 {
 	const char* path = device()->filesystem()->os_path(g_boot.value());
 
@@ -141,14 +177,14 @@ void LuaEnvironment::init()
 }
 
 //-----------------------------------------------------------------------------
-void LuaEnvironment::shutdown()
+void LuaEnvironment::game_shutdown()
 {
 	get_global_symbol("shutdown");
 	execute(0, 0);
 }
 
 //-----------------------------------------------------------------------------
-void LuaEnvironment::frame(float dt)
+void LuaEnvironment::game_frame(float dt)
 {
 	LuaStack stack(m_state);
 
@@ -205,4 +241,59 @@ CE_EXPORT int32_t luaopen_libcrown(lua_State* L)
 	return 1;
 }
 
+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"
+;
 } // namespace crown

+ 37 - 20
src/lua/LuaEnvironment.h

@@ -31,6 +31,7 @@ OTHER DEALINGS IN THE SOFTWARE.
 #include "Config.h"
 #include "LuaStack.h"
 #include "LinearAllocator.h"
+#include "Thread.h"
 
 #ifdef WINDOWS
 	#define CE_EXPORT extern "C" __declspec(dllexport)
@@ -49,49 +50,65 @@ class LuaEnvironment
 
 public:
 	/// Constructor
-						LuaEnvironment();
+							LuaEnvironment();
 
-	void				start();
+	void					init();
 
-	void				stop();
+	void					shutdown();
 
-	lua_State*			state();
+	lua_State*				state();
 
-	const char*			error();
+	const char*				error();
 
-	void				load_buffer(const char* buffer, size_t len);
+	void					load_buffer(const char* buffer, size_t len);
 
-	void				load_file(const char* file);
+	void					load_file(const char* file);
 
-	void 				load_string(const char* str);
+	void 					load_string(const char* str);
 
-	void				get_global_symbol(const char* symbol);
+	void					get_global_symbol(const char* symbol);
 
 	/// Load a function to proper module
-	void				load_module_function(const char* module, const char* name, const lua_CFunction func);
+	void					load_module_function(const char* module, const char* name, const lua_CFunction func);
 
-	void				execute(int32_t args, int32_t results);
+	void					execute(int32_t args, int32_t results);
 
-	void				init();
+	void					collect_garbage();
 
-	void				shutdown();
+	void					game_init();
 
-	void				frame(float dt);
+	void					game_shutdown();
+
+	void					game_frame(float dt);
 
 private:
 
-	void				lua_error();
+	static void*			background_thread(void* thiz);
+
+	void					lua_error();
 	// Disable copying
-						LuaEnvironment(const LuaEnvironment&);
-	LuaEnvironment& 	operator=(const LuaEnvironment&);
+							LuaEnvironment(const LuaEnvironment&);
+	LuaEnvironment& 		operator=(const LuaEnvironment&);
 
 private:
+	/// 
+	lua_State*				m_state;
+	/// LuaEnvironment is used right now?
+	bool					m_is_used;
+	/// Thread used for garbage collection
+	os::Thread 				m_thread;
+
+	char					m_error_buffer[1024];
+
+	char					m_tmp_buffer[1024];
+
+	static const char* 		class_system;
 
-	lua_State*			m_state;
+	static const char*		commands_list;
 
-	char				m_error_buffer[1024];
+	static const char*		get_cmd_by_name;
 
-	char				m_tmp_buffer[1024];
+	static const char*		tmp_print_table;
 };