1 #ifndef _library__luabase__hpp__included__
2 #define _library__luabase__hpp__included__
9 #include <unordered_map>
22 struct luaclass_methods
24 bool (*is
)(lua_state
& state
, int index
);
25 const std::string
& (*name
)();
26 std::string (*print
)(lua_state
& state
, int index
);
29 std::list
<luaclass_methods
>& userdata_recogn_fns();
30 std::string
try_recognize_userdata(lua_state
& state
, int index
);
31 std::string
try_print_userdata(lua_state
& state
, int index
);
35 std::unordered_map
<std::type_index
, void*>& lua_class_types();
40 class lua_function_group
50 ~lua_function_group();
52 * Add a function to group.
54 void do_register(const std::string
& name
, lua_function
& fun
);
56 * Drop a function from group.
58 void do_unregister(const std::string
& name
);
60 * Request callbacks on all currently registered functions.
62 void request_callback(std::function
<void(std::string
, lua_function
*)> cb
);
66 * Callbacks for all registered functions are immediately called.
68 int add_callback(std::function
<void(std::string
, lua_function
*)> cb
,
69 std::function
<void(lua_function_group
*)> dcb
);
73 void drop_callback(int handle
);
76 std::map
<std::string
, lua_function
*> functions
;
77 std::map
<int, std::function
<void(std::string
, lua_function
*)>> callbacks
;
78 std::map
<int, std::function
<void(lua_function_group
*)>> dcallbacks
;
87 //Auxillary type for store-tag.
88 template<typename T
> struct _store_tag
92 _store_tag(T
& a
, T v
) : addr(a
), val(v
) {}
94 //Auxillary type for vararg-tag.
97 std::list
<std::string
> args
;
98 vararg_tag(std::list
<std::string
>& _args
) : args(_args
) {}
99 int pushargs(lua_state
& L
);
102 //Auxillary type for numeric-tag.
103 template<typename T
> struct _numeric_tag
106 _numeric_tag(T v
) : val(v
) {}
109 //Auxillary type for fnptr-tag.
110 template<typename T
> struct _fnptr_tag
112 int(*fn
)(lua_state
& L
, T v
);
114 _fnptr_tag(int (*f
)(lua_state
& L
, T v
), T v
) : fn(f
), val(v
) {}
117 //Auxillary type for fn-tag.
118 template<typename T
> struct _fn_tag
121 _fn_tag(T f
) : fn(f
) {}
125 * Callback parameter: Don't pass any real parameter, but instead store specified value in specified
128 * Parameter a: The location to store value to.
129 * Parameter v: The value to store.
130 * Returns: The parameter structure.
132 template<typename T
> static struct _store_tag
<T
> store_tag(T
& a
, T v
) { return _store_tag
<T
>(a
, v
); }
134 * Callback parameter: Pass numeric value.
136 * Parameter v: The value to pass.
137 * Returns: The parameter structure.
139 template<typename T
> static struct _numeric_tag
<T
> numeric_tag(T v
) { return _numeric_tag
<T
>(v
); }
142 * Callback parameter: Execute function to push more parameters.
144 * Parameter f: The function to execute. The return value is number of additional parameters pushed.
145 * Parameter v: The value to pass to function.
146 * Returns: The parameter structure.
148 template<typename T
> static struct _fnptr_tag
<T
> fnptr_tag(int (*f
)(lua_state
& L
, T v
), T v
)
150 return _fnptr_tag
<T
>(f
, v
);
154 * Callback parameter: Execute function to push more parameters.
156 * Parameter v: The functor to execute. Passed reference to the Lua state. The return value is number of
157 * additional parameters pushed.
158 * Returns: The parameter structure.
160 template<typename T
> static struct _fn_tag
<T
> fn_tag(T v
) { return _fn_tag
<T
>(v
); }
163 * Callback parameter: Pass boolean argument.
165 * Parameter v: The boolean value to pass.
167 struct boolean_tag
{ bool val
; boolean_tag(bool v
) : val(v
) {}};
170 * Callback parameter: Pass string argument.
172 * Parameter v: The string value to pass.
174 struct string_tag
{ std::string val
; string_tag(const std::string
& v
) : val(v
) {}};
177 * Callback parameter: Pass nil argument.
179 struct nil_tag
{ nil_tag() {}};
181 template<typename U
, typename
... T
> void _callback(int argc
, _store_tag
<U
> tag
, T
... args
)
184 _callback(argc
, args
...);
188 template<typename
... T
> void _callback(int argc
, vararg_tag tag
, T
... args
)
190 int e
= tag
.pushargs(*this);
191 _callback(argc
+ e
, args
...);
194 template<typename
... T
> void _callback(int argc
, nil_tag tag
, T
... args
)
197 _callback(argc
+ 1, args
...);
200 template<typename
... T
> void _callback(int argc
, boolean_tag tag
, T
... args
)
202 pushboolean(tag
.val
);
203 _callback(argc
+ 1, args
...);
206 template<typename
... T
> void _callback(int argc
, string_tag tag
, T
... args
)
208 pushlstring(tag
.val
.c_str(), tag
.val
.length());
209 _callback(argc
+ 1, args
...);
212 template<typename U
, typename
... T
> void _callback(int argc
, _numeric_tag
<U
> tag
, T
... args
)
215 _callback(argc
+ 1, args
...);
218 template<typename U
, typename
... T
> void _callback(int argc
, _fnptr_tag
<U
> tag
, T
... args
)
220 int extra
= tag
.fn(*this, tag
.val
);
221 _callback(argc
+ extra
, args
...);
224 template<typename U
, typename
... T
> void _callback(int argc
, _fn_tag
<U
> tag
, T
... args
)
226 int extra
= tag
.fn(*this);
227 _callback(argc
+ extra
, args
...);
230 void _callback(int argc
)
232 int r
= pcall(argc
, 0, 0);
233 if(r
== LUA_ERRRUN
) {
234 (stringfmt() << "Error running Lua callback: " << tostring(-1)).throwex();
237 if(r
== LUA_ERRMEM
) {
238 (stringfmt() << "Error running Lua callback: Out of memory").throwex();
241 if(r
== LUA_ERRERR
) {
242 (stringfmt() << "Error running Lua callback: Double Fault???").throwex();
248 * Create a new state.
250 lua_state() throw(std::bad_alloc
);
252 * Create a new state with specified master state.
254 lua_state(lua_state
& _master
, lua_State
* L
);
258 ~lua_state() throw();
260 * Get the internal state object.
262 * Return value: Internal state.
264 lua_State
* handle() { return lua_handle
; }
266 * Get the master state.
268 lua_state
& get_master() { return master
? master
->get_master() : *this; }
270 * Set the internal state object.
272 void handle(lua_State
* l
) { lua_handle
= l
; }
276 void set_oom_handler(void (*oom
)()) { oom_handler
= oom
? oom
: builtin_oom
; }
280 void reset() throw(std::runtime_error
, std::bad_alloc
);
284 void deinit() throw();
286 * Get a string argument.
288 * Parameter argindex: The stack index.
289 * Parameter fname: The name of function to use in error messages.
290 * Returns: The string.
291 * Throws std::runtime_error: The specified argument is not a string.
293 std::string
get_string(int argindex
, const std::string
& fname
) throw(std::runtime_error
, std::bad_alloc
)
295 if(lua_isnone(lua_handle
, argindex
))
296 (stringfmt() << "argument #" << argindex
<< " to " << fname
<< " must be string").throwex();
298 const char* f
= lua_tolstring(lua_handle
, argindex
, &len
);
300 (stringfmt() << "argument #" << argindex
<< " to " << fname
<< " must be string").throwex();
301 return std::string(f
, f
+ len
);
304 * Get a boolean argument.
306 * Parameter argindex: The stack index.
307 * Parameter fname: The name of function to use in error messages.
308 * Returns: The string.
309 * Throws std::runtime_error: The specified argument is not a boolean.
311 bool get_bool(int argindex
, const std::string
& fname
) throw(std::runtime_error
, std::bad_alloc
)
313 if(lua_isnone(lua_handle
, argindex
) || !lua_isboolean(lua_handle
, argindex
))
314 (stringfmt() << "argument #" << argindex
<< " to " << fname
<< " must be boolean").throwex();
315 return (lua_toboolean(lua_handle
, argindex
) != 0);
318 * Get a mandatory numeric argument.
320 * Parameter argindex: The stack index.
321 * Parameter fname: The name of function to use in error messages.
322 * Returns: The parsed number.
323 * Throws std::runtime_error: Bad type.
326 T
get_numeric_argument(int argindex
, const std::string
& fname
)
328 if(lua_isnone(lua_handle
, argindex
) || !lua_isnumber(lua_handle
, argindex
))
329 (stringfmt() << "Argument #" << argindex
<< " to " << fname
<< " must be numeric").throwex();
330 return static_cast<T
>(lua_tonumber(lua_handle
, argindex
));
333 * Get a optional numeric argument.
335 * Parameter argindex: The stack index.
336 * Parameter value: The place to store the value.
337 * Parameter fname: The name of function to use in error messages.
338 * Throws std::runtime_error: Bad type.
341 void get_numeric_argument(unsigned argindex
, T
& value
, const std::string
& fname
)
343 if(lua_isnoneornil(lua_handle
, argindex
))
345 if(lua_isnone(lua_handle
, argindex
) || !lua_isnumber(lua_handle
, argindex
))
346 (stringfmt() << "Argument #" << argindex
<< " to " << fname
<< " must be numeric if "
347 "present").throwex();
348 value
= static_cast<T
>(lua_tonumber(lua_handle
, argindex
));
353 * Parameter name: The name of the callback.
354 * Parameter args: Arguments to pass to the callback.
356 template<typename
... T
>
357 bool callback(const std::string
& name
, T
... args
)
359 getglobal(name
.c_str());
361 if(t
!= LUA_TFUNCTION
) {
365 _callback(0, args
...);
371 * Parameter cblist: List of environment keys to do callbacks.
372 * Parameter args: Arguments to pass to the callback.
374 template<typename
... T
>
375 bool callback(const std::list
<char>& cblist
, T
... args
)
378 for(auto& i
: cblist
) {
379 pushlightuserdata(const_cast<char*>(&i
));
380 rawget(LUA_REGISTRYINDEX
);
382 if(t
!= LUA_TFUNCTION
) {
385 _callback(0, args
...);
392 * Add a group of functions.
394 void add_function_group(lua_function_group
& group
);
398 void function_callback(const std::string
& name
, lua_function
* func
);
400 * Do something just once per VM.
402 * Parameter key: The do-once key value.
403 * Returns: True if called the first time for given key on given VM, false otherwise.
405 bool do_once(void* key
);
409 class lua_callback_list
412 lua_callback_list(lua_state
& L
, const std::string
& name
, const std::string
& fn_cbname
= "");
413 ~lua_callback_list();
414 void _register(lua_state
& L
); //Reads callback from top of lua stack.
415 void _unregister(lua_state
& L
); //Reads callback from top of lua stack.
416 template<typename
... T
> bool callback(T
... args
) {
417 bool any
= L
.callback(callbacks
, args
...);
418 if(fn_cbname
!= "" && L
.callback(fn_cbname
, args
...))
422 const std::string
& get_name() { return name
; }
423 void clear() { callbacks
.clear(); }
425 lua_callback_list(const lua_callback_list
&);
426 lua_callback_list
& operator=(const lua_callback_list
&);
427 std::list
<char> callbacks
;
430 std::string fn_cbname
;
433 * Enumerate all callbacks.
435 std::list
<lua_callback_list
*> get_callbacks()
438 return master
->get_callbacks();
439 std::list
<lua_callback_list
*> r
;
440 for(auto i
: callbacks
)
441 r
.push_back(i
.second
);
445 * Register a callback.
450 callback_proxy(lua_state
& _L
) : parent(_L
) {}
451 void do_register(const std::string
& name
, lua_callback_list
& callback
)
453 parent
.do_register_cb(name
, callback
);
456 * Unregister a callback.
458 void do_unregister(const std::string
& name
)
460 parent
.do_unregister_cb(name
);
466 void do_register_cb(const std::string
& name
, lua_callback_list
& callback
)
468 callbacks
[name
] = &callback
;
471 void do_unregister_cb(const std::string
& name
)
473 callbacks
.erase(name
);
476 //All kinds of Lua API functions.
477 void pop(int n
) { lua_pop(lua_handle
, n
); }
478 void* newuserdata(size_t size
) { return lua_newuserdata(lua_handle
, size
); }
479 int setmetatable(int index
) { return lua_setmetatable(lua_handle
, index
); }
480 int type(int index
) { return lua_type(lua_handle
, index
); }
481 int getmetatable(int index
) { return lua_getmetatable(lua_handle
, index
); }
482 int rawequal(int index1
, int index2
) { return lua_rawequal(lua_handle
, index1
, index2
); }
483 void* touserdata(int index
) { return lua_touserdata(lua_handle
, index
); }
484 const void* topointer(int index
) { return lua_topointer(lua_handle
, index
); }
485 int gettop() { return lua_gettop(lua_handle
); }
486 void pushvalue(int index
) { lua_pushvalue(lua_handle
, index
); }
487 void pushlightuserdata(void* p
) { lua_pushlightuserdata(lua_handle
, p
); }
488 void rawset(int index
) { lua_rawset(lua_handle
, index
); }
489 void pushnil() { lua_pushnil(lua_handle
); }
490 void pushstring(const char* s
) { lua_pushstring(lua_handle
, s
); }
491 void rawget(int index
) { lua_rawget(lua_handle
, index
); }
492 int isnil(int index
) { return lua_isnil(lua_handle
, index
); }
493 void newtable() { lua_newtable(lua_handle
); }
494 void pushcclosure(lua_CFunction fn
, int n
) { lua_pushcclosure(lua_handle
, fn
, n
); }
495 void pushcfunction(lua_CFunction fn
) { lua_pushcfunction(lua_handle
, fn
); }
496 void setfield(int index
, const char* k
) { lua_setfield(lua_handle
, index
, k
); }
497 void getfield(int index
, const char* k
) { lua_getfield(lua_handle
, index
, k
); }
498 void getglobal(const char* name
) { lua_getglobal(lua_handle
, name
); }
499 void setglobal(const char* name
) { lua_setglobal(lua_handle
, name
); }
500 void insert(int index
) { lua_insert(lua_handle
, index
); }
501 void settable(int index
) { lua_settable(lua_handle
, index
); }
502 int isnone(int index
) { return lua_isnone(lua_handle
, index
); }
503 void pushnumber(lua_Number n
) { return lua_pushnumber(lua_handle
, n
); }
504 int isnumber(int index
) { return lua_isnumber(lua_handle
, index
); }
505 int isboolean(int index
) { return lua_isboolean(lua_handle
, index
); }
506 int toboolean(int index
) { return lua_toboolean(lua_handle
, index
); }
507 const char* tolstring(int index
, size_t *len
) { return lua_tolstring(lua_handle
, index
, len
); }
508 void pushboolean(int b
) { lua_pushboolean(lua_handle
, b
); }
509 lua_Number
tonumber(int index
) { return lua_tonumber(lua_handle
, index
); }
510 void gettable(int index
) { lua_gettable(lua_handle
, index
); }
511 #if LUA_VERSION_NUM == 501
512 int load(lua_Reader reader
, void* data
, const char* chunkname
) { return lua_load(lua_handle
, reader
, data
,
515 #if LUA_VERSION_NUM == 502
516 int load(lua_Reader reader
, void* data
, const char* chunkname
, const char* mode
) { return lua_load(lua_handle
,
517 reader
, data
, chunkname
, mode
); }
519 const char* tostring(int index
) { return lua_tostring(lua_handle
, index
); }
520 const char* tolstring(int index
, size_t& len
) { return lua_tolstring(lua_handle
, index
, &len
); }
521 void pushlstring(const char* s
, size_t len
) { lua_pushlstring(lua_handle
, s
, len
); }
522 void pushlstring(const std::string
& s
) { lua_pushlstring(lua_handle
, s
.c_str(), s
.length()); }
523 void pushlstring(const char32_t
* s
, size_t len
) { pushlstring(to_u8string(std::u32string(s
, len
))); }
524 int pcall(int nargs
, int nresults
, int errfunc
) { return lua_pcall(lua_handle
, nargs
, nresults
, errfunc
); }
525 int next(int index
) { return lua_next(lua_handle
, index
); }
526 int isnoneornil(int index
) { return lua_isnoneornil(lua_handle
, index
); }
527 lua_Integer
tointeger(int index
) { return lua_tointeger(lua_handle
, index
); }
528 void rawgeti(int index
, int n
) { lua_rawgeti(lua_handle
, index
, n
); }
529 callback_proxy cbproxy
;
531 static void builtin_oom();
532 static void* builtin_alloc(void* user
, void* old
, size_t olds
, size_t news
);
533 void (*oom_handler
)();
535 lua_State
* lua_handle
;
536 std::set
<std::pair
<lua_function_group
*, int>> function_groups
;
537 std::map
<std::string
, lua_callback_list
*> callbacks
;
538 lua_state(lua_state
&);
539 lua_state
& operator=(lua_state
&);
543 * Pin of an object against Lua GC.
545 template<typename T
> struct lua_obj_pin
558 * Parameter _state: The state to pin the object in.
559 * Parameter _object: The object to pin.
561 lua_obj_pin(lua_state
& _state
, T
* _object
)
562 : state(&_state
.get_master())
564 _state
.pushlightuserdata(this);
565 _state
.pushvalue(-2);
566 _state
.rawset(LUA_REGISTRYINDEX
);
572 ~lua_obj_pin() throw()
575 state
->pushlightuserdata(this);
577 state
->rawset(LUA_REGISTRYINDEX
);
583 lua_obj_pin(const lua_obj_pin
& p
)
588 state
->pushlightuserdata(this);
589 state
->pushlightuserdata(const_cast<lua_obj_pin
*>(&p
));
590 state
->rawget(LUA_REGISTRYINDEX
);
591 state
->rawset(LUA_REGISTRYINDEX
);
595 * Assignment operator.
597 lua_obj_pin
& operator=(const lua_obj_pin
& p
)
599 if(state
== p
.state
&& obj
== p
.obj
)
602 throw std::logic_error("A Lua object can't be in two lua states at once");
604 state
->pushlightuserdata(this);
606 state
->rawset(LUA_REGISTRYINDEX
);
610 state
->pushlightuserdata(this);
611 state
->pushlightuserdata(const_cast<lua_obj_pin
*>(&p
));
612 state
->rawget(LUA_REGISTRYINDEX
);
613 state
->rawset(LUA_REGISTRYINDEX
);
619 * Clear a pinned object.
624 state
->pushlightuserdata(this);
626 state
->rawset(LUA_REGISTRYINDEX
);
632 * Get pointer to pinned object.
634 * Returns: The pinned object.
636 T
* object() { return obj
; }
640 operator bool() { return obj
!= NULL
; }
644 T
& operator*() { if(obj
) return *obj
; throw std::runtime_error("Attempted to reference NULL Lua pin"); }
645 T
* operator->() { if(obj
) return obj
; throw std::runtime_error("Attempted to reference NULL Lua pin"); }
649 void luapush(lua_state
& state
)
651 state
.pushlightuserdata(this);
652 state
.rawget(LUA_REGISTRYINDEX
);
659 template<typename T
> void* unbox_any_pin(struct lua_obj_pin
<T
>* pin
)
661 return pin
? pin
->object() : NULL
;
665 * Helper class containing binding data for Lua class call.
667 template<class T
> struct lua_class_bind_data
670 * The pointer to call.
672 int (T::*fn
)(lua_state
& state
, const std::string
& _fname
);
674 * The state to call it in.
678 * The name of the method to pass.
683 template<class T
> class lua_class
;
686 * Function to obtain class object for given Lua class.
688 template<class T
> lua_class
<T
>& objclass()
690 return *reinterpret_cast<lua_class
<T
>*>(lua_class_types()[typeid(T
)]);
693 template<class T
> struct lua_class_binding
702 int (T::*fn
)(lua_state
& LS
, const std::string
& fname
);
706 * The type of Lua classes.
708 template<class T
> class lua_class
710 template<typename
... U
> T
* _create(lua_state
& state
, U
... args
)
712 void* obj
= state
.newuserdata(sizeof(T
));
713 load_metatable(state
);
714 state
.setmetatable(-2);
715 T
* _obj
= reinterpret_cast<T
*>(obj
);
716 new(_obj
) T(state
, args
...);
720 static int class_bind_trampoline(lua_State
* LS
)
723 lua_class_bind_data
<T
>* b
= (lua_class_bind_data
<T
>*)lua_touserdata(LS
, lua_upvalueindex(1));
724 lua_state
L(*b
->state
, LS
);
725 T
* p
= lua_class
<T
>::get(L
, 1, b
->fname
);
726 return (p
->*(b
->fn
))(L
, b
->fname
);
727 } catch(std::exception
& e
) {
728 std::string err
= e
.what();
729 lua_pushlstring(LS
, err
.c_str(), err
.length());
734 T
* _get(lua_state
& state
, int arg
, const std::string
& fname
, bool optional
= false)
736 if(state
.type(arg
) == LUA_TNONE
|| state
.type(arg
) == LUA_TNIL
) {
742 load_metatable(state
);
743 if(!state
.getmetatable(arg
))
745 if(!state
.rawequal(-1, -2))
748 return reinterpret_cast<T
*>(state
.touserdata(arg
));
750 (stringfmt() << "argument #" << arg
<< " to " << fname
<< " must be " << name
).throwex();
751 return NULL
; //Never reached.
754 bool _is(lua_state
& state
, int arg
)
756 if(state
.type(arg
) != LUA_TUSERDATA
)
758 load_metatable(state
);
759 if(!state
.getmetatable(arg
)) {
763 bool ret
= state
.rawequal(-1, -2);
768 lua_obj_pin
<T
> _pin(lua_state
& state
, int arg
, const std::string
& fname
)
770 T
* obj
= get(state
, arg
, fname
);
771 state
.pushvalue(arg
);
772 return lua_obj_pin
<T
>(state
, obj
);
776 * Create a new Lua class.
778 * Parameter _name: The name of the class.
780 lua_class(const std::string
& _name
)
784 m
.is
= lua_class
<T
>::is
;
785 m
.name
= lua_class
<T
>::get_name
;
786 m
.print
= lua_class
<T
>::print
;
787 userdata_recogn_fns().push_back(m
);
788 lua_class_types()[typeid(T
)] = this;
792 * Create a new instance of object.
794 * Parameter state: The Lua state to create the object in.
795 * Parameter args: The arguments to pass to class constructor.
797 template<typename
... U
> static T
* create(lua_state
& state
, U
... args
)
799 return objclass
<T
>()._create(state
, args
...);
803 * Bind a method to class.
805 * Parameter state: The state to do the binding in.
806 * Parameter keyname: The name of the method.
807 * Parameter fn: The method to call.
808 * Parameter force: If true, overwrite existing method.
810 void bind(lua_state
& state
, const char* keyname
, int (T::*fn
)(lua_state
& LS
, const std::string
& fname
))
812 load_metatable(state
);
813 state
.pushstring(keyname
);
814 std::string fname
= name
+ std::string("::") + keyname
;
815 void* ptr
= state
.newuserdata(sizeof(lua_class_bind_data
<T
>) + fname
.length() + 1);
816 lua_class_bind_data
<T
>* bdata
= reinterpret_cast<lua_class_bind_data
<T
>*>(ptr
);
818 bdata
->state
= &state
.get_master();
819 std::copy(fname
.begin(), fname
.end(), bdata
->fname
);
820 bdata
->fname
[fname
.length()] = 0;
821 state
.pushcclosure(class_bind_trampoline
, 1);
826 * Bind multiple at once.
828 void bind_multi(lua_state
& state
, std::initializer_list
<lua_class_binding
<T
>> list
, void* doonce_key
= NULL
)
830 static char once_key
;
831 if(state
.do_once(doonce_key
? doonce_key
: &once_key
))
833 bind(state
, i
.name
, i
.fn
);
836 * Get a pointer to the object.
838 * Parameter state: The Lua state.
839 * Parameter arg: Argument index.
840 * Parameter fname: The name of function for error messages.
841 * Parameter optional: If true and argument is NIL or none, return NULL.
842 * Throws std::runtime_error: Wrong type.
844 static T
* get(lua_state
& state
, int arg
, const std::string
& fname
, bool optional
= false)
845 throw(std::bad_alloc
, std::runtime_error
)
847 return objclass
<T
>()._get(state
, arg
, fname
, optional
);
851 * Identify if object is of this type.
853 * Parameter state: The Lua state.
854 * Parameter arg: Argument index.
855 * Returns: True if object is of specified type, false if not.
857 static bool is(lua_state
& state
, int arg
) throw()
859 return objclass
<T
>()._is(state
, arg
);
864 static const std::string
& get_name()
866 return objclass
<T
>().name
;
869 * Format instance of this class as string.
871 static std::string
print(lua_state
& state
, int index
)
873 T
* obj
= get(state
, index
, "__internal_print");
877 * Get a pin of object against Lua GC.
879 * Parameter state: The Lua state.
880 * Parameter arg: Argument index.
881 * Parameter fname: Name of function for error message purposes.
882 * Throws std::runtime_error: Wrong type.
884 static lua_obj_pin
<T
> pin(lua_state
& state
, int arg
, const std::string
& fname
) throw(std::bad_alloc
,
887 return objclass
<T
>()._pin(state
, arg
, fname
);
890 static int dogc(lua_State
* LS
)
892 T
* obj
= reinterpret_cast<T
*>(lua_touserdata(LS
, 1));
897 static int newindex(lua_State
* LS
)
899 lua_pushstring(LS
, "Writing metatables of classes is not allowed");
904 static int index(lua_State
* LS
)
906 lua_getmetatable(LS
, 1);
907 lua_pushvalue(LS
, 2);
912 void load_metatable(lua_state
& state
)
915 state
.pushlightuserdata(this);
916 state
.rawget(LUA_REGISTRYINDEX
);
917 if(state
.type(-1) == LUA_TNIL
) {
919 state
.pushlightuserdata(this);
922 state
.setmetatable(-2);
923 state
.pushstring("__gc");
924 state
.pushcfunction(&lua_class
<T
>::dogc
);
926 state
.pushstring("__newindex");
927 state
.pushcfunction(&lua_class
<T
>::newindex
);
929 state
.pushstring("__index");
930 state
.pushcfunction(&lua_class
<T
>::index
);
932 state
.rawset(LUA_REGISTRYINDEX
);
937 lua_class(const lua_class
<T
>&);
938 lua_class
& operator=(const lua_class
<T
>&);
942 * Function implemented in C++ exported to Lua.
950 lua_function(lua_function_group
& group
, const std::string
& name
) throw(std::bad_alloc
);
952 * Unregister function.
954 virtual ~lua_function() throw();
959 virtual int invoke(lua_state
& L
) = 0;
962 lua_function_group
& group
;
966 * Register function pointer as lua function.
968 class function_ptr_luafun
: public lua_function
974 function_ptr_luafun(lua_function_group
& group
, const std::string
& name
,
975 int (*_fn
)(lua_state
& L
, const std::string
& fname
))
976 : lua_function(group
, name
)
983 int invoke(lua_state
& L
)
988 int (*fn
)(lua_state
& L
, const std::string
& fname
);