#ifndef LUA_BINDINGS_H
#define LUA_BINDINGS_H
// Forward declare types needed
struct lua_State;
typedef int (*lua_CFunction) (lua_State *L);
void registerLuaBinding(lua_State* L, const char* name, lua_CFunction fn); // Register a single function
void registerLuaBindings(lua_State* L); // All the framework ones
// Using macro below, it is then possible to bind game specific ones
#define BIND_C_FUNTION_TO_LUA(L, func) \
registerLuaBinding(L, #func, [](lua_State* lua)->int { return MakeCallableFunc(lua, func); } )
#include "lua-5.3.2/src/lua.h"
#include <functional>
#include <cassert>
// If we are wrapping/binding a function that returns an int, propagate the result to lua
template <typename... As, typename... Ps>
int MakeCallableFunc(lua_State*, int, int (*fn)(Ps... values), int (*)(), As... params) {
return fn(std::forward<As>(params)...);
}
// Otherwise if the return type is not int, return 0
template <typename R, typename... As, typename... Ps>
int MakeCallableFunc(lua_State*, int, R (*fn)(Ps... values), R (*)(), As... params) {
fn(std::forward<As>(params)...);
return 0;
}
// Handle int arguments
template <typename R, typename... As, typename... Ts, typename... Ps>
int MakeCallableFunc(lua_State* L, int i, R (*fn)(As... values), R (*)(int, Ts... values), Ps... params) {
R (*fn3)(Ts... values) = nullptr;
assert(lua_isinteger(L,i));
return MakeCallableFunc(L, i+1, fn, fn3, std::forward<Ps>(params)..., (int)lua_tointeger(L, i));
}
// Handle double arguments
template <typename R, typename... As, typename... Ts, typename... Ps>
int MakeCallableFunc(lua_State* L, int i, R (*fn)(As... values), R (*)(double, Ts... values), Ps... params) {
R (*fn3)(Ts... values) = nullptr;
assert(lua_isnumber(L,i));
return MakeCallableFunc(L, i+1, fn, fn3, std::forward<Ps>(params)..., (double)lua_tonumber(L, i));
}
// Handle string arguments
template <typename R, typename... As, typename... Ts, typename... Ps>
int MakeCallableFunc(lua_State* L, int i, R (*fn)(As... values), R (*)(const char*, Ts... values), Ps... params) {
R (*fn3)(Ts... values) = nullptr;
assert(lua_isstring(L,i));
return MakeCallableFunc(L, i+1, fn, fn3, std::forward<Ps>(params)..., (const char*)lua_tostring(L, i));
}
// Add helper for entry in to creating the binding
template <typename R, typename... As>
int MakeCallableFunc(lua_State* L, R (*fn)(As... values)) {
return MakeCallableFunc(L, 1, fn, fn);
}
#endif // LUA_BINDINGS_H