Pioneer
Loading...
Searching...
No Matches
LuaMetaType.h
Go to the documentation of this file.
1// Copyright © 2008-2023 Pioneer Developers. See AUTHORS.txt for details
2// Licensed under the terms of the GPL v3. See licenses/GPL-3.txt
3
4#pragma once
5
6#include "Lua.h"
7#include "LuaCall.h"
8#include "LuaManager.h"
9#include "LuaPushPull.h"
10#include "LuaTable.h"
11
12/*
13 * LuaMetaType is a C++ -> Lua binding system intended to drastically
14 * simplify the amount of time and code needed to write often-repetitive
15 * glue code to pull arguments from Lua and pass them to a C++ function,
16 * then push the result back on the Lua stack.
17 *
18 * Usage comes in two flavors based on what you're intending to bind:
19 *
20 * LuaObjects (e.g. classes and structs):
21 *
22 * In the regular LuaObject<T>::RegisterClass method, create a static
23 * LuaMetaType<T> object and call CreateMetaType(lua_State *) on it.
24 * Once done, between any StartRecording() and StopRecording() pair,
25 * chain AddFunction and AddMember calls to build the Lua binding like so:
26 *
27 * > .AddFunction("name", &T::SomeFunc)
28 * > .AddMember("name", &T::someMember)
29 *
30 * Call LuaObjectBase::CreateClass(&metaType) afterwards and you're done.
31 *
32 * Generic "Namespace" bindings (e.g. LuaEngine):
33 *
34 * These are similar to the above, simply create a LuaMetaTypeGeneric
35 * object. Instead of binding c++ member functions however, you can
36 * bind any C++ free function - LuaMetaTypeGeneric doesn't have a concept
37 * of a 'this object' and is intended to simplify binding libraries of
38 * stateless functions to Lua (e.g. ImGui).
39 *
40 * > .AddFunction("NewLine", &ImGui::NewLine)
41 */
42
43// Base class for the LuaMetaType binding system
45public:
46 LuaMetaTypeBase(const char *name) :
47 m_typeName(name)
48 {}
49
50 // Creates and registers the lua-side object for this type.
51 void CreateMetaType(lua_State *l);
52
53 const char *GetTypeName() const { return m_typeName.c_str(); }
54
55 const char *GetParent() const { return m_parent.c_str(); }
56
57 void SetParent(const char *parent) { m_parent = parent; }
58
59 // Push the metatable to the lua stack.
60 void GetMetatable() const;
61
62 // Returns true if the metatype has been correctly set up.
63 bool IsValid() const { return m_lua && m_ref != LUA_NOREF; }
64
65 // Call this function to set the lua stack up to begin recording members
66 // and methods into the metatype.
67 // It is invalid to call other functions outside a StartRecording / StopRecording pair.
69 {
70 assert(IsValid());
71 assert(m_index == 0);
72
74 m_index = lua_gettop(m_lua);
75 }
76
77 // Stop recording and remove the metatype from the stack
79 {
80 assert(IsValid());
81 assert(m_index != 0);
82 lua_remove(m_lua, m_index);
83 m_index = 0;
84 }
85
86 // Get all valid method/attribute names for the object on the top of the stack.
87 // Mainly intended to be used by the console, though it can also be used for
88 // debug dumping of properties, attributes, and methods
89 static void GetNames(std::vector<std::string> &names, const std::string &prefix = "", bool methodsOnly = false);
90
91 // Get the lua-side metatable from a type name instead of a LuaRef.
92 static bool GetMetatableFromName(lua_State *l, const char *name);
93
94 // A replacement for luaL_testudata that is metatype-aware
95 static void *TestUserdata(lua_State *l, int index, const char *name);
96
97 // A replacement for luaL_checkudata that is metatype-aware
98 static void *CheckUserdata(lua_State *l, int index, const char *name);
99
100protected:
101 //=========================================================================
102 // LuaMetaTypeGeneric support:
103 //=========================================================================
104
105 // C++ free functions taking any set of arguments and returning a value or void
106 template <typename Rt, typename... Args>
107 using free_function = Rt (*)(Args...);
108
109 // Overload for free functions returning a value
110 template <typename Rt, typename... Args>
111 typename std::enable_if<!std::is_same<Rt, void>::value, int>::type static free_fn_wrapper_(lua_State *L)
112 {
113 if (size_t(lua_gettop(L)) < sizeof...(Args))
114 return luaL_error(L, "Invalid number of arguments for function %s (have %d, need %lu)",
115 lua_tostring(L, lua_upvalueindex(1)), lua_gettop(L), sizeof...(Args));
116
117 auto fn = PullFreeFunction<free_function<Rt, Args...>>(L, lua_upvalueindex(2));
118 Rt ret = pi_lua_multiple_call(L, 1, fn);
119 LuaPush<Rt>(L, ret);
120
121 return 1;
122 }
123
124 // Overload for functions returning void
125 template <typename Rt, typename... Args>
126 typename std::enable_if<std::is_same<Rt, void>::value, int>::type static free_fn_wrapper_(lua_State *L)
127 {
128 if (size_t(lua_gettop(L)) < sizeof...(Args))
129 return luaL_error(L, "Invalid number of arguments for function %s (have %d, need %lu)",
130 lua_tostring(L, lua_upvalueindex(1)), lua_gettop(L), sizeof...(Args));
131
132 auto fn = PullFreeFunction<free_function<Rt, Args...>>(L, lua_upvalueindex(2));
133 pi_lua_multiple_call(L, 1, fn);
134
135 return 0;
136 }
137
138 //=========================================================================
139 // LuaMetaType<T> support:
140 //=========================================================================
141
142 // Direct member pointer access (for structs, etc.)
143 template <typename T, typename Dt>
144 using member_pointer = Dt T::*;
145
146 template <typename T, typename Dt>
147 static int member_wrapper_(lua_State *L)
148 {
149 T *ptr = LuaPull<T *>(L, 1);
150 const char *name = lua_tostring(L, lua_upvalueindex(1));
151
152 if (!ptr)
153 return luaL_error(L, "Null or invalid userdata accessed for property %s", name);
154
155 if (lua_gettop(L) > 2)
156 return luaL_error(L, "Invalid number of arguments for property getter/setter %s", name);
157
158 auto &t = PullPointerToMember<member_pointer<T, Dt>>(L, lua_upvalueindex(2));
159 if (lua_gettop(L) == 1) {
160 LuaPush<Dt>(L, ptr->*(t));
161 return 1;
162 } else {
163 (ptr->*(t)) = LuaPull<Dt>(L, 2);
164 return 0;
165 }
166 }
167
168 //=========================================================================
169
170 // "Member Free Function" access: like lua_CFunction but with an automatic
171 // this-object pointer passed to the function for simplicity
172 template <typename T>
173 using member_cfunction = int (*)(lua_State *, T *);
174
175 template <typename T>
176 static int member_cfn_wrapper_(lua_State *L)
177 {
178 T *ptr = LuaPull<T *>(L, 1);
179 const char *name = lua_tostring(L, lua_upvalueindex(1));
180 luaL_checktype(L, lua_upvalueindex(2), LUA_TLIGHTUSERDATA);
181
182 if (!ptr)
183 return luaL_error(L, "Invalid userdata accessed for function %s", name);
184
185 auto fn = PullFreeFunction<member_cfunction<T>>(L, lua_upvalueindex(2));
186 return fn(L, ptr);
187 }
188
189 // Bind two member free functions into a getter-setter pair for an attr
190 template <typename T>
191 static int getter_member_cfn_wrapper_(lua_State *L)
192 {
193 T *ptr = LuaPull<T *>(L, 1);
194 const char *name = lua_tostring(L, lua_upvalueindex(1));
195 auto getter = PullFreeFunction<member_cfunction<T>>(L, lua_upvalueindex(2));
196
197 if (!ptr)
198 return luaL_error(L, "Null or invalid userdata accessed for property %s", name);
199
200 if (lua_gettop(L) > 2)
201 return luaL_error(L, "Invalid number of arguments for property getter/setter %s", name);
202
203 if (lua_gettop(L) > 1) {
204 auto setter = PullFreeFunction<member_cfunction<T>>(L, lua_upvalueindex(3));
205 if (setter != nullptr)
206 return setter(L, ptr);
207 else
208 return luaL_error(L, "Attempt to call undefined setter for property %s", name);
209 }
210
211 return getter(L, ptr);
212 }
213
214 //=========================================================================
215
216 // C++ member function pointer access: using template magic, this assembles
217 // all of the bridge code needed to pull values from Lua and pass the return value back
218 template <typename T, typename Rt, typename... Args>
219 using member_function = Rt (T::*)(Args...);
220
221 template <typename T, typename Rt, typename... Args>
222 using const_member_function = Rt (T::*)(Args...) const;
223
224 // Overload for function returning a value
225 template <typename T, typename Rt, typename... Args>
226 typename std::enable_if<!std::is_same<Rt, void>::value, int>::type static member_fn_wrapper_(lua_State *L)
227 {
228 T *ptr = LuaPull<T *>(L, 1);
229 const char *name = lua_tostring(L, lua_upvalueindex(1));
230
231 if (!ptr)
232 return luaL_error(L, "Invalid userdata accessed for function %s", name);
233
234 if (size_t(lua_gettop(L) - 1) < sizeof...(Args))
235 return luaL_error(L, "Invalid number of arguments for function %s", name);
236
237 auto &fn = PullPointerToMember<member_function<T, Rt, Args...>>(L, lua_upvalueindex(2));
238 Rt ret = pi_lua_multiple_call(L, 1, ptr, fn);
239 LuaPush<Rt>(L, ret);
240
241 return 1;
242 }
243
244 // Overload for function returning void
245 template <typename T, typename Rt, typename... Args>
246 typename std::enable_if<std::is_same<Rt, void>::value, int>::type static member_fn_wrapper_(lua_State *L)
247 {
248 T *ptr = LuaPull<T *>(L, 1);
249 const char *name = lua_tostring(L, lua_upvalueindex(1));
250
251 if (!ptr)
252 return luaL_error(L, "Invalid userdata accessed for function %s", name);
253
254 if (size_t(lua_gettop(L) - 1) < sizeof...(Args))
255 return luaL_error(L, "Invalid number of arguments for function %s", name);
256
257 auto &fn = PullPointerToMember<member_function<T, Rt, Args...>>(L, lua_upvalueindex(2));
258 pi_lua_multiple_call(L, 1, ptr, fn);
259
260 return 0;
261 }
262
263 // T::GetName / T::SetName glue code to wrap into a single attr function
264 template <typename T, typename Dt, typename Dt2>
265 static int getter_member_fn_wrapper_(lua_State *L)
266 {
267 T *ptr = LuaPull<T *>(L, 1);
268 const char *name = lua_tostring(L, lua_upvalueindex(1));
269 auto &getter = PullPointerToMember<member_function<T, Dt>>(L, lua_upvalueindex(2));
270
271 if (!ptr)
272 return luaL_error(L, "Null or invalid userdata accessed for property %s", name);
273
274 if (lua_gettop(L) > 2)
275 return luaL_error(L, "Invalid number of arguments for property getter/setter %s", name);
276
277 if (lua_gettop(L) > 1) {
278 auto &setter = PullPointerToMember<member_function<T, void, Dt2>>(L, lua_upvalueindex(3));
279 if (setter != nullptr) {
280 pi_lua_multiple_call(L, 1, ptr, setter);
281 return 0;
282 } else
283 return luaL_error(L, "Attempt to call undefined setter for property %s", name);
284 } else {
285 Dt value = pi_lua_multiple_call(L, 1, ptr, getter);
286 LuaPush<Dt>(L, value);
287 return 1;
288 }
289 }
290
291 //=========================================================================
292 // Generic support for getting function pointers in and out of lua:
293 //=========================================================================
294
295 template <typename MemT>
296 static void PushPointerToMember(lua_State *L, MemT obj)
297 {
298 *reinterpret_cast<MemT *>(lua_newuserdata(L, sizeof(MemT))) = obj;
299 }
300
301 template <typename MemT>
302 static MemT &PullPointerToMember(lua_State *L, int idx)
303 {
304 return *reinterpret_cast<MemT *>(lua_touserdata(L, idx));
305 }
306
307 template <typename T>
308 static void PushFreeFunction(lua_State *L, T obj)
309 {
310 static_assert(sizeof(T) == sizeof(void *), "Free functions cannot be 'fat' lambdas!");
311 lua_pushlightuserdata(L, reinterpret_cast<void *>(obj));
312 }
313
314 template <typename T>
315 static T PullFreeFunction(lua_State *L, int index)
316 {
317 return reinterpret_cast<T>(lua_touserdata(L, index));
318 }
319
320 // Pushes a copy of the metatable's attribute table to the stack
321 void GetAttrTable(lua_State *L, int index)
322 {
323 luaL_getsubtable(L, index, "attrs");
324 }
325
326 // Pushes a copy of the metatable's attribute table to the stack
327 void GetMethodTable(lua_State *L, int index)
328 {
329 luaL_getsubtable(L, index, "methods");
330 }
331
332 std::string m_typeName;
333 std::string m_parent;
334
335 lua_State *m_lua;
336 // the reference id of the metatable
337 int m_ref = LUA_NOREF;
338 // the position of the metatable on the stack while recording
339 int m_index = 0;
340};
341
343public:
345
346 LuaMetaTypeGeneric(const char *name) :
347 LuaMetaTypeBase(name)
348 {}
349
351 {
353 return *this;
354 }
355
357 {
359 return *this;
360 }
361
362 Self &SetProtected(bool enabled)
363 {
364 m_protected = enabled;
365 return *this;
366 }
367
368 Self &AddMember(const char *name, lua_CFunction getter)
369 {
371
372 lua_pushcfunction(m_lua, getter);
373 if (m_protected)
374 lua_pushcclosure(m_lua, secure_trampoline, 1);
375
376 lua_setfield(m_lua, -2, name);
377 lua_pop(m_lua, 1);
378 return *this;
379 }
380
381 Self &AddFunction(const char *name, lua_CFunction func)
382 {
384
385 lua_pushcfunction(m_lua, func);
386 if (m_protected)
387 lua_pushcclosure(m_lua, secure_trampoline, 1);
388
389 lua_setfield(m_lua, -2, name);
390 lua_pop(m_lua, 1);
391 return *this;
392 }
393
394 template <typename Rt, typename... Args>
396 {
398
399 lua_pushstring(m_lua, (m_typeName + "." + name).c_str());
400 PushFreeFunction(m_lua, func);
401 lua_pushcclosure(m_lua, &free_fn_wrapper_<Rt, Args...>, 2);
402 if (m_protected)
403 lua_pushcclosure(m_lua, &secure_trampoline, 1);
404
405 lua_setfield(m_lua, -2, name);
406 lua_pop(m_lua, 1);
407 return *this;
408 }
409
410 Self &AddMeta(const char *name, lua_CFunction func)
411 {
412 lua_pushcfunction(m_lua, func);
413 if (m_protected)
414 lua_pushcclosure(m_lua, secure_trampoline, 1);
415
416 lua_setfield(m_lua, m_index, name);
417
418 return *this;
419 }
420
421 template <typename Rt, typename... Args>
422 Self &AddMeta(const char *name, free_function<Rt, Args...> func)
423 {
424 lua_pushstring(m_lua, (m_typeName + "." + name).c_str());
425 PushFreeFunction(m_lua, func);
426 lua_pushcclosure(m_lua, &free_fn_wrapper_<Rt, Args...>, 2);
427 if (m_protected)
428 lua_pushcclosure(m_lua, &secure_trampoline, 1);
429
430 lua_setfield(m_lua, m_index, name);
431
432 return *this;
433 }
434
435 Self &AddCallCtor(lua_CFunction func)
436 {
438 lua_getmetatable(m_lua, -1);
439
440 lua_pushcfunction(m_lua, func);
441 if (m_protected)
442 lua_pushcclosure(m_lua, secure_trampoline, 1);
443
444 lua_setfield(m_lua, -2, "__call");
445 lua_pop(m_lua, 2);
446
447 return *this;
448 }
449
450 Self &AddNewCtor(lua_CFunction func)
451 {
453
454 lua_pushcfunction(m_lua, func);
455 if (m_protected)
456 lua_pushcclosure(m_lua, secure_trampoline, 1);
457
458 lua_setfield(m_lua, -2, "New");
459 lua_pop(m_lua, 1);
460 return *this;
461 }
462
463private:
464 bool m_protected = false;
465};
466
467template <typename T>
469public:
471
472 LuaMetaType(const char *name) :
473 LuaMetaTypeBase(name)
474 {}
475
477 {
479 return *this;
480 }
481
483 {
485 return *this;
486 }
487
488 // All functions and members pushed while protection is enabled will error
489 // when accessed by a non-trusted lua script.
490 void SetProtected(bool enabled) { m_protected = enabled; }
491
492 // Bind a raw C++ data member to Lua.
493 // Obviously, the member in question must be publically accessible, or
494 // LuaMetaTypeBase must be marked as a friend class.
495 template <typename Dt>
497 {
498 lua_State *L = m_lua;
500
501 lua_pushstring(L, (m_typeName + "." + name).c_str());
503 lua_pushcclosure(L, &member_wrapper_<T, Dt>, 2);
504 if (m_protected)
505 lua_pushcclosure(L, &secure_trampoline, 1);
506
507 lua_setfield(L, -2, name);
508 lua_pop(L, 1);
509
510 return *this;
511 }
512
513 // Bind a pseudo-member to Lua via a free-function getter and setter.
514 // The getter and setter are responsible for pulling parameters from Lua.
515 Self &AddMember(const char *name, member_cfunction<T> getter, member_cfunction<T> setter = nullptr)
516 {
517 lua_State *L = m_lua;
519
520 lua_pushstring(L, (m_typeName + "." + name).c_str());
521 PushFreeFunction(L, getter);
522 PushFreeFunction(L, setter);
523 lua_pushcclosure(L, &getter_member_cfn_wrapper_<T>, 3);
524 if (m_protected)
525 lua_pushcclosure(L, &secure_trampoline, 1);
526
527 lua_setfield(L, -2, name);
528 lua_pop(L, 1);
529
530 return *this;
531 }
532
533 // Magic to allow binding a const function to Lua. Take care to ensure that you do not
534 // push a const object to lua, or this code will become undefined behavior.
535 template <typename Dt, typename Dt2 = Dt>
537 {
538 return AddMember(name, reinterpret_cast<member_function<T, Dt>>(getter), setter);
539 }
540
541 // Bind a pseudo-member to Lua via a member-function getter and setter.
542 // The parameter will automatically be pulled from Lua and passed to the setter.
543 template <typename Dt, typename Dt2 = Dt>
544 Self &AddMember(const char *name, member_function<T, Dt> getter, member_function<T, void, Dt2> setter = nullptr)
545 {
546 lua_State *L = m_lua;
548
549 lua_pushstring(L, (m_typeName + "." + name).c_str());
550 PushPointerToMember(L, getter);
551 PushPointerToMember(L, setter);
552 lua_pushcclosure(L, &getter_member_fn_wrapper_<T, Dt, Dt2>, 3);
553 if (m_protected)
554 lua_pushcclosure(L, &secure_trampoline, 1);
555
556 lua_setfield(L, -2, name);
557 lua_pop(L, 1);
558
559 return *this;
560 }
561
562 // Magic to allow binding a const function to Lua. Take care to ensure that you do not
563 // push a const object to lua, or this code will become undefined behavior.
564 template <typename Rt, typename... Args>
566 {
567 return AddFunction(name, reinterpret_cast<member_function<T, Rt, Args...>>(fn));
568 }
569
570 // Bind a member function to Lua.
571 // Parameters will automatically be pulled from Lua and be passed to the function.
572 // It is the responsiblity of the programmer to ensure a valid LuaPull implementation
573 // is available for each parameter's time.
574 // If the function has a non-void return type, its return value will automatically be
575 // pushed to Lua.
576 template <typename Rt, typename... Args>
578 {
579 lua_State *L = m_lua;
581
582 lua_pushstring(L, (m_typeName + "." + name).c_str());
583 PushPointerToMember(L, fn);
584 lua_pushcclosure(L, &member_fn_wrapper_<T, Rt, Args...>, 2);
585 if (m_protected)
586 lua_pushcclosure(L, &secure_trampoline, 1);
587
588 lua_setfield(L, -2, name);
589 lua_pop(L, 1);
590
591 return *this;
592 }
593
594 // Bind a free function to Lua.
595 // The self parameter will be automatically provided, but the function
596 // is responsible for pulling the rest of its parameters and pushing the
597 // appropriate number of return values.
598 Self &AddFunction(const char *name, member_cfunction<T> fn)
599 {
600 lua_State *L = m_lua;
602
603 lua_pushstring(L, (m_typeName + "." + name).c_str());
604 PushFreeFunction(L, fn);
605 lua_pushcclosure(L, &member_cfn_wrapper_<T>, 2);
606 if (m_protected)
607 lua_pushcclosure(L, &secure_trampoline, 1);
608
609 lua_setfield(L, -2, name);
610 lua_pop(L, 1);
611
612 return *this;
613 }
614
615 // Add a raw lua function to this object's method table
616 // For e.g. static member functions
617 Self &AddFunction(const char *name, lua_CFunction func)
618 {
620
621 lua_pushcfunction(m_lua, func);
622 if (m_protected)
623 lua_pushcclosure(m_lua, secure_trampoline, 1);
624
625 lua_setfield(m_lua, -2, name);
626 lua_pop(m_lua, 1);
627 return *this;
628 }
629
630 // Magic to allow binding a const function to Lua. Take care to ensure that you do not
631 // push a const object to lua, or this code will become undefined behavior.
632 template <typename Rt, typename... Args>
634 {
635 return AddMeta(name, reinterpret_cast<member_function<T, Rt, Args...>>(fn));
636 }
637
638 // Bind a member function to Lua as a metamethod.
639 // Parameters will automatically be pulled from Lua and be passed to the function.
640 // It is the responsiblity of the programmer to ensure a valid LuaPull implementation
641 // is available for each parameter's time.
642 // If the function has a non-void return type, its return value will automatically be
643 // pushed to Lua.
644 template <typename Rt, typename... Args>
646 {
647 lua_State *L = m_lua;
648
649 lua_pushstring(L, (m_typeName + "." + name).c_str());
650 PushPointerToMember(L, fn);
651 lua_pushcclosure(L, &member_fn_wrapper_<T, Rt, Args...>, 2);
652 if (m_protected)
653 lua_pushcclosure(L, &secure_trampoline, 1);
654
655 lua_setfield(L, m_index, name);
656
657 return *this;
658 }
659
660 // Bind a free function to Lua as a metamethod.
661 // The self parameter will be automatically provided, but the function
662 // is responsible for pulling the rest of its parameters and pushing the
663 // appropriate number of return values.
664 Self &AddMeta(const char *name, member_cfunction<T> fn)
665 {
666 lua_State *L = m_lua;
667
668 lua_pushstring(L, (m_typeName + "." + name).c_str());
669 PushFreeFunction(L, fn);
670 lua_pushcclosure(L, &member_cfn_wrapper_<T>, 2);
671 if (m_protected)
672 lua_pushcclosure(L, &secure_trampoline, 1);
673
674 lua_setfield(L, m_index, name);
675
676 return *this;
677 }
678
679 // Add a raw lua function to this object's metamethod table
680 Self &AddMeta(const char *name, lua_CFunction func)
681 {
682 lua_pushcfunction(m_lua, func);
683 if (m_protected)
684 lua_pushcclosure(m_lua, secure_trampoline, 1);
685
686 lua_setfield(m_lua, m_index, name);
687
688 return *this;
689 }
690
691 Self &RegisterFuncs(const luaL_Reg *functions)
692 {
693 lua_State *L = m_lua;
695
696 for (const luaL_Reg *func = functions; func->name; ++func) {
697 lua_pushcfunction(L, func->func);
698 if (m_protected)
699 lua_pushcclosure(L, secure_trampoline, 1);
700
701 lua_setfield(L, -2, func->name);
702 }
703
704 lua_pop(L, 1);
705 }
706
707 Self &AddCallCtor(lua_CFunction func)
708 {
710 lua_getmetatable(m_lua, -1);
711
712 lua_pushcfunction(m_lua, func);
713 if (m_protected)
714 lua_pushcclosure(m_lua, secure_trampoline, 1);
715
716 lua_setfield(m_lua, -2, "__call");
717 lua_pop(m_lua, 2);
718
719 return *this;
720 }
721
722 Self &AddNewCtor(lua_CFunction func)
723 {
725
726 lua_pushcfunction(m_lua, func);
727 if (m_protected)
728 lua_pushcclosure(m_lua, secure_trampoline, 1);
729
730 lua_setfield(m_lua, -2, "New");
731 lua_pop(m_lua, 1);
732 return *this;
733 }
734
735private:
736 bool m_protected = false;
737};
Ret pi_lua_multiple_call(lua_State *l, int index, Ret(*fn)())
Definition LuaCall.h:19
int secure_trampoline(lua_State *l)
Definition Sandbox.cpp:441
Definition LuaMetaType.h:44
Rt(T::*)(Args...) const const_member_function
Definition LuaMetaType.h:222
static T PullFreeFunction(lua_State *L, int index)
Definition LuaMetaType.h:315
void StopRecording()
Definition LuaMetaType.h:78
Dt T::* member_pointer
Definition LuaMetaType.h:144
static std::enable_if<!std::is_same< Rt, void >::value, int >::type member_fn_wrapper_(lua_State *L)
Definition LuaMetaType.h:226
static int getter_member_cfn_wrapper_(lua_State *L)
Definition LuaMetaType.h:191
Rt(*)(Args...) free_function
Definition LuaMetaType.h:107
static void PushPointerToMember(lua_State *L, MemT obj)
Definition LuaMetaType.h:296
static std::enable_if< std::is_same< Rt, void >::value, int >::type member_fn_wrapper_(lua_State *L)
Definition LuaMetaType.h:246
static void GetNames(std::vector< std::string > &names, const std::string &prefix="", bool methodsOnly=false)
Definition LuaMetaType.cpp:261
const char * GetParent() const
Definition LuaMetaType.h:55
static void PushFreeFunction(lua_State *L, T obj)
Definition LuaMetaType.h:308
std::string m_typeName
Definition LuaMetaType.h:332
lua_State * m_lua
Definition LuaMetaType.h:335
int m_ref
Definition LuaMetaType.h:337
int(*)(lua_State *, T *) member_cfunction
Definition LuaMetaType.h:173
std::string m_parent
Definition LuaMetaType.h:333
void StartRecording()
Definition LuaMetaType.h:68
void GetMetatable() const
Definition LuaMetaType.cpp:386
static std::enable_if<!std::is_same< Rt, void >::value, int >::type free_fn_wrapper_(lua_State *L)
Definition LuaMetaType.h:111
LuaMetaTypeBase(const char *name)
Definition LuaMetaType.h:46
static bool GetMetatableFromName(lua_State *l, const char *name)
Definition LuaMetaType.cpp:373
Rt(T::*)(Args...) member_function
Definition LuaMetaType.h:219
void SetParent(const char *parent)
Definition LuaMetaType.h:57
static int member_cfn_wrapper_(lua_State *L)
Definition LuaMetaType.h:176
static std::enable_if< std::is_same< Rt, void >::value, int >::type free_fn_wrapper_(lua_State *L)
Definition LuaMetaType.h:126
static int getter_member_fn_wrapper_(lua_State *L)
Definition LuaMetaType.h:265
void GetMethodTable(lua_State *L, int index)
Definition LuaMetaType.h:327
static void * TestUserdata(lua_State *l, int index, const char *name)
Definition LuaMetaType.cpp:399
void GetAttrTable(lua_State *L, int index)
Definition LuaMetaType.h:321
static MemT & PullPointerToMember(lua_State *L, int idx)
Definition LuaMetaType.h:302
static int member_wrapper_(lua_State *L)
Definition LuaMetaType.h:147
static void * CheckUserdata(lua_State *l, int index, const char *name)
Definition LuaMetaType.cpp:412
void CreateMetaType(lua_State *l)
Definition LuaMetaType.cpp:423
const char * GetTypeName() const
Definition LuaMetaType.h:53
int m_index
Definition LuaMetaType.h:339
bool IsValid() const
Definition LuaMetaType.h:63
Definition LuaMetaType.h:342
Self & AddCallCtor(lua_CFunction func)
Definition LuaMetaType.h:435
Self & AddMeta(const char *name, lua_CFunction func)
Definition LuaMetaType.h:410
LuaMetaTypeGeneric(const char *name)
Definition LuaMetaType.h:346
Self & SetProtected(bool enabled)
Definition LuaMetaType.h:362
Self & AddFunction(const char *name, free_function< Rt, Args... > func)
Definition LuaMetaType.h:395
Self & StartRecording()
Definition LuaMetaType.h:350
Self & StopRecording()
Definition LuaMetaType.h:356
Self & AddFunction(const char *name, lua_CFunction func)
Definition LuaMetaType.h:381
Self & AddNewCtor(lua_CFunction func)
Definition LuaMetaType.h:450
Self & AddMember(const char *name, lua_CFunction getter)
Definition LuaMetaType.h:368
Self & AddMeta(const char *name, free_function< Rt, Args... > func)
Definition LuaMetaType.h:422
Definition LuaMetaType.h:468
LuaMetaType(const char *name)
Definition LuaMetaType.h:472
Self & AddNewCtor(lua_CFunction func)
Definition LuaMetaType.h:722
Self & StopRecording()
Definition LuaMetaType.h:482
Self & AddMeta(const char *name, lua_CFunction func)
Definition LuaMetaType.h:680
Self & AddMember(const char *name, member_function< T, Dt > getter, member_function< T, void, Dt2 > setter=nullptr)
Definition LuaMetaType.h:544
Self & AddMember(const char *name, member_pointer< T, Dt > t)
Definition LuaMetaType.h:496
Self & AddMeta(const char *name, const_member_function< T, Rt, Args... > fn)
Definition LuaMetaType.h:633
Self & AddFunction(const char *name, member_function< T, Rt, Args... > fn)
Definition LuaMetaType.h:577
Self & AddMeta(const char *name, member_function< T, Rt, Args... > fn)
Definition LuaMetaType.h:645
Self & AddMeta(const char *name, member_cfunction< T > fn)
Definition LuaMetaType.h:664
Self & RegisterFuncs(const luaL_Reg *functions)
Definition LuaMetaType.h:691
Self & AddFunction(const char *name, const_member_function< T, Rt, Args... > fn)
Definition LuaMetaType.h:565
Self & AddCallCtor(lua_CFunction func)
Definition LuaMetaType.h:707
Self & AddMember(const char *name, const_member_function< T, Dt > getter, member_function< T, void, Dt2 > setter=nullptr)
Definition LuaMetaType.h:536
Self & AddFunction(const char *name, lua_CFunction func)
Definition LuaMetaType.h:617
Self & StartRecording()
Definition LuaMetaType.h:476
void SetProtected(bool enabled)
Definition LuaMetaType.h:490
Self & AddMember(const char *name, member_cfunction< T > getter, member_cfunction< T > setter=nullptr)
Definition LuaMetaType.h:515
Self & AddFunction(const char *name, member_cfunction< T > fn)
Definition LuaMetaType.h:598