Move name generator and formula API to base Lua kernel
This commit is contained in:
parent
3c96dbc145
commit
c39af95a44
4 changed files with 101 additions and 96 deletions
|
@ -74,7 +74,6 @@
|
|||
#include "scripting/lua_api.hpp" // for luaW_toboolean, etc
|
||||
#include "scripting/lua_common.hpp"
|
||||
#include "scripting/lua_cpp_function.hpp"
|
||||
#include "scripting/lua_formula_bridge.hpp"
|
||||
#include "scripting/lua_gui2.hpp" // for show_gamestate_inspector
|
||||
#include "scripting/lua_pathfind_cost_calculator.hpp"
|
||||
#include "scripting/lua_race.hpp"
|
||||
|
@ -104,8 +103,6 @@
|
|||
#include "units/ptr.hpp" // for unit_const_ptr, unit_ptr
|
||||
#include "units/types.hpp" // for unit_type_data, unit_types, etc
|
||||
#include "util.hpp" // for lexical_cast
|
||||
#include "utils/markov_generator.hpp"
|
||||
#include "utils/context_free_grammar_generator.hpp"
|
||||
#include "variable.hpp" // for vconfig, etc
|
||||
#include "variable_info.hpp"
|
||||
#include "wml_exception.hpp"
|
||||
|
@ -4454,69 +4451,6 @@ int game_lua_kernel::intf_toggle_fog(lua_State *L, const bool clear)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int intf_name_generator(lua_State *L)
|
||||
{
|
||||
std::string type = luaL_checkstring(L, 1);
|
||||
name_generator* gen = nullptr;
|
||||
if(type == "markov" || type == "markov_chain") {
|
||||
std::vector<std::string> input;
|
||||
if(lua_istable(L, 2)) {
|
||||
input = lua_check<std::vector<std::string>>(L, 2);
|
||||
} else {
|
||||
input = utils::parenthetical_split(luaL_checkstring(L, 2));
|
||||
}
|
||||
int chain_sz = luaL_optinteger(L, 3, 2);
|
||||
int max_len = luaL_optinteger(L, 4, 12);
|
||||
gen = new(lua_newuserdata(L, sizeof(markov_generator)))
|
||||
markov_generator(input, chain_sz, max_len);
|
||||
// Ensure the pointer didn't change when cast
|
||||
assert(static_cast<void*>(gen) == dynamic_cast<markov_generator*>(gen));
|
||||
} else if(type == "context_free" || type == "cfg" || type == "CFG") {
|
||||
void* buf = lua_newuserdata(L, sizeof(context_free_grammar_generator));
|
||||
if(lua_istable(L, 2)) {
|
||||
std::map<std::string, std::vector<std::string>> data;
|
||||
for(lua_pushnil(L); lua_next(L, 2); lua_pop(L, 1)) {
|
||||
if(!lua_isstring(L, -2)) {
|
||||
lua_pushstring(L, "CFG generator: invalid nonterminal name (must be a string)");
|
||||
return lua_error(L);
|
||||
}
|
||||
if(lua_isstring(L, -1)) {
|
||||
data[lua_tostring(L,-2)] = utils::split(lua_tostring(L,-1),'|');
|
||||
} else if(lua_istable(L, -1)) {
|
||||
data[lua_tostring(L,-2)] = lua_check<std::vector<std::string>>(L, -1);
|
||||
} else {
|
||||
lua_pushstring(L, "CFG generator: invalid noterminal value (must be a string or list of strings)");
|
||||
return lua_error(L);
|
||||
}
|
||||
}
|
||||
if(!data.empty()) {
|
||||
gen = new(buf) context_free_grammar_generator(data);
|
||||
}
|
||||
} else {
|
||||
gen = new(buf) context_free_grammar_generator(luaL_checkstring(L, 2));
|
||||
}
|
||||
if(gen) {
|
||||
assert(static_cast<void*>(gen) == dynamic_cast<context_free_grammar_generator*>(gen));
|
||||
}
|
||||
} else {
|
||||
return luaL_argerror(L, 1, "should be either 'markov_chain' or 'context_free'");
|
||||
}
|
||||
static const char*const generic_err = "error initializing name generator";
|
||||
if(!gen) {
|
||||
lua_pushstring(L, generic_err);
|
||||
return lua_error(L);
|
||||
}
|
||||
// We set the metatable now, even if the generator is invalid, so that it
|
||||
// will be properly collected if it was invalid.
|
||||
luaL_getmetatable(L, "name generator");
|
||||
lua_setmetatable(L, -2);
|
||||
if(!gen->is_valid()) {
|
||||
lua_pushstring(L, generic_err);
|
||||
return lua_error(L);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
// END CALLBACK IMPLEMENTATION
|
||||
|
||||
game_board & game_lua_kernel::board() {
|
||||
|
@ -4586,20 +4520,17 @@ game_lua_kernel::game_lua_kernel(CVideo * video, game_state & gs, play_controlle
|
|||
{ "add_known_unit", &intf_add_known_unit },
|
||||
{ "add_modification", &intf_add_modification },
|
||||
{ "advance_unit", &intf_advance_unit },
|
||||
{ "compile_formula", &lua_formula_bridge::intf_compile_formula},
|
||||
{ "copy_unit", &intf_copy_unit },
|
||||
{ "create_unit", &intf_create_unit },
|
||||
{ "debug", &intf_debug },
|
||||
{ "debug_ai", &intf_debug_ai },
|
||||
{ "eval_conditional", &intf_eval_conditional },
|
||||
{ "eval_formula", &lua_formula_bridge::intf_eval_formula},
|
||||
{ "get_era", &intf_get_era },
|
||||
{ "get_image_size", &intf_get_image_size },
|
||||
{ "get_time_stamp", &intf_get_time_stamp },
|
||||
{ "get_traits", &intf_get_traits },
|
||||
{ "get_viewing_side", &intf_get_viewing_side },
|
||||
{ "modify_ai", &intf_modify_ai },
|
||||
{ "name_generator", &intf_name_generator },
|
||||
{ "set_music", &intf_set_music },
|
||||
{ "transform_unit", &intf_transform_unit },
|
||||
{ "unit_ability", &intf_unit_ability },
|
||||
|
@ -4794,9 +4725,6 @@ game_lua_kernel::game_lua_kernel(CVideo * video, game_state & gs, play_controlle
|
|||
lua_pushstring(L, "unit variables");
|
||||
lua_setfield(L, -2, "__metatable");
|
||||
lua_rawset(L, LUA_REGISTRYINDEX);
|
||||
|
||||
// Create formula bridge metatables
|
||||
cmd_log_ << lua_formula_bridge::register_metatables(L);
|
||||
|
||||
// Create the vconfig metatable.
|
||||
cmd_log_ << lua_common::register_vconfig_metatable(L);
|
||||
|
|
|
@ -292,5 +292,5 @@ std::string lua_formula_bridge::register_metatables(lua_State* L)
|
|||
lua_setfield(L, -2, "__metatable");
|
||||
lua_rawset(L, LUA_REGISTRYINDEX);
|
||||
|
||||
return "Adding formula metatable...";
|
||||
return "Adding formula metatable...\n";
|
||||
}
|
||||
|
|
|
@ -30,14 +30,19 @@
|
|||
#include "scripting/lua_common.hpp"
|
||||
#include "scripting/lua_cpp_function.hpp"
|
||||
#include "scripting/lua_fileops.hpp"
|
||||
#include "scripting/lua_formula_bridge.hpp"
|
||||
#include "scripting/lua_gui2.hpp"
|
||||
#include "scripting/lua_map_location_ops.hpp"
|
||||
#include "scripting/lua_rng.hpp"
|
||||
#include "scripting/lua_types.hpp"
|
||||
#include "scripting/push_check.hpp"
|
||||
|
||||
#include "version.hpp" // for do_version_check, etc
|
||||
|
||||
#include "serialization/string_utils.hpp"
|
||||
#include "utils/functional.hpp"
|
||||
#include "utils/markov_generator.hpp"
|
||||
#include "utils/context_free_grammar_generator.hpp"
|
||||
#include <boost/scoped_ptr.hpp>
|
||||
|
||||
#include <cstring>
|
||||
|
@ -57,6 +62,9 @@ static lg::log_domain log_scripting_lua("scripting/lua");
|
|||
#define WRN_LUA LOG_STREAM(warn, log_scripting_lua)
|
||||
#define ERR_LUA LOG_STREAM(err, log_scripting_lua)
|
||||
|
||||
// Registry key for metatable
|
||||
static const char * Gen = "name generator";
|
||||
|
||||
// Callback implementations
|
||||
|
||||
/**
|
||||
|
@ -160,6 +168,82 @@ int lua_kernel_base::intf_show_lua_console(lua_State *L)
|
|||
return lua_gui2::show_lua_console(L, *video_, this);
|
||||
}
|
||||
|
||||
static int impl_name_generator_call(lua_State *L)
|
||||
{
|
||||
name_generator* gen = static_cast<name_generator*>(lua_touserdata(L, 1));
|
||||
lua_pushstring(L, gen->generate().c_str());
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int impl_name_generator_collect(lua_State *L)
|
||||
{
|
||||
name_generator* gen = static_cast<name_generator*>(lua_touserdata(L, 1));
|
||||
gen->~name_generator();
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int intf_name_generator(lua_State *L)
|
||||
{
|
||||
std::string type = luaL_checkstring(L, 1);
|
||||
name_generator* gen = nullptr;
|
||||
if(type == "markov" || type == "markov_chain") {
|
||||
std::vector<std::string> input;
|
||||
if(lua_istable(L, 2)) {
|
||||
input = lua_check<std::vector<std::string>>(L, 2);
|
||||
} else {
|
||||
input = utils::parenthetical_split(luaL_checkstring(L, 2));
|
||||
}
|
||||
int chain_sz = luaL_optinteger(L, 3, 2);
|
||||
int max_len = luaL_optinteger(L, 4, 12);
|
||||
gen = new(lua_newuserdata(L, sizeof(markov_generator))) markov_generator(input, chain_sz, max_len);
|
||||
// Ensure the pointer didn't change when cast
|
||||
assert(static_cast<void*>(gen) == dynamic_cast<markov_generator*>(gen));
|
||||
} else if(type == "context_free" || type == "cfg" || type == "CFG") {
|
||||
void* buf = lua_newuserdata(L, sizeof(context_free_grammar_generator));
|
||||
if(lua_istable(L, 2)) {
|
||||
std::map<std::string, std::vector<std::string>> data;
|
||||
for(lua_pushnil(L); lua_next(L, 2); lua_pop(L, 1)) {
|
||||
if(!lua_isstring(L, -2)) {
|
||||
lua_pushstring(L, "CFG generator: invalid nonterminal name (must be a string)");
|
||||
return lua_error(L);
|
||||
}
|
||||
if(lua_isstring(L, -1)) {
|
||||
data[lua_tostring(L,-2)] = utils::split(lua_tostring(L,-1),'|');
|
||||
} else if(lua_istable(L, -1)) {
|
||||
data[lua_tostring(L,-2)] = lua_check<std::vector<std::string>>(L, -1);
|
||||
} else {
|
||||
lua_pushstring(L, "CFG generator: invalid noterminal value (must be a string or list of strings)");
|
||||
return lua_error(L);
|
||||
}
|
||||
}
|
||||
if(!data.empty()) {
|
||||
gen = new(buf) context_free_grammar_generator(data);
|
||||
}
|
||||
} else {
|
||||
gen = new(buf) context_free_grammar_generator(luaL_checkstring(L, 2));
|
||||
}
|
||||
if(gen) {
|
||||
assert(static_cast<void*>(gen) == dynamic_cast<context_free_grammar_generator*>(gen));
|
||||
}
|
||||
} else {
|
||||
return luaL_argerror(L, 1, "should be either 'markov_chain' or 'context_free'");
|
||||
}
|
||||
static const char*const generic_err = "error initializing name generator";
|
||||
if(!gen) {
|
||||
lua_pushstring(L, generic_err);
|
||||
return lua_error(L);
|
||||
}
|
||||
// We set the metatable now, even if the generator is invalid, so that it
|
||||
// will be properly collected if it was invalid.
|
||||
luaL_getmetatable(L, Gen);
|
||||
lua_setmetatable(L, -2);
|
||||
if(!gen->is_valid()) {
|
||||
lua_pushstring(L, generic_err);
|
||||
return lua_error(L);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
// End Callback implementations
|
||||
|
||||
// Template which allows to push member functions to the lua kernel base into lua as C functions, using a shim
|
||||
|
@ -283,6 +367,9 @@ lua_kernel_base::lua_kernel_base(CVideo * video)
|
|||
{ "show_message_dialog", &dispatch<&lua_kernel_base::intf_show_message_dialog> },
|
||||
{ "show_popup_dialog", &dispatch<&lua_kernel_base::intf_show_popup_dialog> },
|
||||
{ "show_lua_console", &dispatch<&lua_kernel_base::intf_show_lua_console> },
|
||||
{ "compile_formula", &lua_formula_bridge::intf_compile_formula},
|
||||
{ "eval_formula", &lua_formula_bridge::intf_eval_formula},
|
||||
{ "name_generator", &intf_name_generator },
|
||||
{ nullptr, nullptr }
|
||||
};
|
||||
|
||||
|
@ -349,9 +436,22 @@ lua_kernel_base::lua_kernel_base(CVideo * video)
|
|||
cmd_log_ << "Adding rng tables...\n";
|
||||
lua_rng::load_tables(L);
|
||||
|
||||
cmd_log_ << "Adding name generator metatable...\n";
|
||||
luaL_newmetatable(L, Gen);
|
||||
static luaL_Reg const generator[] = {
|
||||
{ "__call", &impl_name_generator_call},
|
||||
{ "__gc", &impl_name_generator_collect},
|
||||
{ nullptr, nullptr}
|
||||
};
|
||||
luaL_setfuncs(L, generator, 0);
|
||||
|
||||
// Create formula bridge metatables
|
||||
cmd_log_ << lua_formula_bridge::register_metatables(L);
|
||||
|
||||
// Loading ilua:
|
||||
cmd_log_ << "Loading ilua...\n";
|
||||
|
||||
lua_settop(L, 0);
|
||||
lua_pushstring(L, "lua/ilua.lua");
|
||||
int result = intf_require(L);
|
||||
if (result == 1) {
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
#include "units/race.hpp"
|
||||
#include "scripting/lua_common.hpp"
|
||||
#include "units/types.hpp"
|
||||
#include "utils/name_generator.hpp"
|
||||
|
||||
#include <string>
|
||||
#include <string.h>
|
||||
|
@ -92,20 +91,6 @@ static int impl_race_get(lua_State* L)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int impl_name_generator_call(lua_State *L)
|
||||
{
|
||||
name_generator* gen = static_cast<name_generator*>(lua_touserdata(L, 1));
|
||||
lua_pushstring(L, gen->generate().c_str());
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int impl_name_generator_collect(lua_State *L)
|
||||
{
|
||||
name_generator* gen = static_cast<name_generator*>(lua_touserdata(L, 1));
|
||||
gen->~name_generator();
|
||||
return 0;
|
||||
}
|
||||
|
||||
namespace lua_race {
|
||||
|
||||
std::string register_metatable(lua_State * L)
|
||||
|
@ -120,14 +105,6 @@ namespace lua_race {
|
|||
|
||||
lua_pushstring(L, "race");
|
||||
lua_setfield(L, -2, "__metatable");
|
||||
|
||||
luaL_newmetatable(L, Gen);
|
||||
static luaL_Reg const generator[] = {
|
||||
{ "__call", &impl_name_generator_call},
|
||||
{ "__gc", &impl_name_generator_collect},
|
||||
{ nullptr, nullptr}
|
||||
};
|
||||
luaL_setfuncs(L, generator, 0);
|
||||
|
||||
return "Adding getrace metatable...\n";
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue