Otclient  14/8/2020
luabinder.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2010-2020 OTClient <https://github.com/edubart/otclient>
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a copy
5  * of this software and associated documentation files (the "Software"), to deal
6  * in the Software without restriction, including without limitation the rights
7  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8  * copies of the Software, and to permit persons to whom the Software is
9  * furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included in
12  * all copies or substantial portions of the Software.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20  * THE SOFTWARE.
21  */
22 
23 #ifndef LUABINDER_H
24 #define LUABINDER_H
25 
26 // this file is and must be included only from luainterface.h
27 #include "luainterface.h"
28 #include "luaexception.h"
29 
31 #include <tuple>
32 
40 namespace luabinder
41 {
43  template<int N>
45  template<typename Tuple>
46  static void call(Tuple& tuple, LuaInterface* lua) {
47  typedef typename std::tuple_element<N-1, Tuple>::type ValueType;
48  std::get<N-1>(tuple) = lua->polymorphicPop<ValueType>();
50  }
51  };
52  template<>
54  template<typename Tuple>
55  static void call(Tuple& tuple, LuaInterface* lua) { }
56  };
57 
59  template<typename Ret, typename F, typename... Args>
60  typename std::enable_if<!std::is_void<Ret>::value, int>::type
61  call_fun_and_push_result(const F& f, LuaInterface* lua, const Args&... args) {
62  Ret ret = f(args...);
63  int numRets = lua->polymorphicPush(ret);
64  return numRets;
65  }
66 
68  template<typename Ret, typename F, typename... Args>
69  typename std::enable_if<std::is_void<Ret>::value, int>::type
70  call_fun_and_push_result(const F& f, LuaInterface* lua, const Args&... args) {
71  f(args...);
72  return 0;
73  }
74 
76  template<int N, typename Ret>
78  template<typename Tuple, typename F, typename... Args>
79  static int call(const Tuple& tuple, const F& f, LuaInterface* lua, const Args&... args) {
80  return expand_fun_arguments<N-1,Ret>::call(tuple, f, lua, std::get<N-1>(tuple), args...);
81  }
82  };
83  template<typename Ret>
84  struct expand_fun_arguments<0,Ret> {
85  template<typename Tuple, typename F, typename... Args>
86  static int call(const Tuple& tuple, const F& f, LuaInterface* lua, const Args&... args) {
87  return call_fun_and_push_result<Ret>(f, lua, args...);
88  }
89  };
90 
92  template<typename Ret, typename F, typename Tuple>
94  enum { N = std::tuple_size<Tuple>::value };
95  return [=](LuaInterface* lua) -> int {
96  while(lua->stackSize() != N) {
97  if(lua->stackSize() < N)
98  g_lua.pushNil();
99  else
100  g_lua.pop();
101  }
102  Tuple tuple;
104  return expand_fun_arguments<N,Ret>::call(tuple, f, lua);
105  };
106  }
107 
109  inline
110  LuaCppFunction bind_fun(const std::function<int(LuaInterface*)>& f) {
111  return f;
112  }
113 
115  template<typename Ret, typename... Args>
116  LuaCppFunction bind_fun(const std::function<Ret(Args...)>& f) {
117  typedef typename std::tuple<typename stdext::remove_const_ref<Args>::type...> Tuple;
118  return bind_fun_specializer<typename stdext::remove_const_ref<Ret>::type,
119  decltype(f),
120  Tuple>(f);
121  }
122 
124  template<typename F>
126 
127  template<typename Lambda, typename Ret, typename... Args>
128  struct bind_lambda_fun<Ret(Lambda::*)(Args...) const> {
129  static LuaCppFunction call(const Lambda& f) {
130  typedef typename std::tuple<typename stdext::remove_const_ref<Args>::type...> Tuple;
131  return bind_fun_specializer<typename stdext::remove_const_ref<Ret>::type,
132  decltype(f),
133  Tuple>(f);
134 
135  }
136  };
137 
138  template<typename Lambda>
139  typename std::enable_if<std::is_constructible<decltype(&Lambda::operator())>::value, LuaCppFunction>::type bind_fun(const Lambda& f) {
140  typedef decltype(&Lambda::operator()) F;
141  return bind_lambda_fun<F>::call(f);
142  }
143 
145  template<typename Ret, typename... Args>
146  LuaCppFunction bind_fun(Ret (*f)(Args...)) {
147  return bind_fun(std::function<Ret(Args...)>(f));
148  }
149 
151  template<typename Ret, typename C, typename... Args>
152  std::function<Ret(const stdext::shared_object_ptr<C>&, const Args&...)> make_mem_func(Ret (C::* f)(Args...)) {
153  auto mf = std::mem_fn(f);
154  return [=](const stdext::shared_object_ptr<C>& obj, const Args&... args) mutable -> Ret {
155  if(!obj)
156  throw LuaException("failed to call a member function because the passed object is nil");
157  return mf(obj.get(), args...);
158  };
159  }
160  template<typename C, typename... Args>
161  std::function<void(const stdext::shared_object_ptr<C>&, const Args&...)> make_mem_func(void (C::* f)(Args...)) {
162  auto mf = std::mem_fn(f);
163  return [=](const stdext::shared_object_ptr<C>& obj, const Args&... args) mutable -> void {
164  if(!obj)
165  throw LuaException("failed to call a member function because the passed object is nil");
166  mf(obj.get(), args...);
167  };
168  }
169 
171  template<typename Ret, typename C, typename... Args>
172  std::function<Ret(const Args&...)> make_mem_func_singleton(Ret (C::* f)(Args...), C* instance) {
173  auto mf = std::mem_fn(f);
174  return [=](Args... args) mutable -> Ret { return mf(instance, args...); };
175  }
176  template<typename C, typename... Args>
177  std::function<void(const Args&...)> make_mem_func_singleton(void (C::* f)(Args...), C* instance) {
178  auto mf = std::mem_fn(f);
179  return [=](Args... args) mutable -> void { mf(instance, args...); };
180  }
181 
182 
184  template<typename C, typename Ret, class FC, typename... Args>
185  LuaCppFunction bind_mem_fun(Ret (FC::* f)(Args...)) {
186  typedef typename std::tuple<stdext::shared_object_ptr<FC>, typename stdext::remove_const_ref<Args>::type...> Tuple;
187  auto lambda = make_mem_func<Ret,FC>(f);
188  return bind_fun_specializer<typename stdext::remove_const_ref<Ret>::type,
189  decltype(lambda),
190  Tuple>(lambda);
191  }
192 
194  template<typename C, typename Ret, class FC, typename... Args>
195  LuaCppFunction bind_singleton_mem_fun(Ret (FC::*f)(Args...), C *instance) {
196  typedef typename std::tuple<typename stdext::remove_const_ref<Args>::type...> Tuple;
197  assert(instance);
198  auto lambda = make_mem_func_singleton<Ret,FC>(f, static_cast<FC*>(instance));
199  return bind_fun_specializer<typename stdext::remove_const_ref<Ret>::type,
200  decltype(lambda),
201  Tuple>(lambda);
202  }
203 
205  template<typename C>
207  auto mf = std::mem_fn(f);
208  return [=](LuaInterface* lua) mutable -> int {
209  auto obj = lua->castValue<stdext::shared_object_ptr<C>>(1);
210  lua->remove(1);
211  return mf(obj, lua);
212  };
213  }
214 }
215 
216 #endif
stdext::remove_const_ref::type
std::remove_const< typename std::remove_reference< T >::type >::type type
Definition: traits.h:33
LuaCppFunction
std::function< int(LuaInterface *)> LuaCppFunction
Definition: declarations.h:31
luaexception.h
luabinder::bind_singleton_mem_fun
LuaCppFunction bind_singleton_mem_fun(Ret(FC::*f)(Args...), C *instance)
Bind singleton member functions.
Definition: luabinder.h:195
luabinder::pack_values_into_tuple
Pack arguments from lua stack into a tuple recursively.
Definition: luabinder.h:44
luabinder::bind_fun_specializer
LuaCppFunction bind_fun_specializer(const F &f)
Bind different types of functions generating a lambda.
Definition: luabinder.h:93
luainterface.h
luabinder::bind_lambda_fun< Ret(Lambda::*)(Args...) const >::call
static LuaCppFunction call(const Lambda &f)
Definition: luabinder.h:129
luabinder::expand_fun_arguments::call
static int call(const Tuple &tuple, const F &f, LuaInterface *lua, const Args &... args)
Definition: luabinder.h:79
luabinder::pack_values_into_tuple::call
static void call(Tuple &tuple, LuaInterface *lua)
Definition: luabinder.h:46
LuaException
Definition: luaexception.h:28
LuaInterface::polymorphicPush
int polymorphicPush(const T &v, const Args &... args)
Pushes any type onto the stack.
Definition: luainterface.h:358
luabinder::expand_fun_arguments
Expand arguments from tuple for later calling the C++ function.
Definition: luabinder.h:77
g_lua
LuaInterface g_lua
Definition: luainterface.cpp:31
luabinder::bind_mem_fun
LuaCppFunction bind_mem_fun(Ret(FC::*f)(Args...))
Bind member functions.
Definition: luabinder.h:185
LuaInterface::polymorphicPop
T polymorphicPop()
Same as castValue but also pops.
Definition: luainterface.h:339
luabinder::make_mem_func_singleton
std::function< Ret(const Args &...)> make_mem_func_singleton(Ret(C::*f)(Args...), C *instance)
Create member function lambdas for singleton classes.
Definition: luabinder.h:172
luabinder::make_mem_func
std::function< Ret(const stdext::shared_object_ptr< C > &, const Args &...)> make_mem_func(Ret(C::*f)(Args...))
Create member function lambdas.
Definition: luabinder.h:152
luabinder::call_fun_and_push_result
std::enable_if<!std::is_void< Ret >::value, int >::type call_fun_and_push_result(const F &f, LuaInterface *lua, const Args &... args)
C++ function caller that can push results to lua.
Definition: luabinder.h:61
LuaInterface
Class that manages LUA stuff.
Definition: luainterface.h:32
luabinder::bind_lambda_fun
Specialization for lambdas.
Definition: luabinder.h:125
luabinder::expand_fun_arguments< 0, Ret >::call
static int call(const Tuple &tuple, const F &f, LuaInterface *lua, const Args &... args)
Definition: luabinder.h:86
luabinder
Definition: luabinder.h:40
LuaInterface::pop
void pop(int n=1)
Definition: luainterface.cpp:999
luabinder::bind_fun
LuaCppFunction bind_fun(const std::function< int(LuaInterface *)> &f)
Bind a customized function.
Definition: luabinder.h:110
stdext::shared_object_ptr
Definition: shared_object.h:39
luabinder::pack_values_into_tuple< 0 >::call
static void call(Tuple &tuple, LuaInterface *lua)
Definition: luabinder.h:55
traits.h
LuaInterface::pushNil
void pushNil()
Definition: luainterface.cpp:1060
stdext::shared_object_ptr::get
T * get() const
Definition: shared_object.h:82