Created
April 1, 2013 08:06
-
-
Save Twinklebear/5283762 to your computer and use it in GitHub Desktop.
Lua binding generation fiddling
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <string> | |
#include <lua/lua.hpp> | |
//Our fake DataLib | |
template<class T> | |
class DataLib { | |
public: | |
static void Push(lua_State *l, const T obj); | |
static T GetCopy(lua_State *l, int i); | |
}; | |
//Int specialization | |
template<> | |
void DataLib<int>::Push(lua_State *l, const int obj){ | |
lua_pushinteger(l, obj); | |
} | |
template<> | |
int DataLib<int>::GetCopy(lua_State *l, int i){ | |
return luaL_checkint(l, i); | |
} | |
//Float specialization | |
template<> | |
void DataLib<float>::Push(lua_State *l, const float obj){ | |
lua_pushnumber(l, obj); | |
} | |
template<> | |
float DataLib<float>::GetCopy(lua_State *l, int i){ | |
return luaL_checknumber(l, i); | |
} | |
//String specialization | |
template<> | |
void DataLib<std::string>::Push(lua_State *l, const std::string obj){ | |
lua_pushstring(l, obj.c_str()); | |
} | |
template<> | |
std::string DataLib<std::string>::GetCopy(lua_State *l, int i){ | |
return luaL_checkstring(l, i); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <iostream> | |
#include <string> | |
#include <tuple> | |
#include <functional> | |
#include <chrono> | |
#include <thread> | |
#include <lua/lua.hpp> | |
#include "datalib.h" | |
#define RETURN(x) -> decltype(x){ return x; } | |
//---------------------------------------------------- | |
// Apply Tuple code | |
//---------------------------------------------------- | |
//Call a function with a tuple as the parameters | |
//General recursion step | |
template<size_t N> | |
struct apply { | |
template<class F, class... ArgsT, class... Args> | |
static inline auto applyTuple(const F &f, std::tuple<ArgsT...> &t, Args&... args) | |
RETURN(apply<N-1>::applyTuple(f, t, std::get<N-1>(t), args...)); | |
}; | |
//Final recursion level | |
template<> | |
struct apply<0> { | |
template<class F, class... ArgsT, class... Args> | |
static inline auto applyTuple(const F &f, std::tuple<ArgsT...> &t, Args&... args) | |
RETURN(f(args...)); | |
}; | |
//Helper to get things started | |
template<class F, class... ArgsT> | |
static inline auto applyTuple(const F &f, std::tuple<ArgsT...> &t) | |
RETURN(apply<sizeof...(ArgsT)>::applyTuple(f, t)); | |
//---------------------------------------------------- | |
// Set Tuple code | |
//---------------------------------------------------- | |
//Set a tuple's values using those returned by DataLib<type> | |
template<size_t N> | |
struct setter { | |
template<class... ArgsT> | |
static inline void setTuple(lua_State *l, std::tuple<ArgsT...> &t){ | |
std::get<N>(t) = DataLib<typename std::tuple_element<N, std::tuple<ArgsT...>>::type>::GetCopy(l, N + 1); | |
//move to next | |
setter<N-1>::setTuple(l, t); | |
} | |
}; | |
//Final recursion level | |
template<> | |
struct setter<0> { | |
template<class... ArgsT> | |
static inline void setTuple(lua_State *l, std::tuple<ArgsT...> &t){ | |
std::get<0>(t) = DataLib<typename std::tuple_element<0, std::tuple<ArgsT...>>::type>::GetCopy(l, 1); | |
} | |
}; | |
//Helper to get things started | |
template<class... ArgsT> | |
static inline void setTuple(lua_State *l, std::tuple<ArgsT...> &t){ | |
setter<sizeof...(ArgsT) - 1>::setTuple(l, t); | |
} | |
//---------------------------------------------------- | |
//---------------------------------------------------- | |
// Generate a wrapped function | |
//---------------------------------------------------- | |
//How? | |
//---------------------------------------------------- | |
int func(int i, float f){ | |
std::cout << "in func, int: " << i << ", float: " << f << std::endl; | |
return 100; | |
} | |
//Need to come up with a way to generate this function somehow | |
int wrap(lua_State *l){ | |
std::tuple<int, float> args; | |
setTuple(l, args); | |
int res = applyTuple(func, args); | |
DataLib<int>::Push(l, res); | |
return 1; | |
} | |
int speak(lua_State *l){ | |
std::cout << DataLib<std::string>::GetCopy(l, 1) << std::endl; | |
return 0; | |
} | |
const struct luaL_Reg testLib[] = { | |
{ "speak", speak }, | |
{ "wrap", wrap }, | |
{ NULL, NULL } | |
}; | |
int luaopen_test(lua_State *l){ | |
luaL_register(l, "Test", testLib); | |
lua_pop(l, 1); | |
return 0; | |
} | |
int main(int argc, char const **argv){ | |
lua_State *l = luaL_newstate(); | |
luaL_openlibs(l); | |
luaopen_test(l); | |
std::string program = std::string("print 'hello!'\n") + std::string("Test.speak('wee!')\n") | |
+ std::string("q = Test.wrap(10, 4.5)\n") + std::string("print ('q is: ' .. q)\n"); | |
luaL_dostring(l, program.c_str()); | |
lua_close(l); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment