Lua: memory.map_structure
[lsnes.git] / include / lua / internal.hpp
blob2037472a6bad193f7d5fcc5bbaf44d7e6e77b8d4
1 #ifndef _lua_int__hpp__included__
2 #define _lua_int__hpp__included__
4 #include "lua.hpp"
5 #include <cstdio>
6 #include <cstdlib>
7 #include <iostream>
8 extern "C"
10 #include <lua.h>
13 std::string get_string_argument(lua_State* LS, unsigned argindex, const char* fname);
14 bool get_boolean_argument(lua_State* LS, unsigned argindex, const char* fname);
15 void push_keygroup_parameters(lua_State* LS, const struct keygroup::parameters& p);
16 extern lua_render_context* lua_render_ctx;
17 extern controller_frame* lua_input_controllerdata;
18 extern bool lua_booted_flag;
19 extern uint64_t lua_idle_hook_time;
20 extern uint64_t lua_timer_hook_time;
22 template<typename T>
23 T get_numeric_argument(lua_State* LS, unsigned argindex, const char* fname)
25 if(lua_isnone(LS, argindex) || !lua_isnumber(LS, argindex)) {
26 char buffer[1024];
27 sprintf(buffer, "argument #%i to %s must be numeric", argindex, fname);
28 lua_pushstring(LS, buffer);
29 lua_error(LS);
31 return static_cast<T>(lua_tonumber(LS, argindex));
34 template<typename T>
35 void get_numeric_argument(lua_State* LS, unsigned argindex, T& value, const char* fname)
37 if(lua_isnoneornil(LS, argindex))
38 return;
39 if(lua_isnone(LS, argindex) || !lua_isnumber(LS, argindex)) {
40 char buffer[1024];
41 sprintf(buffer, "argument #%i to %s must be numeric if present", argindex, fname);
42 lua_pushstring(LS, buffer);
43 lua_error(LS);
45 value = static_cast<T>(lua_tonumber(LS, argindex));
49 template<typename T> struct lua_obj_pin
51 lua_obj_pin(lua_State* LS, T* _object)
53 lua_pushlightuserdata(LS, this);
54 lua_pushvalue(LS, -2);
55 lua_rawset(LS, LUA_REGISTRYINDEX);
56 state = LS;
57 obj = _object;
59 ~lua_obj_pin()
61 lua_pushlightuserdata(state, this);
62 lua_pushnil(state);
63 lua_rawset(state, LUA_REGISTRYINDEX);
65 T* object() { return obj; }
66 private:
67 T* obj;
68 lua_State* state;
69 lua_obj_pin(const lua_obj_pin&);
70 lua_obj_pin& operator=(const lua_obj_pin&);
73 template<class T> struct lua_class_bind_data
75 int (T::*fn)(lua_State* LS);
78 template<class T> class lua_class;
80 template<class T> lua_class<T>& objclass();
82 template<class T> class lua_class
84 public:
85 lua_class(const std::string& _name)
87 name = _name;
90 template<typename... U> T* _create(lua_State* LS, U... args)
92 void* obj = lua_newuserdata(LS, sizeof(T));
93 load_metatable(LS);
94 lua_setmetatable(LS, -2);
95 T* _obj = reinterpret_cast<T*>(obj);
96 new(_obj) T(args...);
97 return _obj;
100 template<typename... U> static T* create(lua_State* LS, U... args)
102 return objclass<T>()._create(LS, args...);
105 void bind(lua_State* LS)
107 load_metatable(LS);
108 lua_pushvalue(LS, -3);
109 lua_pushvalue(LS, -3);
110 lua_rawset(LS, -3);
111 lua_pop(LS, 1);
114 void bind(lua_State* LS, const char* keyname)
116 load_metatable(LS);
117 lua_pushstring(LS, keyname);
118 lua_pushvalue(LS, -3);
119 lua_rawset(LS, -3);
120 lua_pop(LS, 1);
123 static int class_bind_trampoline(lua_State* LS)
125 lua_class_bind_data<T>* b = (lua_class_bind_data<T>*)lua_touserdata(LS, lua_upvalueindex(1));
126 const char* fname = lua_tostring(LS, lua_upvalueindex(2));
127 T* p = lua_class<T>::get(LS, 1, fname);
128 return (p->*(b->fn))(LS);
131 void bind(lua_State* LS, const char* keyname, int (T::*fn)(lua_State* LS), bool force = false)
133 load_metatable(LS);
134 lua_pushstring(LS, keyname);
135 lua_rawget(LS, -2);
136 if(!lua_isnil(LS, -1) && !force) {
137 lua_pop(LS, 2);
138 return;
140 lua_pop(LS, 1);
141 lua_class_bind_data<T>* bdata = new lua_class_bind_data<T>;
142 bdata->fn = fn;
143 lua_pushstring(LS, keyname);
144 lua_pushlightuserdata(LS, bdata);
145 std::string name = std::string("Method ") + keyname;
146 lua_pushstring(LS, name.c_str());
147 lua_pushcclosure(LS, class_bind_trampoline, 2);
148 lua_rawset(LS, -3);
149 lua_pop(LS, 1);
152 T* _get(lua_State* LS, int arg, const char* fname, bool optional = false)
154 if(lua_type(LS, arg) == LUA_TNONE || lua_type(LS, arg) == LUA_TNIL) {
155 if(optional)
156 return NULL;
157 else
158 goto badtype;
160 load_metatable(LS);
161 if(!lua_getmetatable(LS, arg)) {
162 goto badtype;
164 if(!lua_rawequal(LS, -1, -2)) {
165 goto badtype;
167 lua_pop(LS, 2);
168 return reinterpret_cast<T*>(lua_touserdata(LS, arg));
169 badtype:
170 char buffer[2048];
171 sprintf(buffer, "argument #%i to %s must be %s", arg, fname, name.c_str());
172 lua_pushstring(LS, buffer);
173 lua_error(LS);
176 static T* get(lua_State* LS, int arg, const char* fname, bool optional = false)
178 return objclass<T>()._get(LS, arg, fname, optional);
181 bool _is(lua_State* LS, int arg)
183 if(lua_type(LS, arg) != LUA_TUSERDATA)
184 return false;
185 load_metatable(LS);
186 if(!lua_getmetatable(LS, arg)) {
187 lua_pop(LS, 1);
188 return false;
190 bool ret = lua_rawequal(LS, -1, -2);
191 lua_pop(LS, 2);
192 return ret;
195 static bool is(lua_State* LS, int arg)
197 return objclass<T>()._is(LS, arg);
200 lua_obj_pin<T>* _pin(lua_State* LS, int arg, const char* fname)
202 T* obj = get(LS, arg, fname);
203 lua_pushvalue(LS, arg);
204 return new lua_obj_pin<T>(LS, obj);
207 static lua_obj_pin<T>* pin(lua_State* LS, int arg, const char* fname)
209 return objclass<T>()._pin(LS, arg, fname);
211 private:
212 static int dogc(lua_State* LS)
214 T* obj = reinterpret_cast<T*>(lua_touserdata(LS, 1));
215 obj->~T();
218 static int newindex(lua_State* LS)
220 lua_pushstring(LS, "Writing metatables of classes is not allowed");
221 lua_error(LS);
224 static int index(lua_State* LS)
226 lua_getmetatable(LS, 1);
227 lua_pushvalue(LS, 2);
228 lua_rawget(LS, -2);
229 return 1;
232 void load_metatable(lua_State* LS)
234 again:
235 lua_pushlightuserdata(LS, this);
236 lua_rawget(LS, LUA_REGISTRYINDEX);
237 if(lua_type(LS, -1) == LUA_TNIL) {
238 lua_pop(LS, 1);
239 lua_pushlightuserdata(LS, this);
240 lua_newtable(LS);
241 lua_pushvalue(LS, -1);
242 lua_setmetatable(LS, -2);
243 lua_pushstring(LS, "__gc");
244 lua_pushcfunction(LS, &lua_class<T>::dogc);
245 lua_rawset(LS, -3);
246 lua_pushstring(LS, "__newindex");
247 lua_pushcfunction(LS, &lua_class<T>::newindex);
248 lua_rawset(LS, -3);
249 lua_pushstring(LS, "__index");
250 lua_pushcfunction(LS, &lua_class<T>::index);
251 lua_rawset(LS, -3);
252 lua_rawset(LS, LUA_REGISTRYINDEX);
253 goto again;
256 std::string name;
257 lua_class(const lua_class<T>&);
258 lua_class& operator=(const lua_class<T>&);
261 #define DECLARE_LUACLASS(x, X) template<> lua_class< x >& objclass() { static lua_class< x > clazz( X ); \
262 return clazz; }
266 #endif