Merge branch 'dfapi' of https://github.com/warmist/dfhack
						commit
						761d0de74a
					
				@ -0,0 +1,15 @@
 | 
			
		||||
find_package(Lua51 QUIET)
 | 
			
		||||
 | 
			
		||||
if(LUA51_FOUND)
 | 
			
		||||
	include_directories(${LUA_INCLUDE_DIR} include)
 | 
			
		||||
	FILE(GLOB DFUSION_CPPS src/*.c*)
 | 
			
		||||
	set(
 | 
			
		||||
		DFUSION_CPPS_ALL
 | 
			
		||||
		dfusion.cpp
 | 
			
		||||
		${DFUSION_CPPS}
 | 
			
		||||
	)
 | 
			
		||||
	DFHACK_PLUGIN(dfusion  ${DFUSION_CPPS_ALL})
 | 
			
		||||
	target_link_libraries(dfusion ${LUA_LIBRARIES})
 | 
			
		||||
else(LUA51_FOUND)
 | 
			
		||||
	MESSAGE(STATUS "Required libraries (lua51) not found - dfusion plugin can't be built.")
 | 
			
		||||
endif(LUA51_FOUND)
 | 
			
		||||
@ -0,0 +1,124 @@
 | 
			
		||||
#include <dfhack/Core.h>
 | 
			
		||||
#include <dfhack/Console.h>
 | 
			
		||||
#include <dfhack/Export.h>
 | 
			
		||||
#include <dfhack/PluginManager.h>
 | 
			
		||||
#include <dfhack/Process.h>
 | 
			
		||||
#include <vector>
 | 
			
		||||
#include <string>
 | 
			
		||||
 | 
			
		||||
#include "luamain.h"
 | 
			
		||||
#include "lua_Console.h"
 | 
			
		||||
#include "functioncall.h"
 | 
			
		||||
 | 
			
		||||
using std::vector;
 | 
			
		||||
using std::string;
 | 
			
		||||
using namespace DFHack;
 | 
			
		||||
 | 
			
		||||
static SDL::Mutex* mymutex=0;
 | 
			
		||||
 | 
			
		||||
DFhackCExport command_result dfusion (Core * c, vector <string> & parameters);
 | 
			
		||||
DFhackCExport command_result lua_run (Core * c, vector <string> & parameters);
 | 
			
		||||
 | 
			
		||||
 typedef
 | 
			
		||||
 int  (__thiscall *dfprint)(const char*, char, char,void *) ; 
 | 
			
		||||
 | 
			
		||||
DFhackCExport const char * plugin_name ( void )
 | 
			
		||||
{
 | 
			
		||||
    return "dfusion";
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
DFhackCExport command_result plugin_init ( Core * c, std::vector <PluginCommand> &commands)
 | 
			
		||||
{
 | 
			
		||||
    commands.clear();
 | 
			
		||||
	//maybe remake it to run automaticaly
 | 
			
		||||
	lua::RegisterConsole(lua::glua::Get(),&c->con);
 | 
			
		||||
 | 
			
		||||
    commands.push_back(PluginCommand("dfusion","Init dfusion system.",dfusion));
 | 
			
		||||
	commands.push_back(PluginCommand("lua", "Run interactive interpreter.\
 | 
			
		||||
\n              Options: <filename> = run <filename> instead",lua_run));
 | 
			
		||||
	
 | 
			
		||||
	mymutex=SDL_CreateMutex();
 | 
			
		||||
    return CR_OK;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
DFhackCExport command_result plugin_shutdown ( Core * c )
 | 
			
		||||
{
 | 
			
		||||
	
 | 
			
		||||
// shutdown stuff
 | 
			
		||||
	return CR_OK;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
DFhackCExport command_result plugin_onupdate ( Core * c )
 | 
			
		||||
{
 | 
			
		||||
    /*if(timering == true) //TODO maybe reuse this to make it run less often.
 | 
			
		||||
    {
 | 
			
		||||
        uint64_t time2 = GetTimeMs64();
 | 
			
		||||
        uint64_t delta = time2-timeLast;
 | 
			
		||||
        timeLast = time2;
 | 
			
		||||
        c->con.print("Time delta = %d ms\n", delta);
 | 
			
		||||
    }
 | 
			
		||||
    return CR_OK;*/
 | 
			
		||||
	SDL_mutexP(mymutex); 
 | 
			
		||||
	lua::state s=lua::glua::Get();
 | 
			
		||||
	s.getglobal("OnTick");
 | 
			
		||||
	if(s.is<lua::function>())
 | 
			
		||||
	{
 | 
			
		||||
		try{
 | 
			
		||||
			s.pcall();
 | 
			
		||||
		}
 | 
			
		||||
		catch(lua::exception &e)
 | 
			
		||||
		{
 | 
			
		||||
			c->con.printerr("Error OnTick:%s\n",e.what());
 | 
			
		||||
			c->con.msleep(1000);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	s.settop(0);
 | 
			
		||||
	SDL_mutexV(mymutex);
 | 
			
		||||
	return CR_OK;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
DFhackCExport command_result lua_run (Core * c, vector <string> & parameters)
 | 
			
		||||
{
 | 
			
		||||
	Console &con=c->con;
 | 
			
		||||
	SDL_mutexP(mymutex);
 | 
			
		||||
	lua::state s=lua::glua::Get();
 | 
			
		||||
	if(parameters.size()>0)
 | 
			
		||||
	{
 | 
			
		||||
		try{
 | 
			
		||||
			s.loadfile(parameters[0]); //load file
 | 
			
		||||
			s.pcall(0,0);// run it
 | 
			
		||||
		}
 | 
			
		||||
		catch(lua::exception &e)
 | 
			
		||||
		{
 | 
			
		||||
			con.printerr("Error:%s\n",e.what());
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
	{
 | 
			
		||||
		//TODO interpreter...
 | 
			
		||||
	}
 | 
			
		||||
	s.settop(0);// clean up
 | 
			
		||||
	SDL_mutexV(mymutex);
 | 
			
		||||
	return CR_OK;
 | 
			
		||||
}
 | 
			
		||||
DFhackCExport command_result dfusion (Core * c, vector <string> & parameters)
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
	Console &con=c->con;
 | 
			
		||||
	con.print("%x\n",c->p->getBase());
 | 
			
		||||
	SDL_mutexP(mymutex);
 | 
			
		||||
	lua::state s=lua::glua::Get();
 | 
			
		||||
	
 | 
			
		||||
	try{
 | 
			
		||||
		s.loadfile("dfusion/init.lua"); //load script
 | 
			
		||||
		s.pcall(0,0);// run it
 | 
			
		||||
	}
 | 
			
		||||
	catch(lua::exception &e)
 | 
			
		||||
	{
 | 
			
		||||
		con.printerr("Error:%s\n",e.what());
 | 
			
		||||
	}
 | 
			
		||||
	s.settop(0);// clean up
 | 
			
		||||
	SDL_mutexV(mymutex);
 | 
			
		||||
	return CR_OK;
 | 
			
		||||
}
 | 
			
		||||
@ -0,0 +1,25 @@
 | 
			
		||||
#ifndef FUNCTIONCALL__H
 | 
			
		||||
#define FUNCTIONCALL__H
 | 
			
		||||
#include <vector>
 | 
			
		||||
using std::vector;
 | 
			
		||||
class FunctionCaller
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
	enum callconv
 | 
			
		||||
	{
 | 
			
		||||
		STD_CALL, //__stdcall - all in stack
 | 
			
		||||
		FAST_CALL, //__fastcall - as much in registers as fits
 | 
			
		||||
		THIS_CALL, //__thiscall - eax ptr to this, rest in stack
 | 
			
		||||
		CDECL_CALL //__cdecl - same as stdcall but no stack realign
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	FunctionCaller(size_t base):base_(base){};
 | 
			
		||||
 | 
			
		||||
	int CallFunction(size_t func_ptr,callconv conv,const vector<int> &arguments);
 | 
			
		||||
	
 | 
			
		||||
private:
 | 
			
		||||
	int CallF(size_t count,callconv conv,void* f,const vector<int> &arguments);
 | 
			
		||||
	size_t base_;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif //FUNCTIONCALL__H
 | 
			
		||||
@ -0,0 +1,13 @@
 | 
			
		||||
#ifndef LUA_CONSOLE_H
 | 
			
		||||
#define LUA_CONSOLE_H
 | 
			
		||||
#include <dfhack/Console.h>
 | 
			
		||||
#include "luamain.h"
 | 
			
		||||
 | 
			
		||||
namespace lua
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
void RegisterConsole(lua::state &st, DFHack::Console *c);
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
@ -0,0 +1,40 @@
 | 
			
		||||
#ifndef LUAMAIN_H
 | 
			
		||||
#define LUAMAIN_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 // LUAMAIN_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,112 @@
 | 
			
		||||
#include "functioncall.h"
 | 
			
		||||
#define __F_TDEF(CONV,CONV_,tag) typedef int(CONV_ *F_TYPE##CONV##tag)
 | 
			
		||||
#define __F_T(CONV,tag) F_TYPE##CONV##tag
 | 
			
		||||
#define __F_TYPEDEFS(CONV,CONV_)	__F_TDEF(CONV,CONV_,1)(int);\
 | 
			
		||||
	__F_TDEF(CONV,CONV_,2)(int,int);\
 | 
			
		||||
	__F_TDEF(CONV,CONV_,3)(int,int,int);\
 | 
			
		||||
	__F_TDEF(CONV,CONV_,4)(int,int,int,int);\
 | 
			
		||||
	__F_TDEF(CONV,CONV_,5)(int,int,int,int,int);\
 | 
			
		||||
	__F_TDEF(CONV,CONV_,6)(int,int,int,int,int,int);\
 | 
			
		||||
	__F_TDEF(CONV,CONV_,7)(int,int,int,int,int,int,int)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#define __FCALL(CONV,CONV_) if(conv==CONV)\
 | 
			
		||||
	{	\
 | 
			
		||||
		if(count==1)\
 | 
			
		||||
			ret= (reinterpret_cast<__F_T(CONV,1)>(f))\
 | 
			
		||||
				   (arguments[0]);\
 | 
			
		||||
		else if(count==2)\
 | 
			
		||||
			ret= (reinterpret_cast<__F_T(CONV,2)>(f))\
 | 
			
		||||
				   (arguments[0],arguments[1]);\
 | 
			
		||||
		else if(count==3)\
 | 
			
		||||
			ret= (reinterpret_cast<__F_T(CONV,3)>(f))\
 | 
			
		||||
				   (arguments[0],arguments[1],arguments[2]);\
 | 
			
		||||
		else if(count==4)\
 | 
			
		||||
			ret= (reinterpret_cast<__F_T(CONV,4)>(f))\
 | 
			
		||||
			       (arguments[0],arguments[1],arguments[2],arguments[3]);\
 | 
			
		||||
		else if(count==5)\
 | 
			
		||||
			ret= (reinterpret_cast<__F_T(CONV,5)>(f))\
 | 
			
		||||
			       (arguments[0],arguments[1],arguments[2],arguments[3],arguments[4]);\
 | 
			
		||||
		else if(count==6)\
 | 
			
		||||
			ret= (reinterpret_cast<__F_T(CONV,6)>(f))\
 | 
			
		||||
			       (arguments[0],arguments[1],arguments[2],arguments[3],arguments[4],arguments[5]);\
 | 
			
		||||
		else if(count==7)\
 | 
			
		||||
			ret= (reinterpret_cast<__F_T(CONV,7)>(f))\
 | 
			
		||||
			       (arguments[0],arguments[1],arguments[2],arguments[3],arguments[4],arguments[5],arguments[6]);\
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
#define __FCALLEX(CONV,CONV_) if(conv==CONV)\
 | 
			
		||||
	{	if(count==1)	 {__F_T(CONV,1) tmp_F=reinterpret_cast<__F_T(CONV,1)>(f); return tmp_F(arguments[0]);}\
 | 
			
		||||
		else if(count==2){__F_T(CONV,2) tmp_F=reinterpret_cast<__F_T(CONV,2)>(f); return tmp_F(arguments[0],arguments[1]);}\
 | 
			
		||||
		else if(count==3){__F_T(CONV,3) tmp_F=reinterpret_cast<__F_T(CONV,3)>(f); return tmp_F(arguments[0],arguments[1],arguments[2]);}\
 | 
			
		||||
		else if(count==4){__F_T(CONV,4) tmp_F=reinterpret_cast<__F_T(CONV,4)>(f); return tmp_F(arguments[0],arguments[1],arguments[2],arguments[3]);}\
 | 
			
		||||
		else if(count==5){__F_T(CONV,5) tmp_F=reinterpret_cast<__F_T(CONV,5)>(f); return tmp_F(arguments[0],arguments[1],arguments[2],arguments[3],arguments[4]);}\
 | 
			
		||||
		else if(count==6){__F_T(CONV,6) tmp_F=reinterpret_cast<__F_T(CONV,6)>(f); return tmp_F(arguments[0],arguments[1],arguments[2],arguments[3],arguments[4],arguments[5]);}\
 | 
			
		||||
		else if(count==7){__F_T(CONV,7) tmp_F=reinterpret_cast<__F_T(CONV,7)>(f); return tmp_F(arguments[0],arguments[1],arguments[2],arguments[3],arguments[4],arguments[5],arguments[6]);}\
 | 
			
		||||
	}
 | 
			
		||||
		/*else if(count==8)\
 | 
			
		||||
			ret= (reinterpret_cast<__F_T(CONV,8)>(f))\
 | 
			
		||||
			       (arguments[0],arguments[1],arguments[2],arguments[3],arguments[4],arguments[5],arguments[6],arguments[7]);\
 | 
			
		||||
		else if(count==9)\
 | 
			
		||||
			ret= (reinterpret_cast<int (CONV_*)(int,int,int,int,int\
 | 
			
		||||
												,int,int,int,int)>(f))\
 | 
			
		||||
			       (arguments[0],arguments[1],arguments[2],arguments[3],arguments[4],arguments[5],arguments[6],arguments[7],arguments[8]);\
 | 
			
		||||
		else if(count==10)\
 | 
			
		||||
			ret= (reinterpret_cast<int (CONV_*)(int,int,int,int,int\
 | 
			
		||||
												,int,int,int,int,int)>(f))\
 | 
			
		||||
			       (arguments[0],arguments[1],arguments[2],arguments[3],arguments[4],arguments[5],arguments[6],arguments[7],arguments[8],arguments[9]);}*/
 | 
			
		||||
	
 | 
			
		||||
 | 
			
		||||
int FunctionCaller::CallF(size_t count,callconv conv,void* f,const vector<int> &arguments)//more complex but not more error safe
 | 
			
		||||
{
 | 
			
		||||
	__F_TYPEDEFS(STD_CALL,__stdcall);
 | 
			
		||||
	__F_TYPEDEFS(FAST_CALL,__fastcall);
 | 
			
		||||
	__F_TYPEDEFS(THIS_CALL,__thiscall);
 | 
			
		||||
	__F_TYPEDEFS(CDECL_CALL,__cdecl);
 | 
			
		||||
	{
 | 
			
		||||
	__FCALLEX(STD_CALL,__stdcall);
 | 
			
		||||
	__FCALLEX(FAST_CALL,__fastcall);
 | 
			
		||||
	__FCALLEX(THIS_CALL,__thiscall);
 | 
			
		||||
	__FCALLEX(CDECL_CALL,__cdecl);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
int FunctionCaller::CallFunction(size_t func_ptr,callconv conv,const vector<int> &arguments)
 | 
			
		||||
{
 | 
			
		||||
	//nasty nasty code...
 | 
			
		||||
	
 | 
			
		||||
	void* f= reinterpret_cast<void*>(func_ptr+base_);
 | 
			
		||||
	size_t count=arguments.size();
 | 
			
		||||
	if(count==0)
 | 
			
		||||
		return (reinterpret_cast<int (*)()>(f))(); //does not matter how we call it...
 | 
			
		||||
	int ret=0;
 | 
			
		||||
	//typedefs
 | 
			
		||||
	__F_TYPEDEFS(STD_CALL,__stdcall);
 | 
			
		||||
	__F_TYPEDEFS(FAST_CALL,__fastcall);
 | 
			
		||||
	__F_TYPEDEFS(THIS_CALL,__thiscall);
 | 
			
		||||
	__F_TYPEDEFS(CDECL_CALL,__cdecl);
 | 
			
		||||
	//calls
 | 
			
		||||
	__FCALL(STD_CALL,__stdcall);
 | 
			
		||||
	__FCALL(FAST_CALL,__fastcall);
 | 
			
		||||
	__FCALL(THIS_CALL,__thiscall);
 | 
			
		||||
	__FCALL(CDECL_CALL,__cdecl);
 | 
			
		||||
	return -1; //incorect type. Should probably throw...
 | 
			
		||||
	//return CallF(count,conv,f,arguments);
 | 
			
		||||
	/*//testing part{  worked some time ago..., put where DFHack::Core is accesible
 | 
			
		||||
	c->Suspend();
 | 
			
		||||
	FunctionCaller caller(c->p->getBase()); 
 | 
			
		||||
	std::vector <int> args;
 | 
			
		||||
	args.push_back((size_t)"Hello world");
 | 
			
		||||
	args.push_back(4);
 | 
			
		||||
	args.push_back(4);
 | 
			
		||||
	args.push_back(0);
 | 
			
		||||
	dfprint  mprint=(dfprint)(0x27F030+c->p->getBase());
 | 
			
		||||
	mprint("Hello world",4,4,0);
 | 
			
		||||
	//caller.CallFunction((0x27F030),FunctionCaller::THIS_CALL,args);
 | 
			
		||||
	c->Resume();
 | 
			
		||||
	return CR_OK;
 | 
			
		||||
	//}end testing*/
 | 
			
		||||
}
 | 
			
		||||
#undef __FCALL
 | 
			
		||||
#undef __FCALLEX
 | 
			
		||||
#undef __F_TYPEDEFS
 | 
			
		||||
#undef __F_T
 | 
			
		||||
@ -0,0 +1,137 @@
 | 
			
		||||
#include "lua_Console.h"
 | 
			
		||||
//TODO error management. Using lua error? or something other?
 | 
			
		||||
static DFHack::Console* GetConsolePtr(lua::state &st)
 | 
			
		||||
{
 | 
			
		||||
	int t=st.gettop();
 | 
			
		||||
	st.getglobal("Console");
 | 
			
		||||
	st.getfield("__pointer");
 | 
			
		||||
	DFHack::Console* c=static_cast<DFHack::Console*>(lua_touserdata(st,-1));
 | 
			
		||||
	st.settop(t);
 | 
			
		||||
	return c;
 | 
			
		||||
}
 | 
			
		||||
static int lua_Console_print(lua_State *S)
 | 
			
		||||
{
 | 
			
		||||
	lua::state st(S);
 | 
			
		||||
	int t=st.gettop();
 | 
			
		||||
	DFHack::Console* c=GetConsolePtr(st);
 | 
			
		||||
	c->print("%s",st.as<string>(t).c_str());
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int lua_Console_printerr(lua_State *S)
 | 
			
		||||
{
 | 
			
		||||
	lua::state st(S);
 | 
			
		||||
	int t=st.gettop();
 | 
			
		||||
	DFHack::Console* c=GetConsolePtr(st);
 | 
			
		||||
	c->printerr("%s",st.as<string>(t).c_str());
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int lua_Console_clear(lua_State *S)
 | 
			
		||||
{
 | 
			
		||||
	lua::state st(S);
 | 
			
		||||
	DFHack::Console* c=GetConsolePtr(st);
 | 
			
		||||
	c->clear();
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
static int lua_Console_gotoxy(lua_State *S)
 | 
			
		||||
{
 | 
			
		||||
	lua::state st(S);
 | 
			
		||||
	DFHack::Console* c=GetConsolePtr(st);
 | 
			
		||||
	c->gotoxy(st.as<int>(1,1),st.as<int>(1,2));
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
static int lua_Console_color(lua_State *S)
 | 
			
		||||
{
 | 
			
		||||
	lua::state st(S);
 | 
			
		||||
	DFHack::Console* c=GetConsolePtr(st);
 | 
			
		||||
	c->color( static_cast<DFHack::Console::color_value>(st.as<int>(-1,1)) );
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
static int lua_Console_reset_color(lua_State *S)
 | 
			
		||||
{
 | 
			
		||||
	lua::state st(S);
 | 
			
		||||
	DFHack::Console* c=GetConsolePtr(st);
 | 
			
		||||
	c->reset_color();
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
static int lua_Console_cursor(lua_State *S)
 | 
			
		||||
{
 | 
			
		||||
	lua::state st(S);
 | 
			
		||||
	DFHack::Console* c=GetConsolePtr(st);
 | 
			
		||||
	c->cursor(st.as<bool>(1));
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
static int lua_Console_msleep(lua_State *S)
 | 
			
		||||
{
 | 
			
		||||
	lua::state st(S);
 | 
			
		||||
	DFHack::Console* c=GetConsolePtr(st);
 | 
			
		||||
	c->msleep(st.as<unsigned>(1));
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
static int lua_Console_get_columns(lua_State *S)
 | 
			
		||||
{
 | 
			
		||||
	lua::state st(S);
 | 
			
		||||
	DFHack::Console* c=GetConsolePtr(st);
 | 
			
		||||
	st.push(c->get_columns());
 | 
			
		||||
	return 1;
 | 
			
		||||
}
 | 
			
		||||
static int lua_Console_get_rows(lua_State *S)
 | 
			
		||||
{
 | 
			
		||||
	lua::state st(S);
 | 
			
		||||
	DFHack::Console* c=GetConsolePtr(st);
 | 
			
		||||
	st.push(c->get_rows());
 | 
			
		||||
	return 1;
 | 
			
		||||
}
 | 
			
		||||
static int lua_Console_lineedit(lua_State *S)
 | 
			
		||||
{
 | 
			
		||||
	lua::state st(S);
 | 
			
		||||
	DFHack::Console* c=GetConsolePtr(st);
 | 
			
		||||
	string ret;
 | 
			
		||||
	int i=c->lineedit(st.as<string>(1),ret);
 | 
			
		||||
	st.push(ret);
 | 
			
		||||
	st.push(i);
 | 
			
		||||
	return 2;// dunno if len is needed...
 | 
			
		||||
}
 | 
			
		||||
static int lua_Console_history_add(lua_State *S)
 | 
			
		||||
{
 | 
			
		||||
	lua::state st(S);
 | 
			
		||||
	DFHack::Console* c=GetConsolePtr(st);
 | 
			
		||||
	c->history_add(st.as<string>(1));
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
/*static int lua_Console_history_clear(lua_State *S) //TODO someday add this
 | 
			
		||||
{
 | 
			
		||||
	lua::state st(S);
 | 
			
		||||
	DFHack::Console* c=GetConsolePtr(st);
 | 
			
		||||
	c->history_clear();
 | 
			
		||||
	return 0;
 | 
			
		||||
}*/
 | 
			
		||||
const luaL_Reg lua_console_func[]=
 | 
			
		||||
{
 | 
			
		||||
	{"print",lua_Console_print},
 | 
			
		||||
	{"printerr",lua_Console_printerr},
 | 
			
		||||
	{"clear",lua_Console_clear},
 | 
			
		||||
	{"gotoxy",lua_Console_gotoxy},
 | 
			
		||||
	{"color",lua_Console_color},
 | 
			
		||||
	{"reset_color",lua_Console_reset_color},
 | 
			
		||||
	{"cursor",lua_Console_cursor},
 | 
			
		||||
	{"msleep",lua_Console_msleep},
 | 
			
		||||
	{"get_columns",lua_Console_get_columns},
 | 
			
		||||
	{"get_rows",lua_Console_get_rows},
 | 
			
		||||
	{"lineedit",lua_Console_lineedit},
 | 
			
		||||
	{"history_add",lua_Console_history_add},
 | 
			
		||||
	//{"history_clear",lua_Console_history_clear},
 | 
			
		||||
	{NULL,NULL}
 | 
			
		||||
};
 | 
			
		||||
void lua::RegisterConsole(lua::state &st, DFHack::Console *c)
 | 
			
		||||
{
 | 
			
		||||
	st.newtable();
 | 
			
		||||
 | 
			
		||||
	st.pushlightuserdata(c);
 | 
			
		||||
	st.setfield("__pointer");
 | 
			
		||||
	
 | 
			
		||||
	lua::RegFunctionsLocal(st, lua_console_func);
 | 
			
		||||
	//TODO add color consts
 | 
			
		||||
	st.setglobal("Console");
 | 
			
		||||
}
 | 
			
		||||
@ -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