1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97
|
/*
* Copyright (C) 2006-2016 by the Widelands Development Team
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
#include "scripting/lua_interface.h"
#include <memory>
#include <string>
#include <boost/algorithm/string/predicate.hpp>
#include "io/filesystem/layered_filesystem.h"
#include "scripting/lua_globals.h"
#include "scripting/lua_path.h"
#include "scripting/lua_table.h"
#include "scripting/run_script.h"
namespace {
// Calls 'method_to_call' with argument 'name'. This expects that this will
// return a table with registered functions in it. If 'register_globally' is
// true, this will also do name = <table> globally.
void open_lua_library(lua_State* L,
const std::string& name,
lua_CFunction method_to_call,
bool register_globally) {
lua_pushcfunction(L, method_to_call); // S: function
lua_pushstring(L, name); // S: function name
lua_call(L, 1, 1); // S: module_table
if (register_globally) {
lua_setglobal(L, name.c_str()); // S:
} else {
lua_pop(L, 1); // S:
}
}
} // namespace
LuaInterface::LuaInterface() {
lua_state_ = luaL_newstate();
// Open the Lua libraries
open_lua_library(lua_state_, "", luaopen_base, false);
open_lua_library(lua_state_, LUA_TABLIBNAME, luaopen_table, true);
open_lua_library(lua_state_, LUA_STRLIBNAME, luaopen_string, true);
open_lua_library(lua_state_, LUA_MATHLIBNAME, luaopen_math, true);
open_lua_library(lua_state_, LUA_DBLIBNAME, luaopen_debug, true);
open_lua_library(lua_state_, LUA_COLIBNAME, luaopen_coroutine, true);
// Push the instance of this class into the registry
// MSVC2008 requires that stored and retrieved types are
// same, so use LuaInterface* on both sides.
lua_pushlightuserdata(lua_state_, reinterpret_cast<void*>(dynamic_cast<LuaInterface*>(this)));
lua_setfield(lua_state_, LUA_REGISTRYINDEX, "lua_interface");
// Now our own
LuaGlobals::luaopen_globals(lua_state_);
// And helper methods.
LuaPath::luaopen_path(lua_state_);
// Also push the "wl" and the "hooks" table.
lua_newtable(lua_state_);
lua_setglobal(lua_state_, "wl");
lua_newtable(lua_state_);
lua_setglobal(lua_state_, "hooks");
}
LuaInterface::~LuaInterface() {
lua_close(lua_state_);
}
void LuaInterface::interpret_string(const std::string& cmd) {
int rv = luaL_dostring(lua_state_, cmd.c_str());
check_return_value_for_errors(lua_state_, rv);
}
std::unique_ptr<LuaTable> LuaInterface::run_script(const std::string& path) {
return ::run_script(lua_state_, path, g_fs);
}
|