#ifndef _lua_int__hpp__included__ #define _lua_int__hpp__included__ #include "lua.hpp" #include #include extern "C" { #include } std::string get_string_argument(lua_State* LS, unsigned argindex, const char* fname); bool get_boolean_argument(lua_State* LS, unsigned argindex, const char* fname); void push_keygroup_parameters(lua_State* LS, const struct keygroup::parameters& p); extern lua_render_context* lua_render_ctx; extern controller_frame* lua_input_controllerdata; extern bool lua_booted_flag; template T get_numeric_argument(lua_State* LS, unsigned argindex, const char* fname) { if(lua_isnone(LS, argindex) || !lua_isnumber(LS, argindex)) { char buffer[1024]; sprintf(buffer, "argument #%i to %s must be numeric", argindex, fname); lua_pushstring(LS, buffer); lua_error(LS); } return static_cast(lua_tonumber(LS, argindex)); } template void get_numeric_argument(lua_State* LS, unsigned argindex, T& value, const char* fname) { if(lua_isnoneornil(LS, argindex)) return; if(lua_isnone(LS, argindex) || !lua_isnumber(LS, argindex)) { char buffer[1024]; sprintf(buffer, "argument #%i to %s must be numeric if present", argindex, fname); lua_pushstring(LS, buffer); lua_error(LS); } value = static_cast(lua_tonumber(LS, argindex)); } template struct lua_obj_pin { lua_obj_pin(lua_State* LS, T* _object) { lua_pushlightuserdata(LS, this); lua_pushvalue(LS, -2); lua_rawset(LS, LUA_REGISTRYINDEX); state = LS; obj = _object; } ~lua_obj_pin() { lua_pushlightuserdata(state, this); lua_pushnil(state); lua_rawset(state, LUA_REGISTRYINDEX); } T* object() { return obj; } private: T* obj; lua_State* state; lua_obj_pin(const lua_obj_pin&); lua_obj_pin& operator=(const lua_obj_pin&); }; template class lua_class; template lua_class& objclass(); template class lua_class { public: lua_class(const std::string& _name) { name = _name; } template T* _create(lua_State* LS, U... args) { void* obj = lua_newuserdata(LS, sizeof(T)); load_metatable(LS); lua_setmetatable(LS, -2); T* _obj = reinterpret_cast(obj); new(_obj) T(args...); return _obj; } template static T* create(lua_State* LS, U... args) { return objclass()._create(LS, args...); } void bind(lua_State* LS) { load_metatable(LS); lua_pushvalue(LS, -3); lua_pushvalue(LS, -3); lua_rawset(LS, -3); } void bind(lua_State* LS, const char* keyname) { load_metatable(LS); lua_pushstring(LS, keyname); lua_pushvalue(LS, -3); lua_rawset(LS, -3); } T* _get(lua_State* LS, int arg, const char* fname, bool optional = false) { if(lua_type(LS, arg) == LUA_TNONE || lua_type(LS, arg) == LUA_TNIL) { if(optional) return NULL; else goto badtype; } load_metatable(LS); if(!lua_getmetatable(LS, arg)) goto badtype; if(!lua_rawequal(LS, -1, -2)) goto badtype; lua_pop(LS, 2); return reinterpret_cast(lua_touserdata(LS, arg)); badtype: char buffer[2048]; sprintf(buffer, "argument #%i to %s must be %s", arg, fname, name.c_str()); lua_pushstring(LS, buffer); lua_error(LS); } static T* get(lua_State* LS, int arg, const char* fname, bool optional = false) { return objclass()._get(LS, arg, fname, optional); } bool _is(lua_State* LS, int arg) { if(lua_type(LS, arg) != LUA_TUSERDATA) return false; load_metatable(LS); if(!lua_getmetatable(LS, arg)) { lua_pop(LS, 1); return false; } bool ret = lua_rawequal(LS, -1, -2); lua_pop(LS, 2); return ret; } static bool is(lua_State* LS, int arg) { return objclass()._is(LS, arg); } lua_obj_pin* _pin(lua_State* LS, int arg, const char* fname) { T* obj = get(LS, arg, fname); lua_pushvalue(LS, arg); return new lua_obj_pin(LS, obj); } static lua_obj_pin* pin(lua_State* LS, int arg, const char* fname) { return objclass()._pin(LS, arg, fname); } private: static int dogc(lua_State* LS) { T* obj = reinterpret_cast(lua_touserdata(LS, 1)); obj->~T(); } void load_metatable(lua_State* LS) { again: lua_pushlightuserdata(LS, this); lua_rawget(LS, LUA_REGISTRYINDEX); if(lua_type(LS, -1) == LUA_TNIL) { lua_pop(LS, 1); lua_pushlightuserdata(LS, this); lua_newtable(LS); lua_pushstring(LS, "__gc"); lua_pushcfunction(LS, &lua_class::dogc); lua_rawset(LS, -3); lua_rawset(LS, LUA_REGISTRYINDEX); goto again; } } std::string name; lua_class(const lua_class&); lua_class& operator=(const lua_class&); }; #define DECLARE_LUACLASS(x, X) template<> lua_class< x >& objclass() { static lua_class< x > clazz( X ); \ return clazz; } #endif