-
Notifications
You must be signed in to change notification settings - Fork 117
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add support for C++ object registration.
In addition, this adds partial specializations for Fun and ClassFun to permit calling of functions that do not return values.
- Loading branch information
Showing
12 changed files
with
314 additions
and
76 deletions.
There are no files selected for viewing
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
#pragma once | ||
|
||
#include <functional> | ||
#include <tuple> | ||
#include "util.h" | ||
|
||
namespace sel { | ||
struct BaseFun { | ||
virtual ~BaseFun() {} | ||
virtual int Apply(lua_State *l) = 0; | ||
}; | ||
|
||
namespace detail { | ||
|
||
int _lua_dispatcher(lua_State *l); | ||
|
||
template <typename Ret, typename... Args, std::size_t... N> | ||
Ret _lift(std::function<Ret(Args...)> fun, | ||
std::tuple<Args...> args, | ||
_indices<N...>) { | ||
return fun(std::get<N>(args)...); | ||
} | ||
|
||
template <typename Ret, typename... Args> | ||
Ret _lift(std::function<Ret(Args...)> fun, | ||
std::tuple<Args...> args) { | ||
return _lift(fun, args, typename _indices_builder<sizeof...(Args)>::type()); | ||
} | ||
|
||
|
||
template <typename... T, std::size_t... N> | ||
std::tuple<T...> _get_args(lua_State *l, _indices<N...>) { | ||
return std::make_tuple(_check_get<T>(l, N + 1)...); | ||
} | ||
|
||
template <typename... T> | ||
std::tuple<T...> _get_args(lua_State *l) { | ||
constexpr std::size_t num_args = sizeof...(T); | ||
return _get_args<T...>(l, typename _indices_builder<num_args>::type()); | ||
} | ||
} | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
#pragma once | ||
|
||
#include "ClassFun.h" | ||
#include <functional> | ||
#include "LuaName.h" | ||
#include <memory> | ||
#include "State.h" | ||
#include <string> | ||
#include "util.h" | ||
#include <utility> | ||
#include <vector> | ||
|
||
namespace sel { | ||
struct BaseClass { | ||
virtual ~BaseClass() {} | ||
}; | ||
template <typename T, typename... Funs> | ||
class Class : public BaseClass { | ||
private: | ||
LuaName _name; | ||
std::vector<std::unique_ptr<BaseFun>> _funs; | ||
|
||
template <typename Ret, typename... Args> | ||
void _register_fun(lua_State *state, | ||
T *t, | ||
const char *fun_name, | ||
Ret(T::*fun)(Args...)) { | ||
std::function<Ret(Args...)> lambda = [t, fun](Args... args) { | ||
return (t->*fun)(args...); | ||
}; | ||
constexpr int arity = detail::_arity<Ret>::value; | ||
_funs.emplace_back( | ||
new ClassFun<arity, Ret, Args...> | ||
{state, std::string(fun_name), lambda}); | ||
} | ||
|
||
void _register_funs(lua_State *state, T *t) {} | ||
|
||
template <typename F, typename... Fs> | ||
void _register_funs(lua_State *state, T *t, | ||
std::pair<const char *, F> fun, | ||
std::pair<const char *, Fs>... funs) { | ||
_register_fun(state, t, fun.first, fun.second); | ||
_register_funs(state, t, funs...); | ||
} | ||
public: | ||
Class(lua_State *&state, T *t, const std::string &name, | ||
std::pair<const char *, Funs>... funs) | ||
: _name(state, name) { | ||
lua_createtable(state, 0, sizeof...(Funs)); | ||
_register_funs(state, t, funs...); | ||
_name.Register(); | ||
} | ||
}; | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
#pragma once | ||
|
||
#include "BaseFun.h" | ||
#include "LuaName.h" | ||
#include <string> | ||
|
||
namespace sel { | ||
|
||
template <int N, typename Ret, typename... Args> | ||
class ClassFun : public BaseFun { | ||
private: | ||
using _return_type = Ret; | ||
using _fun_type = std::function<Ret(Args...)>; | ||
_fun_type _fun; | ||
|
||
public: | ||
ClassFun(lua_State *l, | ||
const std::string &name, | ||
_return_type(*fun)(Args...)) | ||
: ClassFun(l, name, _fun_type{fun}) {} | ||
|
||
ClassFun(lua_State *l, | ||
const std::string &name, | ||
_fun_type fun) : _fun(fun) { | ||
lua_pushlightuserdata(l, (void *)static_cast<BaseFun *>(this)); | ||
lua_pushcclosure(l, &detail::_lua_dispatcher, 1); | ||
lua_setfield(l, -2, name.c_str()); | ||
} | ||
|
||
// Each application of a function receives a new Lua context so | ||
// this argument is necessary. | ||
int Apply(lua_State *l) { | ||
std::tuple<Args...> args = detail::_get_args<Args...>(l); | ||
_return_type value = detail::_lift(_fun, args); | ||
detail::_push(l, std::forward<_return_type>(value)); | ||
return N; | ||
} | ||
}; | ||
|
||
template <typename Ret, typename... Args> | ||
class ClassFun<0, Ret, Args...> : public BaseFun { | ||
private: | ||
using _return_type = Ret; | ||
using _fun_type = std::function<Ret(Args...)>; | ||
_fun_type _fun; | ||
|
||
public: | ||
ClassFun(lua_State *l, | ||
const std::string &name, | ||
_return_type(*fun)(Args...)) | ||
: ClassFun(l, name, _fun_type{fun}) {} | ||
|
||
ClassFun(lua_State *l, | ||
const std::string &name, | ||
_fun_type fun) : _fun(fun) { | ||
lua_pushlightuserdata(l, (void *)static_cast<BaseFun *>(this)); | ||
lua_pushcclosure(l, &detail::_lua_dispatcher, 1); | ||
lua_setfield(l, -2, name.c_str()); | ||
} | ||
|
||
// Each application of a function receives a new Lua context so | ||
// this argument is necessary. | ||
int Apply(lua_State *l) { | ||
std::tuple<Args...> args = detail::_get_args<Args...>(l); | ||
detail::_lift(_fun, args); | ||
return 0; | ||
} | ||
}; | ||
} |
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
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
Oops, something went wrong.