Skip to content

Commit

Permalink
Use vector/templating for Lua-like bulk registration functions
Browse files Browse the repository at this point in the history
  • Loading branch information
CelticMinstrel committed Mar 31, 2016
1 parent 1ae22aa commit 86b4680
Show file tree
Hide file tree
Showing 7 changed files with 91 additions and 24 deletions.
5 changes: 3 additions & 2 deletions src/scripting/game_lua_kernel.cpp
Expand Up @@ -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.
Expand Down
21 changes: 13 additions & 8 deletions src/scripting/lua_cpp_function.cpp
Expand Up @@ -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);
}
}
}

Expand All @@ -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 */
}
Expand Down
39 changes: 37 additions & 2 deletions src/scripting/lua_cpp_function.hpp
Expand Up @@ -126,6 +126,7 @@
#define LUA_CPP_FUNCTION_HPP_INCLUDED

#include <boost/function.hpp>
#include <vector>

struct lua_State;

Expand Down Expand Up @@ -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.
Expand All @@ -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

Expand Down
8 changes: 4 additions & 4 deletions src/scripting/lua_kernel_base.cpp
Expand Up @@ -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
Expand Down
19 changes: 14 additions & 5 deletions src/scripting/plugins/context.cpp
Expand Up @@ -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));
}
}
}

Expand Down
21 changes: 20 additions & 1 deletion src/scripting/plugins/context.hpp
Expand Up @@ -23,6 +23,7 @@
#include <map>
#include <string>
#include <boost/function.hpp>
#include <vector>

class config;

Expand All @@ -36,7 +37,23 @@ class plugins_context {
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();

Expand All @@ -56,6 +73,8 @@ class plugins_context {
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_;
Expand Down
2 changes: 0 additions & 2 deletions src/wesnoth.cpp
Expand Up @@ -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);
Expand Down

0 comments on commit 86b4680

Please sign in to comment.