Main Page | Class Hierarchy | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals

ScriptState.cpp

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2004 Ivo Danihelka (ivo@danihelka.net)
00003  *
00004  * This program is free software; you can redistribute it and/or modify
00005  * it under the terms of the GNU General Public License as published by
00006  * the Free Software Foundation; either version 2 of the License, or
00007  * (at your option) any later version.
00008  */
00009 #include "ScriptState.h"
00010 
00011 #include "Log.h"
00012 #include "Path.h"
00013 #include "ScriptException.h"
00014 
00015 extern "C" {
00016 #include "lualib.h"
00017 #include "lauxlib.h"
00018 }
00019 
00020 #include "def-script.h"
00021 
00022 //-----------------------------------------------------------------
00023 ScriptState::ScriptState()
00024 {
00025     m_state = lua_open();
00026     luaopen_base(m_state);
00027     luaopen_string(m_state);
00028     luaopen_math(m_state);
00029     luaopen_table(m_state);
00030 
00031     prepareErrorHandler();
00032 }
00033 //-----------------------------------------------------------------
00034 ScriptState::~ScriptState()
00035 {
00036     lua_close(m_state);
00037 }
00038 //-----------------------------------------------------------------
00039 /**
00040  * Prepare error handler at global stack.
00041  */
00042 void
00043 ScriptState::prepareErrorHandler()
00044 {
00045     lua_pushliteral(m_state, "_TRACEBACK");
00046     lua_pushcfunction(m_state, script_debugStack);
00047     lua_settable(m_state, LUA_GLOBALSINDEX);
00048 }
00049 //-----------------------------------------------------------------
00050 /**
00051  * Insert error handler at given local index.
00052  */
00053 void
00054 ScriptState::insertErrorHandler(int index)
00055 {
00056     lua_pushliteral(m_state, "_TRACEBACK");
00057     lua_rawget(m_state, LUA_GLOBALSINDEX);
00058     lua_insert(m_state, index);
00059 }
00060 //-----------------------------------------------------------------
00061 /**
00062  * Process script on stack.
00063  * @param error script load status
00064  * @param params number of params
00065  * @param returns number of values on return
00066  *
00067  * @throws ScriptException when script is bad
00068  */
00069     void
00070 ScriptState::callStack(int error, int params, int returns)
00071 {
00072     if (0 == error) {
00073         int base = lua_gettop(m_state) - params;
00074         insertErrorHandler(base);
00075         error = lua_pcall(m_state, params, returns, base);
00076         lua_remove(m_state, base);
00077     }
00078 
00079     if (error) {
00080         const char *msg = lua_tostring(m_state, -1);
00081         if (NULL == msg) {
00082             msg = "(error with no message)";
00083         }
00084         lua_pop(m_state, 1);
00085         throw ScriptException(ExInfo("script failure")
00086                 .addInfo("error", msg));
00087     }
00088 }
00089 //-----------------------------------------------------------------
00090 /**
00091  * Process script file.
00092  * @param file script
00093  */
00094     void
00095 ScriptState::doFile(const Path &file)
00096 {
00097     int error = luaL_loadfile(m_state, file.getNative().c_str());
00098     callStack(error);
00099 }
00100 //-----------------------------------------------------------------
00101 /**
00102  * Process string.
00103  * @param input script
00104  */
00105     void
00106 ScriptState::doString(const std::string &input)
00107 {
00108     int error = luaL_loadbuffer(m_state, input.c_str(), input.size(),
00109             input.c_str());
00110     callStack(error);
00111 }
00112 //-----------------------------------------------------------------
00113     void
00114 ScriptState::registerFunc(const char *name, lua_CFunction func)
00115 {
00116     lua_register(m_state, name, func);
00117 }
00118 
00119 //-----------------------------------------------------------------
00120 /**
00121  * Call "bool function(param)" function.
00122  * @param funcRef function index at registry
00123  * @param param integer parametr
00124  * @return boolean result from function
00125  * @throws ScriptException when function is bad
00126  */
00127 bool
00128 ScriptState::callCommand(int funcRef, int param)
00129 {
00130     int numResults = 1;
00131     lua_rawgeti(m_state, LUA_REGISTRYINDEX, funcRef);
00132     lua_pushnumber(m_state, param);
00133     callStack(0, 1, numResults);
00134 
00135     if (0 == lua_isboolean(m_state, -1)) {
00136         const char *type = lua_typename(m_state, lua_type(m_state, -1));
00137         lua_pop(m_state, numResults);
00138         throw ScriptException(
00139                 ExInfo("script command failure - boolean expected")
00140                 .addInfo("got", type));
00141     }
00142     bool result = lua_toboolean(m_state, -1);
00143     lua_pop(m_state, numResults);
00144     return result;
00145 }
00146 //-----------------------------------------------------------------
00147 /**
00148  * Remove function from registry.
00149  * @param funcRef function index at registry
00150  */
00151 void
00152 ScriptState::unref(int funcRef)
00153 {
00154     luaL_unref(m_state, LUA_REGISTRYINDEX, funcRef);
00155 }
00156 
00157 //-----------------------------------------------------------------
00158 /**
00159  * Register light userdata for lua script.
00160  */
00161 void
00162 ScriptState::registerLeader(Scripter *leader)
00163 {
00164     lua_pushstring(m_state, script_getLeaderName());
00165     lua_pushlightuserdata(m_state, leader);
00166     lua_rawset(m_state, LUA_REGISTRYINDEX);
00167 }
00168 

Generated on Wed Jun 1 09:54:31 2005 for Fish Fillets - Next Generation by  doxygen 1.4.2