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