// // Base Lua class for Lua script loading // // Copyright © 2009—2015 Sam Hocevar // © 2009—2015 Benjamin “Touky” Huet // // Lol Engine is free software. It comes without any warranty, to // the extent permitted by applicable law. You can redistribute it // and/or modify it under the terms of the Do What the Fuck You Want // to Public License, Version 2, as published by the WTFPL Task Force. // See http://www.wtfpl.net/ for more details. // #include #include #include #include namespace lol { //----------------------------------------------------------------------------- class LuaBaseData { friend class Lolua::Loader; //PANIC PANIC ------------------------------------------------------------- static int LuaPanic(LuaState* l) { char const *message = lua_tostring(l, -1); msg::error("%s\n", message); DebugAbort(); return 0; } //Exec lua code ----------------------------------------------------------- static int LuaDoCode(LuaState *l, String const& s) { int status = luaL_dostring(l, s.C()); if (status == 1) { LuaString error; error.Get(l, -1); msg::error("Lua error %s\n", error().C()); lua_pop(l, 1); } return status; } //Open a file and exec lua code ------------------------------------------- static int LuaDoFile(LuaState *l) { if (lua_isnoneornil(l, 1)) return LUA_ERRFILE; LuaCharPtr var; var.Get(l, 1); char const *filename = var;// lua_tostring(l, 1); int status = LUA_ERRFILE; File f; for (auto candidate : System::GetPathList(filename)) { f.Open(candidate, FileAccess::Read); if (f.IsValid()) { String s = f.ReadString(); f.Close(); msg::debug("loading Lua file %s\n", candidate.C()); status = LuaDoCode(l, s); break; } } if (status == LUA_ERRFILE) msg::error("could not find Lua file %s\n", filename); else if (status == 1) { LuaString error; error.Get(l, -1); msg::error("Lua error %s\n", error().C()); lua_pop(l, 1); } lua_pop(l, 1); return status; } }; namespace Lolua { //----------------------------------------------------------------------------- Loader::Loader() { m_lua_state = luaL_newstate(); lua_atpanic(m_lua_state, LuaBaseData::LuaPanic); luaL_openlibs(m_lua_state); /* Override dofile() */ LuaFunction do_file(m_lua_state, "dofile", LuaBaseData::LuaDoFile); //Store this instance Loader::Store(m_lua_state, this); } //----------------------------------------------------------------------------- Loader::~Loader() { //Release this instance Loader::Release(m_lua_state, this); lua_close(m_lua_state); } //Store loader ------------------------------------------------------------ static array g_loaders; void Loader::Store(LuaState* l, Lolua::Loader* loader) { g_loaders.push(l, loader); } void Loader::Release(LuaState* l, Lolua::Loader* loader) { for (int i = 0; i < g_loaders.count(); ++i) { if (g_loaders[i].m1 == l && g_loaders[i].m2 == loader) { g_loaders.remove(i); return; } } } Lolua::Loader *LuaLoader::Find(LuaState* l) { for (int i = 0; i < g_loaders.count(); ++i) if (g_loaders[i].m1 == l) return g_loaders[i].m2; return nullptr; } //Store lua object -------------------------------------------------------- void Loader::StoreObject(LuaState* l, Object* obj) { for (auto loader : g_loaders) { if (loader.m1 == l) { loader.m2->Store(obj); return; } } } //----------------------------------------------------------------------------- bool Loader::ExecLuaFile(String const &lua) { const char* c = lua_pushstring(m_lua_state, lua.C()); int status = LuaBaseData::LuaDoFile(m_lua_state); return status == 0; } //----------------------------------------------------------------------------- bool Loader::ExecLuaCode(String const &lua) { return 0 == LuaBaseData::LuaDoCode(m_lua_state, lua); } //----------------------------------------------------------------------------- LuaState* Loader::GetLuaState() { return m_lua_state; } } /* namespace Lolua */ } /* namespace lol */