/* * The Mana World Server * Copyright 2007 The Mana World Development Team * * This file is part of The Mana World. * * The Mana World 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 * any later version. * * The Mana World 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 The Mana World; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Id$ */ #include extern "C" { #include #include } #include "resourcemanager.h" #include "scripting/script.hpp" #include "utils/logger.h" /** * Implementation of the Script class for Lua. */ class LuaScript: public Script { public: LuaScript(lua_State *); ~LuaScript(); void prepare(std::string const &); void push(int); void push(Thing *); int execute(); private: lua_State *mState; int nbArgs; }; LuaScript::LuaScript(lua_State *s): mState(s), nbArgs(-1) { luaL_openlibs(mState); // A Lua state is like a function, so "execute" it in order to initialize it. int res = lua_pcall(mState, 0, 0, 0); if (res) { LOG_ERROR("Failure while initializing Lua script: " << lua_tostring(mState, 0)); } } LuaScript::~LuaScript() { lua_close(mState); } void LuaScript::prepare(std::string const &name) { assert(nbArgs == -1); lua_getglobal(mState, name.c_str()); nbArgs = 0; } void LuaScript::push(int v) { assert(nbArgs >= 0); lua_pushinteger(mState, v); ++nbArgs; } void LuaScript::push(Thing *v) { assert(nbArgs >= 0); lua_pushlightuserdata(mState, v); ++nbArgs; } int LuaScript::execute() { assert(nbArgs >= 0); int res = lua_pcall(mState, nbArgs, 1, 0); nbArgs = -1; if (res || !lua_isnumber(mState, 1)) { LOG_WARN("Failure while calling Lua function: error=" << res << ", type=" << lua_typename(mState, lua_type(mState, 1)) << ", message=" << lua_tostring(mState, 1)); lua_pop(mState, 1); return 0; } res = lua_tointeger(mState, 1); lua_pop(mState, 1); return res; } static Script *loadScript(std::string const &filename) { // Load the file through resource manager. ResourceManager *resman = ResourceManager::getInstance(); int fileSize; char *buffer = (char *)resman->loadFile(filename, fileSize); if (!buffer) return NULL; lua_State *s = luaL_newstate(); int res = luaL_loadstring(s, buffer); free(buffer); switch(res) { case 0: LOG_INFO("Successfully loaded script " << filename); return new LuaScript(s); case LUA_ERRSYNTAX: LOG_ERROR("Syntax error while loading script " << filename); } lua_close(s); return NULL; } struct LuaRegister { LuaRegister() { Script::registerEngine("lua", loadScript); } }; static LuaRegister dummy;