Pioneer
LuaCall.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 /*
7  This file implements a generic method to call a C++ member function with
8  arguments passed in from Lua. It's intended to back a generic method of
9  binding code to Lua with minimal boilerplate needed.
10 */
11 
12 #include "Lua.h"
13 #include "LuaPushPull.h"
14 
15 // Backend to bind call a C++ free function with arguments from Lua.
16 // Parameter `index` points to the first argument
17 
18 template <typename Ret>
19 Ret pi_lua_multiple_call(lua_State *l, int index, Ret (*fn)())
20 {
21  return fn();
22 }
23 
24 template <typename Ret, typename Arg1>
25 Ret pi_lua_multiple_call(lua_State *l, int index, Ret (*fn)(Arg1))
26 {
27  auto arg1 = LuaPull<Arg1>(l, index);
28  return fn(arg1);
29 }
30 
31 template <typename Ret, typename Arg1, typename Arg2>
32 Ret pi_lua_multiple_call(lua_State *l, int index, Ret (*fn)(Arg1, Arg2))
33 {
34  auto arg1 = LuaPull<Arg1>(l, index);
35  auto arg2 = LuaPull<Arg2>(l, index + 1);
36  return fn(arg1, arg2);
37 }
38 
39 template <typename Ret, typename Arg1, typename Arg2, typename Arg3>
40 Ret pi_lua_multiple_call(lua_State *l, int index, Ret (*fn)(Arg1, Arg2, Arg3))
41 {
42  auto arg1 = LuaPull<Arg1>(l, index);
43  auto arg2 = LuaPull<Arg2>(l, index + 1);
44  auto arg3 = LuaPull<Arg3>(l, index + 2);
45  return fn(arg1, arg2, arg3);
46 }
47 
48 template <typename Ret, typename Arg1, typename Arg2, typename Arg3, typename Arg4>
49 Ret pi_lua_multiple_call(lua_State *l, int index, Ret (*fn)(Arg1, Arg2, Arg3, Arg4))
50 {
51  auto arg1 = LuaPull<Arg1>(l, index);
52  auto arg2 = LuaPull<Arg2>(l, index + 1);
53  auto arg3 = LuaPull<Arg3>(l, index + 2);
54  auto arg4 = LuaPull<Arg4>(l, index + 3);
55  return fn(arg1, arg2, arg3, arg4);
56 }
57 
58 template <typename Ret, typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5>
59 Ret pi_lua_multiple_call(lua_State *l, int index, Ret (*fn)(Arg1, Arg2, Arg3, Arg4, Arg5))
60 {
61  auto arg1 = LuaPull<Arg1>(l, index);
62  auto arg2 = LuaPull<Arg2>(l, index + 1);
63  auto arg3 = LuaPull<Arg3>(l, index + 2);
64  auto arg4 = LuaPull<Arg4>(l, index + 3);
65  auto arg5 = LuaPull<Arg5>(l, index + 4);
66  return fn(arg1, arg2, arg3, arg4, arg5);
67 }
68 
69 template <typename Ret, typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5, typename Arg6>
70 Ret pi_lua_multiple_call(lua_State *l, int index, Ret (*fn)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6))
71 {
72  auto arg1 = LuaPull<Arg1>(l, index);
73  auto arg2 = LuaPull<Arg2>(l, index + 1);
74  auto arg3 = LuaPull<Arg3>(l, index + 2);
75  auto arg4 = LuaPull<Arg4>(l, index + 3);
76  auto arg5 = LuaPull<Arg5>(l, index + 4);
77  auto arg6 = LuaPull<Arg6>(l, index + 5);
78  return fn(arg1, arg2, arg3, arg4, arg5, arg6);
79 }
80 
81 template <typename Ret, typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5, typename Arg6, typename Arg7>
82 Ret pi_lua_multiple_call(lua_State *l, int index, Ret (*fn)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7))
83 {
84  auto arg1 = LuaPull<Arg1>(l, index);
85  auto arg2 = LuaPull<Arg2>(l, index + 1);
86  auto arg3 = LuaPull<Arg3>(l, index + 2);
87  auto arg4 = LuaPull<Arg4>(l, index + 3);
88  auto arg5 = LuaPull<Arg5>(l, index + 4);
89  auto arg6 = LuaPull<Arg6>(l, index + 5);
90  auto arg7 = LuaPull<Arg7>(l, index + 6);
91  return fn(arg1, arg2, arg3, arg4, arg5, arg6, arg7);
92 }
93 
94 // Backend to bind call a C++ member function with arguments from Lua.
95 // Parameter `index` points one-behind the first argument, where the object
96 // pointer should traditionally be
97 
98 template <class T, typename Ret>
99 Ret pi_lua_multiple_call(lua_State *l, int index, T *ptr, Ret (T::*fn)())
100 {
101  return (ptr->*fn)();
102 }
103 
104 template <class T, typename Ret, typename Arg1>
105 Ret pi_lua_multiple_call(lua_State *l, int index, T *ptr, Ret (T::*fn)(Arg1))
106 {
107  auto arg1 = LuaPull<Arg1>(l, index + 1);
108  return (ptr->*fn)(arg1);
109 }
110 
111 template <class T, typename Ret, typename Arg1, typename Arg2>
112 Ret pi_lua_multiple_call(lua_State *l, int index, T *ptr, Ret (T::*fn)(Arg1, Arg2))
113 {
114  auto arg1 = LuaPull<Arg1>(l, index + 1);
115  auto arg2 = LuaPull<Arg2>(l, index + 2);
116  return (ptr->*fn)(arg1, arg2);
117 }
118 
119 template <class T, typename Ret, typename Arg1, typename Arg2, typename Arg3>
120 Ret pi_lua_multiple_call(lua_State *l, int index, T *ptr, Ret (T::*fn)(Arg1, Arg2, Arg3))
121 {
122  auto arg1 = LuaPull<Arg1>(l, index + 1);
123  auto arg2 = LuaPull<Arg2>(l, index + 2);
124  auto arg3 = LuaPull<Arg3>(l, index + 3);
125  return (ptr->*fn)(arg1, arg2, arg3);
126 }
127 
128 template <class T, typename Ret, typename Arg1, typename Arg2, typename Arg3, typename Arg4>
129 Ret pi_lua_multiple_call(lua_State *l, int index, T *ptr, Ret (T::*fn)(Arg1, Arg2, Arg3, Arg4))
130 {
131  auto arg1 = LuaPull<Arg1>(l, index + 1);
132  auto arg2 = LuaPull<Arg2>(l, index + 2);
133  auto arg3 = LuaPull<Arg3>(l, index + 3);
134  auto arg4 = LuaPull<Arg4>(l, index + 4);
135  return (ptr->*fn)(arg1, arg2, arg3, arg4);
136 }
137 
138 template <class T, typename Ret, typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5>
139 Ret pi_lua_multiple_call(lua_State *l, int index, T *ptr, Ret (T::*fn)(Arg1, Arg2, Arg3, Arg4, Arg5))
140 {
141  auto arg1 = LuaPull<Arg1>(l, index + 1);
142  auto arg2 = LuaPull<Arg2>(l, index + 2);
143  auto arg3 = LuaPull<Arg3>(l, index + 3);
144  auto arg4 = LuaPull<Arg4>(l, index + 4);
145  auto arg5 = LuaPull<Arg5>(l, index + 5);
146  return (ptr->*fn)(arg1, arg2, arg3, arg4, arg5);
147 }
148 
149 template <class T, typename Ret, typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5, typename Arg6>
150 Ret pi_lua_multiple_call(lua_State *l, int index, T *ptr, Ret (T::*fn)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6))
151 {
152  auto arg1 = LuaPull<Arg1>(l, index + 1);
153  auto arg2 = LuaPull<Arg2>(l, index + 2);
154  auto arg3 = LuaPull<Arg3>(l, index + 3);
155  auto arg4 = LuaPull<Arg4>(l, index + 4);
156  auto arg5 = LuaPull<Arg5>(l, index + 5);
157  auto arg6 = LuaPull<Arg6>(l, index + 6);
158  return (ptr->*fn)(arg1, arg2, arg3, arg4, arg5, arg6);
159 }
160 
161 template <class T, typename Ret, typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5, typename Arg6, typename Arg7>
162 Ret pi_lua_multiple_call(lua_State *l, int index, T *ptr, Ret (T::*fn)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7))
163 {
164  auto arg1 = LuaPull<Arg1>(l, index + 1);
165  auto arg2 = LuaPull<Arg2>(l, index + 2);
166  auto arg3 = LuaPull<Arg3>(l, index + 3);
167  auto arg4 = LuaPull<Arg4>(l, index + 4);
168  auto arg5 = LuaPull<Arg5>(l, index + 5);
169  auto arg6 = LuaPull<Arg6>(l, index + 6);
170  auto arg7 = LuaPull<Arg7>(l, index + 7);
171  return (ptr->*fn)(arg1, arg2, arg3, arg4, arg5, arg6, arg7);
172 }
173 
174 // Pull an object and arguments for the passed function from Lua.
175 // Intended to ease the amount of boilerplate code needed to bind a method to Lua.
176 
177 template <typename Ret, typename... Args>
178 Ret pi_lua_generic_call(lua_State *l, int index, Ret (*fn)(Args...))
179 {
180  return pi_lua_multiple_call<Ret, Args...>(l, index, fn);
181 }
182 
183 template <class T, typename Ret, typename... Args>
184 Ret pi_lua_generic_call(lua_State *l, int index, Ret (T::*fn)(Args...))
185 {
186  T *ptr = LuaPull<T>(l, index);
187  return pi_lua_multiple_call<T, Ret, Args...>(l, index, ptr, fn);
188 }
Ret pi_lua_generic_call(lua_State *l, int index, Ret(*fn)(Args...))
Definition: LuaCall.h:178
Ret pi_lua_multiple_call(lua_State *l, int index, Ret(*fn)())
Definition: LuaCall.h:19