parent
							
								
									7969a701c3
								
							
						
					
					
						commit
						3afa35df61
					
				| @ -0,0 +1,38 @@ | ||||
| #ifndef LUASTUFF_H | ||||
| #define LUASTUFF_H | ||||
| #include <string> | ||||
| using std::string; | ||||
| 
 | ||||
| extern "C" { | ||||
| #include "lua.h" | ||||
| #include "lauxlib.h" | ||||
| #include "lualib.h" | ||||
| } | ||||
| 
 | ||||
| //#include "lune.h"
 | ||||
| #include "luaxx.hpp" | ||||
| 
 | ||||
| namespace lua | ||||
| { | ||||
| 	//global lua state singleton
 | ||||
|     class glua | ||||
|     { | ||||
|     public: | ||||
|         static state &Get(); | ||||
|     private: | ||||
|         glua(); | ||||
|         static glua *ptr; | ||||
|         state mystate; | ||||
|     }; | ||||
| 	//registers basic lua commands
 | ||||
|     void RegBasics(lua::state &L); | ||||
| 	//dumps lua function trace, useless unless called from lua.
 | ||||
|     string DebugDump(lua::state &L); | ||||
| 	//register functions, first registers into global scope, second into current table
 | ||||
| 	void RegFunctions(lua::state &L,luaL_reg const *arr); | ||||
| 	void RegFunctionsLocal(lua::state &L,luaL_reg const *arr); | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| #endif // LUASTUFF_H
 | ||||
| @ -0,0 +1,525 @@ | ||||
| /* vim: set et sw=3 tw=0 fo=croqlaw cino=t0:
 | ||||
|  * | ||||
|  * Luaxx, the C++ Lua wrapper library. | ||||
|  * Copyright (c) 2006-2008 Matthew Nicholson | ||||
|  * | ||||
|  * Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|  * of this software and associated documentation files (the "Software"), to | ||||
|  * deal in the Software without restriction, including without limitation the | ||||
|  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or | ||||
|  * sell copies of the Software, and to permit persons to whom the Software is | ||||
|  * furnished to do so, subject to the following conditions: | ||||
|  * | ||||
|  * The above copyright notice and this permission notice shall be included in | ||||
|  * all copies or substantial portions of the Software. | ||||
|  * | ||||
|  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | ||||
|  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS | ||||
|  * IN THE SOFTWARE. | ||||
|  */ | ||||
| 
 | ||||
| #ifndef LUAXX_H | ||||
| #define LUAXX_H | ||||
| 
 | ||||
| #define lua_Integer_long 1 | ||||
| #define lua_Integer_int 1 | ||||
| 
 | ||||
| #include <lua.hpp> | ||||
| #include <string> | ||||
| #include <vector> | ||||
| #include <new> | ||||
| #include <exception> | ||||
| 
 | ||||
| /** @file
 | ||||
|  * Luaxx header file. | ||||
|  */ | ||||
| 
 | ||||
| /** @mainpage Luaxx
 | ||||
|  * | ||||
|  * Luaxx is a thin wrapper around the Lua C API.  The wrapper adds some | ||||
|  * convenience functions and integrates well with modern C++. | ||||
|  * | ||||
|  * Luaxx is not designed like toLua, instead Luaxx is more of a 1 to 1 | ||||
|  * logical mapping of the lua API in C++.  For example: in C you would write | ||||
|  * 'lua_pushnumber(L, 3)', in C++ with Luaxx you would write | ||||
|  * 'L.push(3)'. | ||||
|  * | ||||
|  * Every thing is contained in the 'lua' namespace and exceptions are thrown | ||||
|  * when a lua API function returns an error.  Most of the functionality is | ||||
|  * contained in the lua::state class, which can be passed directly to lua C API | ||||
|  * functions (the compiler will automatically use the internal lua_State | ||||
|  * pointer).  See the documentation for that class for more information. | ||||
|  */ | ||||
| 
 | ||||
| namespace lua | ||||
| { | ||||
|     void StackDump(lua_State *L); | ||||
|    /** A generic lua exception.
 | ||||
|     */ | ||||
|    class exception : public std::exception { | ||||
|       public: | ||||
|          /// Constructor.
 | ||||
|          exception() : std::exception() { } | ||||
|          /// Constructor.
 | ||||
|          explicit exception(const char* desc) : std::exception(), description(desc) { } | ||||
|          virtual ~exception() throw() { } | ||||
|          /** Get a description of the error.
 | ||||
|           * @returns a C-string describing the error | ||||
|           */ | ||||
|          virtual const char* what() const throw() { | ||||
|             return description.c_str(); | ||||
|          } | ||||
|       private: | ||||
|          std::string description; | ||||
|    }; | ||||
| 
 | ||||
|    /** A lua runtime error.
 | ||||
|     * This is thrown when there was an error executing some lua code. | ||||
|     * @note This is not an std::runtime error. | ||||
|     */ | ||||
|    class runtime_error : public exception { | ||||
|       public: | ||||
|          /// Constructor.
 | ||||
|          runtime_error() : exception() { } | ||||
|          /// Constructor.
 | ||||
|          explicit runtime_error(const char* desc) : exception(desc) { } | ||||
|          virtual ~runtime_error() throw() { } | ||||
|    }; | ||||
| 
 | ||||
|    /** A syntax error.
 | ||||
|     */ | ||||
|    class syntax_error : public exception { | ||||
|       public: | ||||
|          /// Constructor.
 | ||||
|          syntax_error() : exception() { } | ||||
|          /// Constructor.
 | ||||
|          explicit syntax_error(const char* desc) : exception(desc) { } | ||||
|          virtual ~syntax_error() throw() { } | ||||
|    }; | ||||
| 
 | ||||
|    /** An error loading a lua file.
 | ||||
|     * This is thrown when a call to lua::loadfile failed because the file could | ||||
|     * not be opened or read. | ||||
|     */ | ||||
|    class file_error : public exception { | ||||
|       public: | ||||
|          /// Constructor.
 | ||||
|          file_error() : exception() { } | ||||
|          /// Constructor.
 | ||||
|          explicit file_error(const char* desc) : exception(desc) { } | ||||
|          virtual ~file_error() throw() { } | ||||
|    }; | ||||
| 
 | ||||
|    /** A memory allocation error.
 | ||||
|     */ | ||||
|    class bad_alloc : public exception, std::bad_alloc { | ||||
|       public: | ||||
|          /// Constructor.
 | ||||
|          bad_alloc() : lua::exception(), std::bad_alloc() { } | ||||
|          /// Constructor.
 | ||||
|          explicit bad_alloc(const char* desc) : lua::exception(desc), std::bad_alloc() { } | ||||
|          virtual ~bad_alloc() throw() { } | ||||
|    }; | ||||
| 
 | ||||
|    /** An error converting a lua type.
 | ||||
|     */ | ||||
|    class bad_conversion : public exception { | ||||
|       public: | ||||
|          /// Constructor.
 | ||||
|          bad_conversion() : exception() { } | ||||
|          /// Constructor.
 | ||||
|          explicit bad_conversion(const char* desc) : exception(desc) { } | ||||
|          virtual ~bad_conversion() throw() { } | ||||
|    }; | ||||
| 
 | ||||
|    /// A Lua table (this class does not have any data).
 | ||||
|    class table { }; | ||||
|    /// A Lua nil (this class does not have any data).
 | ||||
|    class nil { }; | ||||
|    /// A lua function (not a cfunction).
 | ||||
|    class function { }; | ||||
|    /// A lua userdatum
 | ||||
|    class userdata { }; | ||||
|    /// A lua light userdatum
 | ||||
|    class lightuserdata { }; | ||||
| 
 | ||||
|    typedef lua_CFunction cfunction;  ///< A cfunction on the lua statck
 | ||||
|    typedef lua_Integer integer;      ///< The default lua integer type
 | ||||
|    typedef lua_Number number;        ///< The default lua number type
 | ||||
|    typedef lua_Reader reader;        ///< The type of function used by lua_load
 | ||||
|    const int multiret = LUA_MULTRET; ///< LUA_MULTIRET
 | ||||
| 
 | ||||
|    /** This is the Luaxx equivalent of lua_State.
 | ||||
|     * The functions provided by this class, closely resemble those of the Lua C | ||||
|     * API. | ||||
|     */ | ||||
|     void StackDump(lua_State *L); | ||||
|    class state { | ||||
|       public: | ||||
|          state(); | ||||
|          state(lua_State* L); | ||||
|          state(const state& t) | ||||
|          { | ||||
|              managed=false; | ||||
|              L=t.L; | ||||
|          } | ||||
|          state& operator = (const state& t); | ||||
|          ~state(); | ||||
| 
 | ||||
|          operator lua_State*(); | ||||
| 
 | ||||
|          state& push(); | ||||
|          state& push(nil); | ||||
|          state& push(bool boolean); | ||||
|          template<typename T> state& push(T number); | ||||
|          state& push(const char* s, size_t length); | ||||
|          state& push(const char* s); | ||||
|          state& push(const std::string& s); | ||||
|          state& push(cfunction f); | ||||
|          state& push(table); | ||||
|          state& push(void* p); | ||||
|          template<typename T> state& pushlightuserdata(T p); | ||||
| 
 | ||||
|          template<typename T> state& to(T& number, int index = -1); | ||||
|          template<typename T> state& touserdata(T& p, int index = -1); | ||||
| 
 | ||||
|          template<typename T> T as(T default_value, int index = -1); | ||||
|          template<typename T> T as(int index = -1); | ||||
|          template<typename T> T vpop() | ||||
|          { | ||||
|              T ret; | ||||
|              ret=as<T>(); | ||||
|              pop(); | ||||
|              return ret; | ||||
|          } | ||||
|          template<typename T> bool is(int index = -1); | ||||
| 
 | ||||
|          state& check(int narg); | ||||
| #ifndef lua_Integer_int | ||||
|          state& check(int& i, int narg); | ||||
| #endif | ||||
|          state& check(integer& i, int narg); | ||||
| #ifndef lua_Integer_long | ||||
|          state& check(long& l, int narg); | ||||
| #endif | ||||
|          state& check(std::string& s, int narg); | ||||
|          state& check(number& n, int narg); | ||||
| 
 | ||||
|          template<typename msg_t> void error(msg_t message); | ||||
| #if 0 | ||||
|          template<> void error(const std::string& message); | ||||
| #endif | ||||
| 
 | ||||
|          state& pcall(int nargs = 0, int nresults = 0, int on_error = 0); | ||||
|          state& call(int nargs = 0, int nresults = 0); | ||||
| 
 | ||||
|          state& checkstack(int size); | ||||
|          state& settop(int index); | ||||
|          int gettop(); | ||||
|          int size(); | ||||
|          bool empty(); | ||||
| 
 | ||||
|          state& insert(int index); | ||||
|          state& replace(int index); | ||||
|          state& remove(int index); | ||||
|          state& pop(int elements = 1); | ||||
| 
 | ||||
|          state& pushvalue(int index); | ||||
| 
 | ||||
|          state& newtable(); | ||||
|          bool newmetatable(const std::string& tname); | ||||
|          template<typename userdata_t> userdata_t* newuserdata(); | ||||
|          void* newuserdata(size_t nbytes); | ||||
| 
 | ||||
|          state& gettable(int index = -2); | ||||
|          state& getfield(const std::string& k, int index = -1); | ||||
|          state& settable(int index = -3); | ||||
|          state& setfield(const std::string& k, int index = -2); | ||||
|          state& getmetatable(const std::string& tname); | ||||
|          bool getmetatable(int index); | ||||
| 
 | ||||
|          bool next(int index = -2); | ||||
| 
 | ||||
|          state& getglobal(const std::string& name); | ||||
|          state& setglobal(const std::string& name); | ||||
| 
 | ||||
|          state& loadfile(const std::string& filename); | ||||
|          state& loadstring(const std::string& s); | ||||
| 
 | ||||
|          template<typename iterator_t> state& load(iterator_t begin, iterator_t end); | ||||
| 
 | ||||
|          size_t objlen(int index = -1); | ||||
| 
 | ||||
|       private: | ||||
|          lua_State* L; | ||||
|          bool managed; | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
|          int throw_error(int code); | ||||
|    }; | ||||
| 
 | ||||
|    // template functions
 | ||||
| 
 | ||||
|    /** Push a number onto the stack.
 | ||||
|     * @tparam T the numeric type to push (should be automatically determined, | ||||
|     * if there is no specialization for the desired type, lua_pushnumber() will | ||||
|     * be used, and may fail) | ||||
|     * @param number the number to push | ||||
|     * @returns a reference to this lua::state | ||||
|     */ | ||||
|    template<typename T> | ||||
|    state& state::push(T number) { | ||||
|       lua_pushnumber(L, number); | ||||
|       return *this; | ||||
|    } | ||||
| 
 | ||||
|    /** Push a light userdatum on to the stack.
 | ||||
|     * @tparam T the type of data to push (should be automatically determined) | ||||
|     * @param p the pointer to push | ||||
|     * @returns a reference to this lua::state | ||||
|     */ | ||||
|    template<typename T> | ||||
|    state& state::pushlightuserdata(T p) { | ||||
|       lua_pushlightuserdata(L, p); | ||||
|       return *this; | ||||
|    } | ||||
| 
 | ||||
|    /** Check if the given index is of the given type (defaults to using
 | ||||
|     * lua_isnumber()). | ||||
|     * @tparam T the type to check for (the default, if no specializations | ||||
|     * match, does lua_isnumber()) | ||||
|     * @param index the index to check | ||||
|     * @note the default version (used if no specialization is matched) will | ||||
|     * check if the given value is a number | ||||
|     * @returns whether the value at the given index is a nil | ||||
|     */ | ||||
|    template<typename T> | ||||
|    bool state::is(int index) { | ||||
|       return lua_isnumber(L, index); | ||||
|    } | ||||
| 
 | ||||
|    /** Get the value at index as the given numeric type.
 | ||||
|     * @tparam T they numeric type to static_cast<T>() the numeric value on the | ||||
|     * stack to | ||||
|     * @param number where to store the value | ||||
|     * @param index the index to get | ||||
|     * @note This function does \em not pop the value from the stack. | ||||
|     * @todo Instead of throwing an exception here, we may just return an | ||||
|     * error code. | ||||
|     * @throws lua::bad_conversion if the value on the stack could not be | ||||
|     * converted to the indicated type | ||||
|     * @returns a reference to this lua::state | ||||
|     */ | ||||
|    template<typename T> | ||||
|    state& state::to(T& number, int index) { | ||||
|       if (lua_isnumber(L, index)) | ||||
|          number = static_cast<T>(lua_tonumber(L, index)); | ||||
|       else | ||||
|          throw bad_conversion("Cannot convert non 'number' value to number"); | ||||
| 
 | ||||
|       return *this; | ||||
|    } | ||||
| 
 | ||||
|    /** Get the value at index as (light) userdata.
 | ||||
|     * @tparam T the type of data pointed to (pointer is returned as | ||||
|     * reinterpret_cast<T>()) | ||||
|     * @param p the pointer to store the value in | ||||
|     * @param index the index to get | ||||
|     * @note This function does \em not pop the value from the stack. | ||||
|     * @todo Instead of throwing an exception here, we may just return an | ||||
|     * error code. | ||||
|     * @throws lua::bad_conversion if the value on the stack could not be | ||||
|     * converted to the indicated type | ||||
|     * @returns a reference to this lua::state | ||||
|     */ | ||||
|    template<typename T> | ||||
|    state& state::touserdata(T& p, int index) { | ||||
|       if (lua_isuserdata(L, index)) | ||||
|          p = reinterpret_cast<T>(lua_touserdata(L, index)); | ||||
|       else | ||||
|          throw bad_conversion("Cannot convert non 'userdata' or 'lightuserdata' value to userdata"); | ||||
| 
 | ||||
|       return *this; | ||||
|    } | ||||
| 
 | ||||
|    /** Get the value at index as the given type.
 | ||||
|     * @tparam T the type to retrieve the value on the stack as (the default | ||||
|     * template function uses lua_tonumber(), specializations may cause | ||||
|     * different behavior) | ||||
|     * @param default_value this value is returned if the conversion fails | ||||
|     * @param index the index to get | ||||
|     * @note This function does \em not pop the value from the stack. | ||||
|     * @returns the indicated value from the stack or the default value if | ||||
|     * the conversion fails | ||||
|     */ | ||||
|    template<typename T> | ||||
|    T state::as(T default_value, int index) { | ||||
|       if (lua_isnumber(L, index)) | ||||
|          return static_cast<T>(lua_tonumber(L, index)); | ||||
|       else | ||||
|          return default_value; | ||||
|    } | ||||
| 
 | ||||
|    /** Get the value at index as the given type.
 | ||||
|     * @tparam T the expected type of the value | ||||
|     * @param index the index to get | ||||
|     * | ||||
|     * @note This function does \em not pop the value from the stack. | ||||
|     * @note The default version of this function uses lua_tonumber() but | ||||
|     * specializations may cause different behavior. | ||||
|     * | ||||
|     * @todo Instead of throwing an exception here, we may just return an | ||||
|     * error code. | ||||
|     * | ||||
|     * @throws lua::bad_conversion if the value on the stack could not be | ||||
|     * converted to the indicated type | ||||
|     * | ||||
|     * This function will return the value on the stack as the given type.  If | ||||
|     * the value is not of the given type <em>no conversion will be | ||||
|     * performed</em> and lua::bad_conversion will be thrown.  There are some | ||||
|     * exceptions to this rule, for example, numbers will be converted to | ||||
|     * strings and vice-versa (conversion is only performed if the matching | ||||
|     * lua_is*() function returns true).  The state::to() function should be | ||||
|     * used to perform automatic conversion. | ||||
|     * | ||||
|     * @returns the indicated value as the given type if possible | ||||
|     */ | ||||
|    template<typename T> | ||||
|    T state::as(int index) { | ||||
|       if (lua_isnumber(L, index)) | ||||
|          return static_cast<T>(lua_tonumber(L, index)); | ||||
|       else | ||||
|          throw bad_conversion("Cannot convert non 'number' value to number"); | ||||
|    } | ||||
| 
 | ||||
|    /** Create a new userdatum on the stack.
 | ||||
|     * @tparam userdata_t the type of the userdata (will be passed to sizeof()) | ||||
|     * | ||||
|     * This function creates a new userdatum on the stack the size of | ||||
|     * userdata_t and return a pointer to it. | ||||
|     * @returns a pointer to the new userdatum | ||||
|     */ | ||||
|    template<typename userdata_t> | ||||
|    userdata_t* state::newuserdata() { | ||||
|       return reinterpret_cast<userdata_t*>(lua_newuserdata(L, sizeof(userdata_t))); | ||||
|    } | ||||
| 
 | ||||
|    /** Generate a Lua error.
 | ||||
|     * @tparam msg_t the type of error message data (should be automatically | ||||
|     * determined) | ||||
|     * @param message the error message/value | ||||
|     * @note This function is used to raise errors from lua::cfunctions. | ||||
|     * @note This function never returns, instead it throws an exception | ||||
|     * caught by the intepreter. | ||||
|     */ | ||||
|    template<typename msg_t> | ||||
|    void state::error(msg_t message) { | ||||
|       push(message); | ||||
|       lua_error(L); | ||||
|    } | ||||
| 
 | ||||
|    /** Load a sequence of data as a Lua chunk.
 | ||||
|     * @tparam iterator_t the type of iterator to use (should be automatically | ||||
|     * determined) | ||||
|     * @param begin an iterator to the start of the sequence | ||||
|     * @param end an iterator to the end of the sequence (one past the | ||||
|     * end) | ||||
|     * | ||||
|     * This function takes a sequence of data and attempts to convert it | ||||
|     * into a Lua chunk.  The type of data passed must be able to be | ||||
|     * converted into an 8-bit char. | ||||
|     * | ||||
|     * @note This function should automatically detect if the data is text | ||||
|     * or binary. | ||||
|     * | ||||
|     * @returns a reference to this lua::state | ||||
|     */ | ||||
|    template<typename iterator_t> | ||||
|    state& state::load(iterator_t begin, iterator_t end) { | ||||
|       // convert the data to characters
 | ||||
|       std::vector<char> chunk(begin, end); | ||||
| 
 | ||||
|       // Here we use the address of the first element of our vector.
 | ||||
|       // This works because the data in std::vectors is contiguous.
 | ||||
|       throw_error(luaL_loadbuffer(L, &(*chunk.begin()), chunk.size(), NULL)); | ||||
|       return *this; | ||||
|    } | ||||
| 
 | ||||
| 
 | ||||
|    // template specializations
 | ||||
|    template<> state& state::to(bool& boolean, int index); | ||||
|    template<> state& state::to(std::string& string, int index); | ||||
| 
 | ||||
|    template<> bool state::as(bool default_value, int index); | ||||
|    template<> std::string state::as(std::string default_value, int index); | ||||
|    template<> bool state::as(int index); | ||||
|    template<> std::string state::as(int index); | ||||
| 
 | ||||
|    template<> bool state::is<nil>(int index); | ||||
|    template<> bool state::is<bool>(int index); | ||||
|    template<> bool state::is<std::string>(int index); | ||||
|    template<> bool state::is<table>(int index); | ||||
|    template<> bool state::is<cfunction>(int index); | ||||
|    template<> bool state::is<function>(int index); | ||||
|    template<> bool state::is<userdata>(int index); | ||||
|    template<> bool state::is<lightuserdata>(int index); | ||||
| 
 | ||||
| 
 | ||||
|    // inline functions
 | ||||
| 
 | ||||
|    /** Convert a lua::state to a lua_State*.
 | ||||
|     * This operator allows lua::state to behave like a lua_State | ||||
|     * pointer. | ||||
|     * | ||||
|     * @note This should be used as a last result to interoperate with C | ||||
|     * code.  This may be removed in future versions of Luaxx. | ||||
|     */ | ||||
|    inline state::operator lua_State*() { | ||||
|       return L; | ||||
|    } | ||||
| 
 | ||||
|    /** Throws exceptions for error return codes.
 | ||||
|     * @param code the return code | ||||
|     * | ||||
|     * This function throws an exception based on the error it was passed. | ||||
|     * If it is passed a 0 it will not throw anything. | ||||
|     * | ||||
|     * @todo In the future this function may check an exception mask | ||||
|     * before throwing an error. | ||||
|     * | ||||
|     * @returns the code it was passed | ||||
|     */ | ||||
|    inline int state::throw_error(int code) { | ||||
|       std::string error; | ||||
| 
 | ||||
|       // below, we package lua errors into exceptions
 | ||||
|       switch (code) { | ||||
|          case 0: | ||||
|             break; | ||||
|          case LUA_ERRSYNTAX: | ||||
|             to(error).pop(); | ||||
|             throw syntax_error(error.c_str()); | ||||
|          case LUA_ERRMEM: | ||||
|             to(error).pop(); | ||||
|             throw bad_alloc(error.c_str()); | ||||
|          case LUA_ERRRUN: | ||||
|             to(error).pop(); | ||||
|             throw runtime_error(error.c_str()); | ||||
|          case LUA_ERRFILE: | ||||
|             to(error).pop(); | ||||
|             throw file_error(error.c_str()); | ||||
|          default: | ||||
|             to(error).pop(); | ||||
|             throw exception(error.c_str()); | ||||
|       } | ||||
|       return code; | ||||
|    } | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| #endif | ||||
| @ -0,0 +1,69 @@ | ||||
| #include "luamain.h" | ||||
| #include <vector> | ||||
| 
 | ||||
| 
 | ||||
| lua::glua* lua::glua::ptr=0; | ||||
| lua::glua::glua() | ||||
| { | ||||
|     RegBasics(mystate); | ||||
| } | ||||
| lua::state &lua::glua::Get() | ||||
| { | ||||
|     if(!glua::ptr) | ||||
|         glua::ptr=new glua(); | ||||
|     return glua::ptr->mystate; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| int lua_Ver_Lua(lua_State *L) | ||||
| { | ||||
|     lua::state st(L); | ||||
|     st.push(LUA_RELEASE); | ||||
|     return 1; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| static const struct luaL_reg lua_basic_lib [] = | ||||
| { | ||||
|     {"getluaver", lua_Ver_Lua}, | ||||
|     {NULL, NULL}  /* sentinel */ | ||||
| }; | ||||
| void lua::RegBasics(lua::state &L) | ||||
| { | ||||
|     luaL_openlibs(L); | ||||
|     RegFunctions(L,lua_basic_lib); | ||||
| } | ||||
| 
 | ||||
| void lua::RegFunctions(lua::state &L,luaL_reg const*arr) | ||||
| { | ||||
|     luaL_reg const *cur=arr; | ||||
|     while(cur->name!=NULL) | ||||
|     { | ||||
|         lua_pushcfunction(L, cur->func); | ||||
|         lua_setglobal(L, cur->name); | ||||
| 
 | ||||
|         cur++; | ||||
|     } | ||||
| } | ||||
| void lua::RegFunctionsLocal(lua::state &L,luaL_reg const*arr) | ||||
| { | ||||
|     luaL_reg const *cur=arr; | ||||
|     while(cur->name!=NULL) | ||||
|     { | ||||
|         lua_pushcfunction(L, cur->func); | ||||
|         //lua_setglobal(L, cur->name);
 | ||||
|         L.setfield(cur->name); | ||||
| 
 | ||||
|         cur++; | ||||
|     } | ||||
| } | ||||
| string lua::DebugDump(lua::state &L) | ||||
| { | ||||
|     L.getglobal("debug"); | ||||
|     L.getfield("traceback"); | ||||
|     L.call(0,1); | ||||
|     string ret=L.as<string>(); | ||||
|     //cout<<"StackTrace:"<<ret<<endl;
 | ||||
|     L.settop(0); | ||||
|     return ret; | ||||
| } | ||||
| @ -0,0 +1,824 @@ | ||||
| /* vim: set et sw=3 tw=0 fo=croqlaw cino=t0:
 | ||||
|  * | ||||
|  * Luaxx, the C++ Lua wrapper library. | ||||
|  * Copyright (c) 2006-2008 Matthew Nicholson | ||||
|  * | ||||
|  * Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|  * of this software and associated documentation files (the "Software"), to | ||||
|  * deal in the Software without restriction, including without limitation the | ||||
|  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or | ||||
|  * sell copies of the Software, and to permit persons to whom the Software is | ||||
|  * furnished to do so, subject to the following conditions: | ||||
|  * | ||||
|  * The above copyright notice and this permission notice shall be included in | ||||
|  * all copies or substantial portions of the Software. | ||||
|  * | ||||
|  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | ||||
|  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS | ||||
|  * IN THE SOFTWARE. | ||||
|  */ | ||||
| 
 | ||||
| #include <luaxx.hpp> | ||||
| #include <iostream> | ||||
| #define LOG std::cout | ||||
| /** @file
 | ||||
|  * Luaxx implementation file. | ||||
|  */ | ||||
| 
 | ||||
| namespace lua | ||||
| { | ||||
|     void StackDump(lua_State *L) | ||||
|     { | ||||
|         int i; | ||||
|         int top = lua_gettop(L); | ||||
|         for (i = 1; i <= top; i++)    /* repeat for each level */ | ||||
|         { | ||||
|             int t = lua_type(L, i); | ||||
|             LOG<<i<<":"; | ||||
|             switch (t) | ||||
|             { | ||||
| 
 | ||||
|             case LUA_TSTRING:  /* strings */ | ||||
|                 LOG<<"str ="<<lua_tostring(L, i)<<"\n"; | ||||
|                 break; | ||||
| 
 | ||||
|             case LUA_TBOOLEAN:  /* booleans */ | ||||
|                 LOG<<"bool="<<(lua_toboolean(L, i) ? "true" : "false")<<"\n"; | ||||
|                 break; | ||||
| 
 | ||||
|             case LUA_TNUMBER:  /* numbers */ | ||||
|                 LOG<<"num ="<<lua_tonumber(L, i)<<"\n"; | ||||
|                 break; | ||||
|             case LUA_TTABLE: | ||||
| 
 | ||||
|                 LOG<<lua_typename(L, t); | ||||
|                 { | ||||
|                     //LOG<<"PRE TOP:"<< lua_gettop(L)<<"\n";
 | ||||
|                     lua_getglobal(L,"PrintTable"); | ||||
|                     //lua_insert(L,-2);
 | ||||
|                     lua_pushvalue(L,i); | ||||
|                     lua_pcall(L,1,0,0); | ||||
|                     //LOG<<"POST TOP:"<< lua_gettop(L)<<"\n";
 | ||||
|                 } | ||||
| 
 | ||||
|                 break; | ||||
|             default:  /* other values */ | ||||
|                 LOG<<lua_typename(L, t); | ||||
|                 { | ||||
|                     //LOG<<"PRE TOP:"<< lua_gettop(L)<<"\n";
 | ||||
|                     lua_getglobal(L,"tostring"); | ||||
|                     //lua_insert(L,-2);
 | ||||
|                     lua_pushvalue(L,i); | ||||
|                     lua_pcall(L,1,1,0); | ||||
|                     LOG<<"="; | ||||
|                     LOG<<lua_tostring(L,-1)<<"\n"; | ||||
|                     lua_pop(L,1); | ||||
|                     //LOG<<"POST TOP:"<< lua_gettop(L)<<"\n";
 | ||||
|                 } | ||||
| 
 | ||||
|                 break; | ||||
| 
 | ||||
|             } | ||||
| 
 | ||||
|         } | ||||
|         LOG<<"\n";  /* end the listing */ | ||||
|         LOG<<"==============================\n"; | ||||
|     } | ||||
| #undef LOG | ||||
|    /// Construct our lua environment.
 | ||||
|    state::state() : L(luaL_newstate()), managed(true) { | ||||
|       if (L == NULL) | ||||
|          throw bad_alloc("Error creating lua state"); | ||||
|    } | ||||
| 
 | ||||
|    /** Construct our lua environment from an existing lua_State.
 | ||||
|     * @param L the existing state to use. | ||||
|     * | ||||
|     * This function differs from the normal constructor as it sets a flag | ||||
|     * that prevents lua_close() from being called when this class is | ||||
|     * destroyed. | ||||
|     */ | ||||
|    state::state(lua_State* L) : | ||||
|       L(L), managed(false) { | ||||
|    } | ||||
|    state& state::operator = (const state& t) | ||||
|     { | ||||
|              if(managed) | ||||
|                 lua_close(L); | ||||
|              managed=false; | ||||
|              L=t.L; | ||||
| 			 return *this; | ||||
|         } | ||||
|    /// Destroy our lua environment.
 | ||||
|    state::~state() { | ||||
|       if (managed) | ||||
|          lua_close(L); | ||||
|    } | ||||
| 
 | ||||
|    /** Push a nil onto the stack.
 | ||||
|     * @returns a reference to this lua::state | ||||
|     */ | ||||
|    state& state::push() { | ||||
|       lua_pushnil(L); | ||||
|       return *this; | ||||
|    } | ||||
| 
 | ||||
|    /** Push a nil onto the stack.
 | ||||
|     * @returns a reference to this lua::state | ||||
|     */ | ||||
|    state& state::push(nil) { | ||||
|       lua_pushnil(L); | ||||
|       return *this; | ||||
|    } | ||||
| 
 | ||||
|    /** Push a boolean onto the stack.
 | ||||
|     * @param boolean the value to push | ||||
|     * @returns a reference to this lua::state | ||||
|     */ | ||||
|    state& state::push(bool boolean) { | ||||
|       lua_pushboolean(L, boolean); | ||||
|       return *this; | ||||
|    } | ||||
| 
 | ||||
|    /** Push a C-style string onto the stack.
 | ||||
|     * @param s the string to push | ||||
|     * @param length the length of the string | ||||
|     * @returns a reference to this lua::state | ||||
|     */ | ||||
|    state& state::push(const char* s, size_t length) { | ||||
|       lua_pushlstring(L, s, length); | ||||
|       return *this; | ||||
|    } | ||||
| 
 | ||||
|    /** Push a C-style string onto the stack.
 | ||||
|     * @param s the string to push | ||||
|     * @note This must be a '0' terminated string. | ||||
|     * @returns a reference to this lua::state | ||||
|     */ | ||||
|    state& state::push(const char* s) { | ||||
|       lua_pushstring(L, s); | ||||
|       return *this; | ||||
|    } | ||||
| 
 | ||||
|    /** Push an std::string onto the stack.
 | ||||
|     * @param s the string to push | ||||
|     * @returns a reference to this lua::state | ||||
|     */ | ||||
|    state& state::push(const std::string& s) { | ||||
|       lua_pushlstring(L, s.c_str(), s.size()); | ||||
|       return *this; | ||||
|    } | ||||
| 
 | ||||
|    /** Push an C function onto the stack.
 | ||||
|     * @param f the function to push | ||||
|     * @returns a reference to this lua::state | ||||
|     */ | ||||
|    state& state::push(cfunction f) { | ||||
|       lua_pushcfunction(L, f); | ||||
|       return *this; | ||||
|    } | ||||
| 
 | ||||
|    /** Create a new table on to the stack.
 | ||||
|     * @see state::newtable() | ||||
|     * @returns a reference to this lua::state | ||||
|     */ | ||||
|    state& state::push(table) { | ||||
|       lua_newtable(L); | ||||
|       return *this; | ||||
|    } | ||||
| 
 | ||||
|    /** Push a light userdatum on to the stack.
 | ||||
|     * @param p the pointer to push | ||||
|     * @returns a reference to this lua::state | ||||
|     */ | ||||
|    state& state::push(void* p) { | ||||
|       lua_pushlightuserdata(L, p); | ||||
|       return *this; | ||||
|    } | ||||
| 
 | ||||
|    /** Get the value at index as a string.
 | ||||
|     * @param default_value this value is returned if the conversion fails | ||||
|     * @param index the index to get | ||||
|     * @note This function does \em not pop the value from the stack. | ||||
|     * | ||||
|     * @note lua::state::as(std::string()) will convert the value at the | ||||
|     * indicated index to a string <em>on the stack</em>.  This can | ||||
|     * confuse lua::state::next(); | ||||
|     * | ||||
|     * @returns the indicated value from the stack or the default value if the | ||||
|     * conversion fails | ||||
|     */ | ||||
|    template<> | ||||
|    std::string state::as(std::string default_value, int index) { | ||||
|       if (lua_isstring(L, index)) | ||||
|          return std::string(lua_tostring(L, index), lua_strlen(L, index)); | ||||
|       else | ||||
|          return default_value; | ||||
|    } | ||||
| 
 | ||||
|    /** Check an argument of the current function.
 | ||||
|     * @param narg the argument number to check | ||||
|     * | ||||
|     * This function will throw a lua error if there is no argument at the | ||||
|     * given position. | ||||
|     * | ||||
|     * @note This function is meant to be called from with in a lua::cfunction. | ||||
|     * The error throw is internal to the lua interpreter.  When compiled as | ||||
|     * C++, a C++ exception is thrown, so the stack is properly unwound.  This | ||||
|     * exception is not meant to be caught. | ||||
|     */ | ||||
|    state& state::check(int narg) { | ||||
|       luaL_checkany(L, narg); | ||||
|       return *this; | ||||
|    } | ||||
| 
 | ||||
| #ifndef lua_Integer_int | ||||
|    /** Check an argument of the current function.
 | ||||
|     * @param i the int to hold the returned value | ||||
|     * @param narg the argument number to check | ||||
|     * | ||||
|     * This function checks if the given argument number is an int. | ||||
|     * | ||||
|     * @note This function is meant to be called from with in a | ||||
|     * lua::cfunction.  The error throw is internal to the lua intrepeter. | ||||
|     * When compiled as C++, a C++ exception is thrown, so the stack is | ||||
|     * properly unwound.  This exception is not meant to be caught. | ||||
|     */ | ||||
|    state& state::check(int& i, int narg) { | ||||
|       i = luaL_checkint(L, narg); | ||||
|       return *this; | ||||
|    } | ||||
| #endif | ||||
| 
 | ||||
|    /** Check an argument of the current function.
 | ||||
|     * @param i the lua::integer (lua_Integer) to hold the returned value | ||||
|     * @param narg the argument number to check | ||||
|     * | ||||
|     * This function checks if the given argument number is an integer. | ||||
|     * | ||||
|     * @note This is different from lua::check(int(), ...).  It returns a | ||||
|     * lua::integer (lua_Integer), which may not be an int. | ||||
|     * | ||||
|     * @note This function is meant to be called from with in a | ||||
|     * lua::cfunction.  The error throw is internal to the lua intrepeter. | ||||
|     * When compiled as C++, a C++ exception is thrown, so the stack is | ||||
|     * properly unwound.  This exception is not meant to be caught. | ||||
|     */ | ||||
|    state& state::check(integer& i, int narg) { | ||||
|       i = luaL_checkinteger(L, narg); | ||||
|       return *this; | ||||
|    } | ||||
| 
 | ||||
| #ifndef lua_Integer_long | ||||
|    /** Check an argument of the current function.
 | ||||
|     * @param l the long to hold the returned value | ||||
|     * @param narg the argument number to check | ||||
|     * | ||||
|     * This function checks if the given argument number is a long. | ||||
|     * | ||||
|     * @note This function is meant to be called from with in a | ||||
|     * lua::cfunction.  The error throw is internal to the lua intrepeter. | ||||
|     * When compiled as C++, a C++ exception is thrown, so the stack is | ||||
|     * properly unwound.  This exception is not meant to be caught. | ||||
|     */ | ||||
|    state& state::check(long& l, int narg) { | ||||
|       l = luaL_checklong(L, narg); | ||||
|       return *this; | ||||
|    } | ||||
| #endif | ||||
| 
 | ||||
|    /** Check an argument of the current function.
 | ||||
|     * @param s the string to hold the returned value | ||||
|     * @param narg the argument number to check | ||||
|     * | ||||
|     * This function checks if the given argument number is a string. | ||||
|     * | ||||
|     * @note This function is meant to be called from with in a | ||||
|     * lua::cfunction.  The error throw is internal to the lua intrepeter. | ||||
|     * When compiled as C++, a C++ exception is thrown, so the stack is | ||||
|     * properly unwound.  This exception is not meant to be caught. | ||||
|     */ | ||||
|    state& state::check(std::string& s, int narg) { | ||||
|       const char* c; | ||||
|       size_t l; | ||||
|       c = luaL_checklstring(L, narg, &l); | ||||
| 
 | ||||
|       s.assign(c, l); | ||||
| 
 | ||||
|       return *this; | ||||
|    } | ||||
| 
 | ||||
|    /** Check an argument of the current function.
 | ||||
|     * @param n the lua::number (lua_Number) to hold the returned value | ||||
|     * @param narg the argument number to check | ||||
|     * | ||||
|     * This function checks if the given argument number is a lua::number | ||||
|     * (lua_Number, a double by default). | ||||
|     * | ||||
|     * @note This function is meant to be called from with in a lua::cfunction. | ||||
|     * The error throw is internal to the lua interpreter.  When compiled as | ||||
|     * C++, a C++ exception is thrown, so the stack is properly unwound.  This | ||||
|     * exception is not meant to be caught. | ||||
|     */ | ||||
|    state& state::check(number& n, int narg) { | ||||
|       n = luaL_checknumber(L, narg); | ||||
|       return *this; | ||||
|    } | ||||
| 
 | ||||
| #if 0 | ||||
|    /** [specialization] Generate a Lua error (T = std::string).
 | ||||
|     */ | ||||
|    template<> | ||||
|    void state::error(const std::string& message) { | ||||
|       push(message); | ||||
|       lua_error(L); | ||||
|    } | ||||
| #endif | ||||
| 
 | ||||
|    /** Call a lua function.
 | ||||
|     * @param nargs the number of args to pass to the function | ||||
|     * @param nresults the number of values to return from the function | ||||
|     * @param on_error A stack index where the error handling function is | ||||
|     * stored. | ||||
|     * @note The error handling function must be pushed in the stack | ||||
|     * before the function to be called and its arguments. | ||||
|     * @returns a reference to this lua::state | ||||
|     */ | ||||
|    state& state::pcall(int nargs, int nresults, int on_error) { | ||||
|       throw_error(lua_pcall(L, nargs, nresults, on_error)); | ||||
|       return *this; | ||||
|    } | ||||
| 
 | ||||
|    /** Call a lua function in unprotected mode.
 | ||||
|     * @param nargs the number of args to pass to the function | ||||
|     * @param nresults the number of values to return from the function | ||||
|     * stored. | ||||
|     * @note If there is an error in the call the program will terminate. | ||||
|     * @returns a reference to this lua::state | ||||
|     */ | ||||
|    state& state::call(int nargs, int nresults) { | ||||
|       lua_call(L, nargs, nresults); | ||||
|       return *this; | ||||
|    } | ||||
| 
 | ||||
|    /** Ensure the stack is at least the given size.
 | ||||
|     * @param size the size to use | ||||
|     * | ||||
|     * If the stack is smaller than the given size, it will grow to the | ||||
|     * specified size. | ||||
|     * | ||||
|     * @exception lua::exception Thrown if the operation fails. | ||||
|     * @returns a reference to this lua::state | ||||
|     */ | ||||
|    state& state::checkstack(int size) { | ||||
|       if (!lua_checkstack(L, size)) | ||||
|          throw lua::exception("Error growing the stack"); | ||||
|       return *this; | ||||
|    } | ||||
| 
 | ||||
|    /** Set a new index as the top of the stack.
 | ||||
|     * @param index the index to use as the new top | ||||
|     * @note If the previous top was higher than the new one, top values | ||||
|     * are discarded.  Otherwise this function pushs nils on to the stack | ||||
|     * to get the proper size. | ||||
|     * @returns a reference to this lua::state | ||||
|     */ | ||||
|    state& state::settop(int index) { | ||||
|       lua_settop(L, index); | ||||
|       return *this; | ||||
|    } | ||||
| 
 | ||||
|    /** Get the number of elements in the stack.
 | ||||
|     * @note This value is also the index of the top element. | ||||
|     * @returns the number of elements in the stack | ||||
|     */ | ||||
|    int state::gettop() { | ||||
|       return lua_gettop(L); | ||||
|    } | ||||
| 
 | ||||
|    /** Get the number of elements in the stack.
 | ||||
|     * @note This value is also the index of the top element. | ||||
|     * @returns the number of elements in the stack | ||||
|     */ | ||||
|    int state::size() { | ||||
|       return lua_gettop(L); | ||||
|    } | ||||
| 
 | ||||
|    /** Check if the stack is empty.
 | ||||
|     * @returns true if the stack is empty, false otherwise | ||||
|     */ | ||||
|    bool state::empty() { | ||||
|       return !lua_gettop(L); | ||||
|    } | ||||
| 
 | ||||
|    /** Move the top element to the given index.
 | ||||
|     * @param index the index to insert at | ||||
|     * @note All elements on top of the given index are shifted up to open | ||||
|     * space for this element. | ||||
|     * @returns a reference to this lua::state | ||||
|     */ | ||||
|    state& state::insert(int index) { | ||||
|       lua_insert(L, index); | ||||
|       return *this; | ||||
|    } | ||||
| 
 | ||||
|    /** Replace the given index with the top element.
 | ||||
|     * @param index the index to replae | ||||
|     * @returns a reference to this lua::state | ||||
|     */ | ||||
|    state& state::replace(int index) { | ||||
|       lua_replace(L, index); | ||||
|       return *this; | ||||
|    } | ||||
| 
 | ||||
|    /** Remove the given index from the stack.
 | ||||
|     * @param index the index to remove | ||||
|     * @note Elements are shifted down to fill in the empty spot. | ||||
|     * @returns a reference to this lua::state | ||||
|     */ | ||||
|    state& state::remove(int index) { | ||||
|       lua_remove(L, index); | ||||
|       return *this; | ||||
|    } | ||||
| 
 | ||||
|    /** Remove the given number of elemens from the stack.
 | ||||
|     * @param elements the number of elements to remove | ||||
|     * @returns a reference to this lua::state | ||||
|     */ | ||||
|    state& state::pop(int elements) { | ||||
|       lua_pop(L, elements); | ||||
|       return *this; | ||||
|    } | ||||
| 
 | ||||
|    /** Push a copy of the element at the given index to the top of the
 | ||||
|     * stack. | ||||
|     * @param index the index of the element to copy | ||||
|     * @returns a reference to this lua::state | ||||
|     */ | ||||
|    state& state::pushvalue(int index) { | ||||
|       lua_pushvalue(L, index); | ||||
|       return *this; | ||||
|    } | ||||
| 
 | ||||
|    /** Create a new table on the stack.
 | ||||
|     * @returns a reference to this lua::state | ||||
|     */ | ||||
|    state& state::newtable() { | ||||
|       lua_newtable(L); | ||||
|       return *this; | ||||
|    } | ||||
| 
 | ||||
|    /** Create a new metatable and add it to the registry.
 | ||||
|     * @param tname the name to use for the new metatable in the registry | ||||
|     * | ||||
|     * This function creates a new metatable and adds it to the registry | ||||
|     * with the given key.  This function also pushes the new metatable | ||||
|     * onto the stack. | ||||
|     * | ||||
|     * @note Regardless of the return value, the new metatable is always pushed | ||||
|     * on to the stack. | ||||
|     * | ||||
|     * @return true if a new metatable was created, false if the registry | ||||
|     * alread has a key with the given name. | ||||
|     */ | ||||
|    bool state::newmetatable(const std::string& tname) { | ||||
|       return luaL_newmetatable(L, tname.c_str()); | ||||
|    } | ||||
| 
 | ||||
|    /** Create a new userdatum on the stack.
 | ||||
|     * @param nbytes the size of the new userdatum | ||||
|     * @return a pointer to the new userdatum | ||||
|     */ | ||||
|    void* state::newuserdata(size_t nbytes) { | ||||
|       return lua_newuserdata(L, nbytes); | ||||
|    } | ||||
| 
 | ||||
|    /** Get a value from a table on the stack.
 | ||||
|     * @param index the index the table is stored at | ||||
|     * | ||||
|     * This function gets a value from the table at the given index and | ||||
|     * pushes it onto the stack. | ||||
|     * | ||||
|     * @note You should have already pushed the key used to reference this | ||||
|     * value onto the stack before calling this function. | ||||
|     * | ||||
|     * @returns a reference to this lua::state | ||||
|     */ | ||||
|    state& state::gettable(int index) { | ||||
|       lua_gettable(L, index); | ||||
|       return *this; | ||||
|    } | ||||
| 
 | ||||
|    /** Get a value from a table on the stack.
 | ||||
|     * @param k the key | ||||
|     * @param index the index the table is stored at | ||||
|     * | ||||
|     * This function gets a value from the table at the given index and | ||||
|     * pushes it onto the stack. | ||||
|     * | ||||
|     * @returns a reference to this lua::state | ||||
|     */ | ||||
|    state& state::getfield(const std::string& k, int index) { | ||||
|       lua_getfield(L, index, k.c_str()); | ||||
|       return *this; | ||||
|    } | ||||
| 
 | ||||
|    /** Set a value in a table.
 | ||||
|     * @param index the index the table is stored at | ||||
|     * | ||||
|     * This function sets a value in a table stored at the given index. | ||||
|     * | ||||
|     * @note The key and value to be used should have already been pushed | ||||
|     * on the stack in that order. | ||||
|     * | ||||
|     * @returns a reference to this lua::state | ||||
|     */ | ||||
|    state& state::settable(int index) { | ||||
|       lua_settable(L, index); | ||||
|       return *this; | ||||
|    } | ||||
| 
 | ||||
|    /** Set a field in a table.
 | ||||
|     * @param k the key | ||||
|     * @param index the index the table is stored at | ||||
|     * | ||||
|     * This function sets a value in a table stored at the given index. | ||||
|     * | ||||
|     * @note The value to be used should be on the top of the stack. | ||||
|     * | ||||
|     * @returns a reference to this lua::state | ||||
|     */ | ||||
|    state& state::setfield(const std::string& k, int index) { | ||||
|       lua_setfield(L, index, k.c_str()); | ||||
|       return *this; | ||||
|    } | ||||
| 
 | ||||
|    /** Get the metatable associated with the given registry entry.
 | ||||
|     * @param tname the name in the registry | ||||
|     * | ||||
|     * This function gets the metatable associated with the given key in | ||||
|     * the registry.  The resulting metatable is pushed onto the stack. | ||||
|     * | ||||
|     * @note This function uses luaL_getmetatable() internally. | ||||
|     * | ||||
|     * @returns a reference to this lua::state | ||||
|     */ | ||||
|    state& state::getmetatable(const std::string& tname) { | ||||
|       luaL_getmetatable(L, tname.c_str()); | ||||
|       return *this; | ||||
|    } | ||||
| 
 | ||||
|    /** Get the metatable of the value at the given index.
 | ||||
|     * @param index the index the value is stored at | ||||
|     * | ||||
|     * This function pushes on to the stack the metatabe of the value at | ||||
|     * the given index. | ||||
|     * | ||||
|     * @note This function uses lua_getmetatable() internally. | ||||
|     * | ||||
|     * @returns false if the value at the given index does not have a | ||||
|     * metatable or if the index is not valid | ||||
|     */ | ||||
|    bool state::getmetatable(int index) { | ||||
|       return lua_getmetatable(L, index); | ||||
|    } | ||||
| 
 | ||||
|    /** Get the next key value pair from a table on the stack.
 | ||||
|     * @param index the stack index the table is at | ||||
|     * | ||||
|     * This function pops a key from the stack and pushes the next key | ||||
|     * value pair to the stack.  The key will be stored at index -2 and | ||||
|     * the value will be at index -1.  The key is expected to be on the | ||||
|     * top of the stack. | ||||
|     * | ||||
|     * @note While traversing a table, do not call | ||||
|     * lua::state::to(std::string()) directly on a key, unless you know | ||||
|     * that the key is actually a string.  lua::state::to(std::string()) | ||||
|     * changes the value at the given index; this confuses the next call | ||||
|     * to lua::state::next(). | ||||
|     * | ||||
|     * <strong>While Loop Example:</strong> | ||||
|     * @code | ||||
|     * while(L.next() != 0) { | ||||
|     *    // do stuff
 | ||||
|     *    L.pop(); | ||||
|     * } | ||||
|     * @endcode | ||||
|     * | ||||
|     * <strong>For Loop Example:</strong> | ||||
|     * @code | ||||
|     * for(L.push(lua::nil()); L.next(); L.pop()) { | ||||
|     *    // do stuff
 | ||||
|     * } | ||||
|     * @endcode | ||||
|     * | ||||
|     * @returns true as long as there are remaining items in the table | ||||
|     */ | ||||
|    bool state::next(int index) { | ||||
|       return lua_next(L, index); | ||||
|    } | ||||
| 
 | ||||
|    /** Load a global symbol onto the stack.
 | ||||
|     * @param name the name of the global to load | ||||
|     * | ||||
|     * This function loads a global symbol onto the stack from the lua | ||||
|     * state. | ||||
|     * | ||||
|     * @returns a reference to this lua::state | ||||
|     */ | ||||
|    state& state::getglobal(const std::string& name) { | ||||
|       lua_getglobal(L, name.c_str()); | ||||
|       return *this; | ||||
|    } | ||||
| 
 | ||||
|    /** Set a global symbol.
 | ||||
|     * @param name the name of the global to set | ||||
|     * | ||||
|     * This function sets/creates a global symbol from the value above it | ||||
|     * on the stack. | ||||
|     * | ||||
|     * @note You should have pushed the value of the symbol onto the stack | ||||
|     * before calling this function. | ||||
|     * | ||||
|     * @returns a reference to this lua::state | ||||
|     */ | ||||
|    state& state::setglobal(const std::string& name) { | ||||
|       lua_setglobal(L, name.c_str()); | ||||
|       return *this; | ||||
|    } | ||||
| 
 | ||||
|    /** Load a file as a Lua chunk.
 | ||||
|     * @param filename the name of the file to load | ||||
|     * @returns a reference to this lua::state | ||||
|     */ | ||||
|    state& state::loadfile(const std::string& filename) { | ||||
|       throw_error(luaL_loadfile(L, filename.c_str())); | ||||
|       return *this; | ||||
|    } | ||||
| 
 | ||||
|    /** Load a string as a Lua chunk.
 | ||||
|     * @param s the string to load | ||||
|     * @returns a reference to this lua::state | ||||
|     */ | ||||
|    state& state::loadstring(const std::string& s) { | ||||
|       throw_error(luaL_loadstring(L, s.c_str())); | ||||
|       return *this; | ||||
|    } | ||||
| 
 | ||||
|    /** Get the length of a value on the stack.
 | ||||
|     * @param index the index the value is stored at | ||||
|     * @returns the length of the indicated value | ||||
|     */ | ||||
|    size_t state::objlen(int index) { | ||||
|       return lua_objlen(L, index); | ||||
|    } | ||||
| 
 | ||||
|    /** Get the value at index as a bool.
 | ||||
|     * @param boolean where to store the value | ||||
|     * @param index the index to get | ||||
|     * @note This function does \em not pop the value from the stack. | ||||
|     * @todo Instead of throwing an exception here, we may just return an | ||||
|     * error code. | ||||
|     * @throws lua::bad_conversion if the value on the stack could not be | ||||
|     * converted to the indicated type | ||||
|     * @returns a reference to this lua::state | ||||
|     */ | ||||
|    template<> | ||||
|    state& state::to(bool& boolean, int index) { | ||||
|       if (lua_isboolean(L, index)) | ||||
|          boolean = lua_toboolean(L, index); | ||||
|       else | ||||
|          throw bad_conversion("Cannot convert non 'boolean' value to bool"); | ||||
| 
 | ||||
|       return *this; | ||||
|    } | ||||
| 
 | ||||
|    /** Get the value at index as a string.
 | ||||
|     * @param string where to store the value | ||||
|     * @param index the index to get | ||||
|     * @note This function does \em not pop the value from the stack. | ||||
|     * @todo Instead of throwing an exception here, we may just return an | ||||
|     * error code. | ||||
|     * | ||||
|     * @note lua::state::to(std::string()) will convert the value at the | ||||
|     * indicated index to a string <em>on the stack</em>.  This can | ||||
|     * confuse lua::state::next(); | ||||
|     * | ||||
|     * @throws lua::bad_conversion if the value on the stack could not be | ||||
|     * converted to the indicated type | ||||
|     * @returns a reference to this lua::state | ||||
|     */ | ||||
|    template<> | ||||
|    state& state::to(std::string& string, int index) { | ||||
|       if (lua_isstring(L, index)) | ||||
|          string.replace(0, std::string::npos, lua_tostring(L, index), lua_strlen(L, index)); | ||||
|       else | ||||
|          throw bad_conversion("Cannot convert value to string"); | ||||
| 
 | ||||
|       return *this; | ||||
|    } | ||||
| 
 | ||||
|    /** Get the value at index as a bool.
 | ||||
|     * @param default_value this value is returned if the conversion fails | ||||
|     * @param index the index to get | ||||
|     * @note This function does \em not pop the value from the stack. | ||||
|     * @returns the indicated value from the stack or the default value if the | ||||
|     * conversion fails | ||||
|     */ | ||||
|    template<> | ||||
|    bool state::as(bool default_value, int index) { | ||||
|       if (lua_isboolean(L, index)) | ||||
|          return lua_toboolean(L, index); | ||||
|       else | ||||
|          return default_value; | ||||
|    } | ||||
| 
 | ||||
|    /** [specialization] Get the value at index as a bool (T = bool).
 | ||||
|     */ | ||||
|    template<> | ||||
|    bool state::as(int index) { | ||||
|       if (lua_isboolean(L, index)) | ||||
|          return lua_toboolean(L, index); | ||||
|       else | ||||
|          throw bad_conversion("Cannot convert non 'boolean' value to bool"); | ||||
|    } | ||||
| 
 | ||||
|    /** [specialization] Get the value at index as a string (T = std::string).
 | ||||
|     * @note lua::state::as(std::string()) will convert the value at the | ||||
|     * indicated index to a string <em>on the stack</em>.  This can confuse | ||||
|     * lua::state::next(); | ||||
|     */ | ||||
|    template<> | ||||
|    std::string state::as(int index) { | ||||
|       if (lua_isstring(L, index)) | ||||
|          return std::string(lua_tostring(L, index), lua_strlen(L, index)); | ||||
|       else | ||||
|          throw bad_conversion("Cannot convert value to string"); | ||||
|    } | ||||
| 
 | ||||
|    /** [specialization] Check if the given index is a nil (T = lua::nil).
 | ||||
|     */ | ||||
|    template<> | ||||
|    bool state::is<nil>(int index) { | ||||
|       return lua_isnil(L, index); | ||||
|    } | ||||
| 
 | ||||
|    /** [specialization] Check if the given index is a boolean (T = bool).
 | ||||
|     */ | ||||
|    template<> | ||||
|    bool state::is<bool>(int index) { | ||||
|       return lua_isboolean(L, index); | ||||
|    } | ||||
| 
 | ||||
|    /** [specialization] Check if the given index is a string (T = std::string).
 | ||||
|     */ | ||||
|    template<> | ||||
|    bool state::is<std::string>(int index) { | ||||
|       return lua_isstring(L, index); | ||||
|    } | ||||
| 
 | ||||
|    /** [specialization] Check if the given index is a table (T = lua::table).
 | ||||
|     */ | ||||
|    template<> | ||||
|    bool state::is<table>(int index) { | ||||
|       return lua_istable(L, index); | ||||
|    } | ||||
| 
 | ||||
|    /** [specialization] Check if the given index is a C function (T =
 | ||||
|     * lua::cfunction). | ||||
|     */ | ||||
|    template<> | ||||
|    bool state::is<cfunction>(int index) { | ||||
|       return lua_iscfunction(L, index); | ||||
|    } | ||||
| 
 | ||||
|    /** [specialization] Check if the given index is a function (T =
 | ||||
|     * lua::function). | ||||
|     */ | ||||
|    template<> | ||||
|    bool state::is<function>(int index) { | ||||
|       return lua_isfunction(L, index); | ||||
|    } | ||||
| 
 | ||||
|    /** [specialization] Check if the given index is userdata (T =
 | ||||
|     * lua::userdata). | ||||
|     */ | ||||
|    template<> | ||||
|    bool state::is<userdata>(int index) { | ||||
|       return lua_isuserdata(L, index); | ||||
|    } | ||||
| 
 | ||||
|    /** [specialization] Check if the given index is light userdata (T =
 | ||||
|     * lua::lightuserdata). | ||||
|     */ | ||||
|    template<> | ||||
|    bool state::is<lightuserdata>(int index) { | ||||
|       return lua_islightuserdata(L, index); | ||||
|    } | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
		Loading…
	
		Reference in New Issue