Voxellancer  0.3
A game about voxels in space
 All Classes Functions Pages
luawrapper.h
1 #pragma once
2 
3 #include <string>
4 #include <vector>
5 #include <tuple>
6 #include <map>
7 #include <list>
8 #include <memory>
9 
10 #include <glm/glm.hpp>
11 
12 #include "luawrapperfunction.h"
13 
14 
15 struct lua_State;
16 
18 {
19 public:
20  LuaWrapper();
21  ~LuaWrapper();
22 
23  void loadScript(const std::string & script);
24  void loadString(const std::string & script);
25  void removeScript(const std::string & script);
26  void reloadScripts();
27 
28  bool has(const std::string & fun);
29 
30  static void reloadAll();
31 
32 
33 protected:
34  void luaError();
35  void pushFunc(const std::string & func) const;
36  void callFunc(const int numArgs, const int numRet);
37 
38  void popStack(const int index);
39 
40  template <typename T, typename... Ts>
41  void push(const T value, const Ts... values) const
42  {
43  push(value);
44  push(values...);
45  };
46 
47  void push() const;
48  void push(const std::string & value) const;
49  void push(const char * value) const;
50  void push(const int8_t value) const;
51  void push(const uint8_t value) const;
52  void push(const int16_t value) const;
53  void push(const uint16_t value) const;
54  void push(const int32_t value) const;
55  void push(const uint32_t value) const;
56  void push(const int64_t value) const;
57  void push(const uint64_t value) const;
58  void push(const float value) const;
59  void push(const double value) const;
60  void push(const bool value) const;
61  void push(const glm::vec3 & value) const;
62 
63  template <typename T> T fetch(const int index) const;
64 
65  template <size_t, typename... Ts>
66  struct _pop
67  {
68  typedef std::tuple<Ts...> type;
69 
70  template <typename T>
71  static std::tuple<T> worker(const LuaWrapper &instance, const int index)
72  {
73  return std::make_tuple(instance.fetch<T>(index));
74  }
75 
76  template <typename T1, typename T2, typename... Rest>
77  static std::tuple<T1, T2, Rest...> worker(const LuaWrapper &instance, const int index)
78  {
79  std::tuple<T1> head = std::make_tuple(instance.fetch<T1>(index));
80  return std::tuple_cat(head, worker<T2, Rest...>(instance, index + 1));
81  }
82 
83  static type apply(LuaWrapper &instance)
84  {
85  type ret = worker<Ts...>(instance, 1);
86  instance.popStack(sizeof...(Ts));
87  return ret;
88  }
89  };
90 
91  template <typename... Ts>
92  struct _pop<0, Ts...>
93  {
94  typedef void type;
95  static type apply(LuaWrapper & /*instance*/){}
96  };
97 
98  template <typename T>
99  struct _pop<1, T>
100  {
101  typedef T type;
102  static T apply(LuaWrapper &instance)
103  {
104  // fetch the top element (negative indices count from the top)
105  T ret = instance.fetch<T>(-1);
106 
107  instance.popStack(1);
108  return ret;
109  }
110  };
111 
112  template <typename... T>
113  typename _pop<sizeof...(T), T...>::type pop()
114  {
115  return _pop<sizeof...(T), T...>::apply(*this);
116  }
117 
118 
119 public:
120  template <typename... Ret, typename... Args>
121  typename _pop<sizeof...(Ret), Ret...>::type call(const std::string &fun, const Args&... args)
122  {
123  pushFunc(fun.c_str());
124  push(args...);
125 
126  const int numArgs = sizeof...(Args);
127  const int numRet = sizeof...(Ret);
128 
129  callFunc(numArgs, numRet);
130 
131  return pop<Ret...>();
132  }
133 
134 
135  template<typename Return, typename Class, typename... Args>
136  void Register(const std::string & name, Class * obj, Return(Class::* const method) (Args...))
137  {
138  std::function<Return(typename std::remove_reference<Args>::type...)> function = [obj, method](Args... args) {
139  return (obj->*method)(args...);
140  };
141 
142  Register(name, function);
143  };
144 
145  template <typename Return, typename... Args>
146  void Register(const std::string & name, std::function<Return(Args...)> function)
147  {
148  auto tmp = std::unique_ptr<BaseLuaFunction>(new LuaFunction<1, Return, Args...>{m_state, name, function});
149  m_functions.insert(std::make_pair(name, std::move(tmp)));
150  }
151 
152  template <typename Return, typename... Args>
153  void Register(const std::string & name, Return (*function)(Args...))
154  {
155  auto tmp = std::unique_ptr<BaseLuaFunction>(new LuaFunction<1, Return, Args...>{m_state, name, function});
156  m_functions.insert(std::make_pair(name, std::move(tmp)));
157  }
158 
159  template <typename... Return, typename... Args>
160  void Register(const std::string & name, std::function<std::tuple<Return...>(Args...)> function)
161  {
162  const int num_return = sizeof...(Return);
163  auto tmp = std::unique_ptr<BaseLuaFunction>(new LuaFunction<num_return, std::tuple<Return...>, Args...>{m_state, name, function});
164  m_functions.insert(std::make_pair(name, std::move(tmp)));
165  }
166 
167  template <typename... Return, typename... Args>
168  void Register(const std::string & name, std::tuple<Return...> (*function)(Args...))
169  {
170  const int num_return = sizeof...(Return);
171  auto tmp = std::unique_ptr<BaseLuaFunction>(new LuaFunction<num_return, std::tuple<Return...>, Args...>{m_state, name, function});
172  m_functions.insert(std::make_pair(name, std::move(tmp)));
173  }
174 
175  void Unregister(const std::string &name) {
176  auto it = m_functions.find(name);
177  if (it != m_functions.end()) m_functions.erase(it);
178  }
179 
180 
181 protected:
182  lua_State * m_state;
183 
184  std::vector<std::string> m_scripts;
185  int m_err;
186 
187  std::map<std::string, std::unique_ptr<BaseLuaFunction>> m_functions;
188 
189  static std::list<LuaWrapper *> s_instances;
190 
191 
192 public:
193  void operator=(LuaWrapper &) = delete;
194 };
Definition: luawrapper.h:66
Definition: luawrapperfunction.h:115
Definition: luawrapper.h:17