Voxellancer  0.3
A game about voxels in space
 All Classes Functions Pages
luawrapperfunction.h
1 #pragma once
2 
3 #if defined(MSVC)
4 #pragma warning (disable : 4100)
5 #endif
6 
7 #include <string>
8 #include <tuple>
9 #include <functional>
10 
11 #include <glm/glm.hpp>
12 
13 
14 struct lua_State;
15 
17 {
18  virtual ~BaseLuaFunction() {}
19  virtual int apply(lua_State * state) = 0;
20 };
21 
22 namespace Lua
23 {
24  typedef int (*lua_CFunction) (lua_State * state);
25 
26  void settop(lua_State * state, int index);
27  void pushlightuserdata(lua_State * state, void * p);
28  void pushcclosure(lua_State * state, lua_CFunction fn, int n);
29  void setglobal(lua_State * state, const char * name);
30  void pushnil(lua_State * state);
31 }
32 
33 namespace Luaw
34 {
35  int _lua_dispatcher(lua_State * state);
36 
37  template <std::size_t... Is>
38  struct _indices {};
39 
40  template <std::size_t N, std::size_t... Is>
41  struct _indices_builder : _indices_builder<N-1, N-1, Is...> {};
42 
43  template <std::size_t... Is>
44  struct _indices_builder<0, Is...>
45  {
46  using type = _indices<Is...>;
47  };
48 
49  template <typename T> T _check_get(lua_State * state, const int index);
50 
51  template <typename T> bool _check(lua_State * state, const int index);
52  template <typename T> T _check_get_field(lua_State * state, const int index, const char* key);
53 
54  void _push(lua_State * state); // Necessary in the case no arguments are passed
55  void _push(lua_State * state, bool &&value);
56  void _push(lua_State * state, int &&value);
57  void _push(lua_State * state, unsigned long &&value);
58  void _push(lua_State * state, unsigned int &&value);
59  void _push(lua_State * state, float &&value);
60  void _push(lua_State * state, double &&value);
61  void _push(lua_State * state, std::string &&value);
62  void _push(lua_State * state, glm::vec3 &&value);
63 
64  template <typename Return, typename... Args, std::size_t... N>
65  Return _lift(std::function<Return(Args...)> function, std::tuple<Args...> args, _indices<N...>)
66  {
67  return function(std::get<N>(args)...);
68  }
69 
70  template <typename Return, typename... Args>
71  Return _lift(std::function<Return(Args...)> function, std::tuple<Args...> args)
72  {
73  return _lift(function, args, typename _indices_builder<sizeof...(Args)>::type());
74  }
75 
76  template <typename... T, std::size_t... N>
77  std::tuple<T...> _get_args(lua_State * state, _indices<N...>)
78  {
79  return std::make_tuple(_check_get<T>(state, N+1)...);
80  }
81 
82  template <typename... T>
83  std::tuple<T...> _get_args(lua_State * state)
84  {
85  const std::size_t num_args = sizeof...(T);
86  return _get_args<T...>(state, typename _indices_builder<num_args>::type());
87  }
88 
89  inline void _push_n(lua_State *) {}
90 
91  template <typename T, typename... Rest>
92  void _push_n(lua_State * state, T value, Rest... rest)
93  {
94  _push(state, std::forward<T>(value));
95  _push_n(state, rest...);
96  }
97 
98  template <typename... T, std::size_t... N>
99  void _push_dispatcher(lua_State * state, std::tuple<T...> &&values, _indices<N...>)
100  {
101  _push_n(state, std::get<N>(values)...);
102  }
103 
104  template <typename... T>
105  void _push(lua_State * state, std::tuple<T...> &&values)
106  {
107  const int num_values = sizeof...(T);
108  Lua::settop(state, num_values);
109  _push_dispatcher(state, std::forward<std::tuple<T...>>(values), typename _indices_builder<num_values>::type());
110  }
111 }
112 
113 
114 template <int N, typename Return, typename... Args>
116 {
117 protected:
118  std::function<Return(Args...)> m_function;
119  std::string m_name;
120  lua_State ** m_state;
121 
122 public:
123  LuaFunction(lua_State * &state, const std::string & name, Return(*function)(Args...)) : LuaFunction(state, name, std::function<Return(Args...)>{function}) {}
124 
125  LuaFunction(lua_State * &state, const std::string & name, std::function<Return(Args...)> function) : m_function(function), m_name(name), m_state(&state)
126  {
127  Lua::pushlightuserdata(state, (void *)static_cast<BaseLuaFunction *>(this));
128 
129  Lua::pushcclosure(state, &Luaw::_lua_dispatcher, 1);
130 
131  Lua::setglobal(state, name.c_str());
132  }
133 
134  ~LuaFunction()
135  {
136  if (m_state != nullptr && *m_state != nullptr)
137  {
138  Lua::pushnil(*m_state);
139  Lua::setglobal(*m_state, m_name.c_str());
140  }
141  }
142 
143  int apply(lua_State * state)
144  {
145  std::tuple<Args...> args = Luaw::_get_args<Args...>(state);
146  Return value = Luaw::_lift(m_function, args);
147  Luaw::_push(state, std::forward<Return>(value));
148  return N;
149  }
150 
151 public:
152  void operator=(LuaFunction &) = delete;
153 };
154 
155 #if defined(MSVC)
156 #pragma warning (default : 4100)
157 #endif
Definition: luawrapperfunction.h:115
Definition: luawrapperfunction.h:41
Definition: luawrapperfunction.h:38
Definition: luawrapperfunction.h:16