Use vector/templating for Lua-like bulk registration functions
This commit is contained in:
parent
1ae22aa046
commit
86b4680371
7 changed files with 91 additions and 24 deletions
|
@ -4365,15 +4365,16 @@ game_lua_kernel::game_lua_kernel(CVideo * video, game_state & gs, play_controlle
|
|||
{ "remove_shroud", &dispatch2<&game_lua_kernel::intf_shroud_op, false > },
|
||||
{ nullptr, nullptr }
|
||||
};
|
||||
/*
|
||||
lua_cpp::Reg const cpp_callbacks[] = {
|
||||
{}
|
||||
};
|
||||
*/
|
||||
lua_getglobal(L, "wesnoth");
|
||||
if (!lua_istable(L,-1)) {
|
||||
lua_newtable(L);
|
||||
}
|
||||
luaL_setfuncs(L, callbacks, 0);
|
||||
lua_cpp::set_functions(L, cpp_callbacks);
|
||||
//lua_cpp::set_functions(L, cpp_callbacks);
|
||||
lua_setglobal(L, "wesnoth");
|
||||
|
||||
// Create the getside metatable.
|
||||
|
|
|
@ -89,12 +89,14 @@ void push_function( lua_State* L, const lua_function & f )
|
|||
new (p) lua_function(f);
|
||||
}
|
||||
|
||||
void set_functions( lua_State* L, const lua_cpp::Reg * l)
|
||||
void set_functions( lua_State* L, const std::vector<lua_cpp::Reg>& functions)
|
||||
{
|
||||
luaL_checkversion(L);
|
||||
for (; l->name != nullptr; l++) { /* fill the table with given functions */
|
||||
push_function(L, l->func);
|
||||
lua_setfield(L, -2, l->name);
|
||||
for (const lua_cpp::Reg& l : functions) { /* fill the table with given functions */
|
||||
if (l.name != nullptr) {
|
||||
push_function(L, l.func);
|
||||
lua_setfield(L, -2, l.name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -111,16 +113,19 @@ void push_closure( lua_State* L, const lua_function & f, int nup)
|
|||
lua_pushcclosure(L, &intf_closure_dispatcher, 1+nup);
|
||||
}
|
||||
|
||||
void set_functions( lua_State* L, const lua_cpp::Reg * l, int nup )
|
||||
void set_functions( lua_State* L, const std::vector<lua_cpp::Reg>& functions, int nup )
|
||||
{
|
||||
luaL_checkversion(L);
|
||||
luaL_checkstack(L, nup+1, "too many upvalues");
|
||||
for (; l->name != nullptr; l++) { /* fill the table with given functions */
|
||||
for (const lua_cpp::Reg& l : functions) { /* fill the table with given functions */
|
||||
if (l.name == nullptr) {
|
||||
continue;
|
||||
}
|
||||
int i;
|
||||
for (i = 0; i < nup; ++i) /* copy upvalues to the top */
|
||||
lua_pushvalue(L, -nup);
|
||||
push_closure(L, l->func, nup); /* closure with those upvalues */
|
||||
lua_setfield(L, -(nup + 2), l->name);
|
||||
push_closure(L, l.func, nup); /* closure with those upvalues */
|
||||
lua_setfield(L, -(nup + 2), l.name);
|
||||
}
|
||||
lua_pop(L, nup); /* remove upvalues */
|
||||
}
|
||||
|
|
|
@ -126,6 +126,7 @@
|
|||
#define LUA_CPP_FUNCTION_HPP_INCLUDED
|
||||
|
||||
#include <boost/function.hpp>
|
||||
#include <vector>
|
||||
|
||||
struct lua_State;
|
||||
|
||||
|
@ -155,7 +156,24 @@ void push_function( lua_State* L, const lua_function & f );
|
|||
*
|
||||
* The note above applies.
|
||||
*/
|
||||
void set_functions( lua_State* L, const lua_cpp::Reg * l);
|
||||
void set_functions( lua_State* L, const std::vector<lua_cpp::Reg>& functions);
|
||||
|
||||
/**
|
||||
* Analogous to lua_setfuncs, it registers a collection of function wrapper
|
||||
* objects into a table, using push_function.
|
||||
*
|
||||
* The note above applies.
|
||||
*/
|
||||
template<int N>
|
||||
void set_functions( lua_State* L, const lua_cpp::Reg(& functions)[N])
|
||||
{
|
||||
std::vector<lua_cpp::Reg> l;
|
||||
l.reserve(N);
|
||||
for(int i = 0; i < N; i++) {
|
||||
l.push_back(functions[i]);
|
||||
}
|
||||
set_functions(L, l);
|
||||
}
|
||||
|
||||
/**
|
||||
* Pushes a closure which retains a boost::function object as its first up-value.
|
||||
|
@ -173,7 +191,24 @@ void push_closure( lua_State* L, const lua_function & f, int nup);
|
|||
* NOTE: set_functions(L, l, 0) is NOT the same as set_functions(L, l), as
|
||||
* the latter produces userdata and the former doesn't.
|
||||
*/
|
||||
void set_functions( lua_State* L, const lua_cpp::Reg * l, int nup);
|
||||
void set_functions( lua_State* L, const std::vector<lua_cpp::Reg>& functions, int nup);
|
||||
|
||||
/**
|
||||
* Analogous to lua_setfuncs and set_functions above, but pushes closures.
|
||||
*
|
||||
* NOTE: set_functions(L, l, 0) is NOT the same as set_functions(L, l), as
|
||||
* the latter produces userdata and the former doesn't.
|
||||
*/
|
||||
template<int N>
|
||||
void set_functions( lua_State* L, const lua_cpp::Reg(& functions)[N], int nup)
|
||||
{
|
||||
std::vector<lua_cpp::Reg> l;
|
||||
l.reserve(N);
|
||||
for(int i = 0; i < N; i++) {
|
||||
l.push_back(functions[i]);
|
||||
}
|
||||
set_functions(L, l, nup);
|
||||
}
|
||||
|
||||
} // end namespace lua_cpp_func
|
||||
|
||||
|
|
|
@ -286,21 +286,21 @@ lua_kernel_base::lua_kernel_base(CVideo * video)
|
|||
{ nullptr, nullptr }
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
lua_cpp::Reg const cpp_callbacks[] = {
|
||||
/* { "dofile", boost::bind(&lua_kernel_base::intf_dofile, this, _1)},
|
||||
{ "dofile", boost::bind(&lua_kernel_base::intf_dofile, this, _1)},
|
||||
{ "require", boost::bind(&lua_kernel_base::intf_require, this, _1)},
|
||||
{ "show_dialog", boost::bind(&lua_kernel_base::intf_show_dialog, this, _1)},
|
||||
{ "show_lua_console", boost::bind(&lua_kernel_base::intf_show_lua_console, this, _1)},
|
||||
*/ {}
|
||||
};
|
||||
*/
|
||||
|
||||
lua_getglobal(L, "wesnoth");
|
||||
if (!lua_istable(L,-1)) {
|
||||
lua_newtable(L);
|
||||
}
|
||||
luaL_setfuncs(L, callbacks, 0);
|
||||
lua_cpp::set_functions(L, cpp_callbacks, 0);
|
||||
//lua_cpp::set_functions(L, cpp_callbacks, 0);
|
||||
lua_setglobal(L, "wesnoth");
|
||||
|
||||
// Override the print function
|
||||
|
|
|
@ -28,16 +28,25 @@ plugins_context::plugins_context(const std::string & name)
|
|||
, name_(name)
|
||||
{}
|
||||
|
||||
plugins_context::plugins_context(const std::string & name, const Reg * l, const aReg * r)
|
||||
plugins_context::plugins_context(const std::string& name, const std::vector<Reg>& l, const std::vector<aReg>& r)
|
||||
: callbacks_()
|
||||
, accessors_()
|
||||
, name_(name)
|
||||
{
|
||||
for (; l->name != nullptr; l++) { /* fill the table with given functions */
|
||||
callbacks_.insert(std::make_pair(l->name, l->func));
|
||||
initialize(l, r);
|
||||
}
|
||||
|
||||
void plugins_context::initialize(const std::vector<Reg>& callbacks, const std::vector<aReg>& accessors)
|
||||
{
|
||||
for (const Reg& l : callbacks) { /* fill the table with given functions */
|
||||
if (l.name != nullptr) {
|
||||
callbacks_.insert(std::make_pair(l.name, l.func));
|
||||
}
|
||||
}
|
||||
for (; r->name != nullptr; r++) { /* fill the table with given functions */
|
||||
accessors_.insert(std::make_pair(r->name, r->func));
|
||||
for (const aReg& r : accessors) { /* fill the table with given functions */
|
||||
if (r.name != nullptr) {
|
||||
accessors_.insert(std::make_pair(r.name, r.func));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include <map>
|
||||
#include <string>
|
||||
#include <boost/function.hpp>
|
||||
#include <vector>
|
||||
|
||||
class config;
|
||||
|
||||
|
@ -36,7 +37,23 @@ public:
|
|||
typedef struct { char const * name; accessor_function func; } aReg;
|
||||
|
||||
plugins_context( const std::string & name );
|
||||
plugins_context( const std::string & name, const Reg * callbacks, const aReg * accessors);
|
||||
plugins_context( const std::string & name, const std::vector<Reg>& callbacks, const std::vector<aReg>& accessors);
|
||||
template<int N, int M>
|
||||
plugins_context( const std::string & name, const Reg (& callbacks)[N], const aReg (& accessors)[M])
|
||||
: name_(name)
|
||||
{
|
||||
std::vector<Reg> l;
|
||||
std::vector<aReg> r;
|
||||
l.reserve(N);
|
||||
r.reserve(M);
|
||||
for(int i = 0; i < N; i++) {
|
||||
l.push_back(callbacks[i]);
|
||||
}
|
||||
for(int i = 0; i < M; i++) {
|
||||
r.push_back(accessors[i]);
|
||||
}
|
||||
initialize(l, r);
|
||||
}
|
||||
|
||||
void play_slice();
|
||||
|
||||
|
@ -56,6 +73,8 @@ public:
|
|||
private:
|
||||
typedef std::map<std::string, callback_function > callback_list;
|
||||
typedef std::map<std::string, accessor_function > accessor_list;
|
||||
|
||||
void initialize(const std::vector<Reg>& callbacks, const std::vector<aReg>& accessors);
|
||||
|
||||
callback_list callbacks_;
|
||||
accessor_list accessors_;
|
||||
|
|
|
@ -674,11 +674,9 @@ static int do_gameloop(const std::vector<std::string>& args)
|
|||
|
||||
plugins_context::Reg const callbacks[] = {
|
||||
{ "play_multiplayer", boost::bind(&game_launcher::play_multiplayer, game.get())},
|
||||
{}
|
||||
};
|
||||
plugins_context::aReg const accessors[] = {
|
||||
{ "command_line", boost::bind(&commandline_options::to_config, &cmdline_opts)},
|
||||
{}
|
||||
};
|
||||
|
||||
plugins_context plugins("titlescreen", callbacks, accessors);
|
||||
|
|
Loading…
Add table
Reference in a new issue