Lua: Add a few more useful functions to the WML module and make WML table conversion a little more robust
- New functions: wml.find_child, wml.attribute_count, wml.equal, wml.valid - When converting a Lua table to WML, the engine will no longer accept invalid attributes - Use of wml.tovconfig in plugin or map generation scripts is deprecated (it already doesn't quite work properly in those contexts but still could've been used as a way to test a table's validity as WML)
This commit is contained in:
parent
680e7741ff
commit
86f66a5825
4 changed files with 84 additions and 3 deletions
|
@ -21,7 +21,7 @@ end
|
|||
|
||||
local function ensure_config(cfg)
|
||||
if type(cfg) == 'table' then
|
||||
return true
|
||||
return wml.valid(cfg)
|
||||
end
|
||||
if type(cfg) == 'userdata' then
|
||||
if getmetatable(cfg) == 'wml object' then return true end
|
||||
|
@ -35,6 +35,7 @@ end
|
|||
--! Returns the first subtag of @a cfg with the given @a name.
|
||||
--! If @a id is not nil, the "id" attribute of the subtag has to match too.
|
||||
--! The function also returns the index of the subtag in the array.
|
||||
--! Returns nil if no matching subtag is found
|
||||
function wml.get_child(cfg, name, id)
|
||||
ensure_config(cfg)
|
||||
for i,v in ipairs(cfg) do
|
||||
|
@ -48,6 +49,7 @@ end
|
|||
--! Returns the nth subtag of @a cfg with the given @a name.
|
||||
--! (Indices start at 1, as always with Lua.)
|
||||
--! The function also returns the index of the subtag in the array.
|
||||
--! Returns nil if no matching subtag is found
|
||||
function wml.get_nth_child(cfg, name, n)
|
||||
ensure_config(cfg)
|
||||
for i,v in ipairs(cfg) do
|
||||
|
@ -58,6 +60,36 @@ function wml.get_nth_child(cfg, name, n)
|
|||
end
|
||||
end
|
||||
|
||||
--! Returns the first subtag of @a cfg with the given @a name that matches the @a filter.
|
||||
--! If @a name is omitted, any subtag can match regardless of its name.
|
||||
--! The function also returns the index of the subtag in the array.
|
||||
--! Returns nil if no matching subtag is found
|
||||
function wml.find_child(cfg, name, filter)
|
||||
ensure_config(cfg)
|
||||
if filter == nil then
|
||||
filter = name
|
||||
name = nil
|
||||
end
|
||||
for i,v in ipairs(cfg) do
|
||||
if name == nil or v[1] == name then
|
||||
local w = v[2]
|
||||
if wml.matches_filter(w, filter) then return w, i end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--! Returns the number of attributes of the config
|
||||
function wml.attribute_count(cfg)
|
||||
ensure_config(cfg)
|
||||
local count = 0
|
||||
for k,v in pairs(cfg) do
|
||||
if type(k) == 'string' then
|
||||
count = count + 1
|
||||
end
|
||||
end
|
||||
return count
|
||||
end
|
||||
|
||||
--! Returns the number of subtags of @a with the given @a name.
|
||||
function wml.child_count(cfg, name)
|
||||
ensure_config(cfg)
|
||||
|
@ -130,6 +162,8 @@ wml.tag = setmetatable({}, create_tag_mt)
|
|||
|
||||
--[========[Config / Vconfig Unified Handling]========]
|
||||
|
||||
-- These are slated to be moved to game kernel only
|
||||
|
||||
function wml.literal(cfg)
|
||||
if type(cfg) == "userdata" then
|
||||
return cfg.__literal
|
||||
|
@ -562,6 +596,28 @@ if wesnoth.kernel_type() == "Game Lua Kernel" then
|
|||
if type(side) == 'number' then side = wesnoth.sides[side] end
|
||||
return side.starting_location
|
||||
end
|
||||
else
|
||||
--[========[Backwards compatibility for wml.tovconfig]========]
|
||||
local fake_vconfig_mt = {
|
||||
__index = function(self, key)
|
||||
if key == '__literal' or key == '__parsed' or key == '__shallow_literal' or key == '__shallow_parsed' then
|
||||
return self
|
||||
end
|
||||
return self[key]
|
||||
end
|
||||
}
|
||||
|
||||
local function tovconfig_fake(cfg)
|
||||
ensure_config(cfg)
|
||||
return setmetatable(cfg, fake_vconfig_mt)
|
||||
end
|
||||
|
||||
wesnoth.tovconfig = wesnoth.deprecate_api('wesnoth.tovconfig', 'wml.valid', 1, null, tovconfig_fake, 'tovconfig is now deprecated in plugin or map generation contexts; if you need to check whether a table is valid as a WML object, use wml.valid instead.')
|
||||
wml.tovconfig = wesnoth.deprecate_api('wml.tovconfig', 'wml.valid', 1, null, tovconfig_fake, 'tovconfig is now deprecated in plugin or map generation contexts; if you need to check whether a table is valid as a WML object, use wml.valid instead.')
|
||||
wml.literal = wesnoth.deprecate_api('wml.literal', '(no replacement)', 1, null, wml.literal, 'Since vconfigs are not supported outside of the game kernel, this function is redundant and will be removed from plugin and map generation contexts. It will continue to work in the game kernel.')
|
||||
wml.parsed = wesnoth.deprecate_api('wml.parsed', '(no replacement)', 1, null, wml.parsed, 'Since vconfigs are not supported outside of the game kernel, this function is redundant and will be removed from plugin and map generation contexts. It will continue to work in the game kernel.')
|
||||
wml.shallow_literal = wesnoth.deprecate_api('wml.shallow_literal', '(no replacement)', 1, null, wml.shallow_literal, 'Since vconfigs are not supported outside of the game kernel, this function is redundant and will be removed from plugin and map generation contexts. It will continue to work in the game kernel.')
|
||||
wml.shallow_parsed = wesnoth.deprecate_api('wml.shallow_parsed', '(no replacement)', 1, null, wml.shallow_parsed, 'Since vconfigs are not supported outside of the game kernel, this function is redundant and will be removed from plugin and map generation contexts. It will continue to work in the game kernel.')
|
||||
end
|
||||
|
||||
--[========[GUI2 Dialog Manipulations]========]
|
||||
|
|
|
@ -4296,6 +4296,12 @@ game_lua_kernel::game_lua_kernel(game_state & gs, play_controller & pc, reports
|
|||
lua_setfield(L, -2, "current");
|
||||
lua_pop(L, 1);
|
||||
|
||||
// Add tovconfig to the WML module
|
||||
lua_getglobal(L, "wml");
|
||||
lua_pushcfunction(L, &lua_common::intf_tovconfig);
|
||||
lua_setfield(L, -2, "tovconfig");
|
||||
lua_pop(L, 1);
|
||||
|
||||
// Create the units module
|
||||
cmd_log_ << "Adding units module...\n";
|
||||
static luaL_Reg const unit_callbacks[] {
|
||||
|
|
|
@ -781,7 +781,9 @@ bool luaW_toconfig(lua_State *L, int index, config &cfg)
|
|||
int indextype = lua_type(L, -2);
|
||||
if (indextype == LUA_TNUMBER) continue;
|
||||
if (indextype != LUA_TSTRING) return_misformed();
|
||||
config::attribute_value &v = cfg[lua_tostring(L, -2)];
|
||||
const char* m = lua_tostring(L, -2);
|
||||
if(!m || !config::valid_attribute(m)) return_misformed();
|
||||
config::attribute_value &v = cfg[m];
|
||||
if (lua_istable(L, -1)) {
|
||||
int subindex = lua_absindex(L, -1);
|
||||
std::ostringstream str;
|
||||
|
|
|
@ -329,6 +329,22 @@ static int intf_wml_patch(lua_State* L) {
|
|||
return 1;
|
||||
}
|
||||
|
||||
static int intf_wml_equal(lua_State* L) {
|
||||
config left = luaW_checkconfig(L, 1);
|
||||
config right = luaW_checkconfig(L, 2);
|
||||
lua_pushboolean(L, left == right);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int intf_wml_valid(lua_State* L) {
|
||||
config test;
|
||||
if(luaW_toconfig(L, 1, test)) {
|
||||
// The validate_wml call is PROBABLY redundant, but included just in case validation changes and toconfig isn't updated to match
|
||||
lua_pushboolean(L, test.validate_wml());
|
||||
} else lua_pushboolean(L, false);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Logs a message
|
||||
* Arg 1: (optional) Logger
|
||||
|
@ -668,9 +684,10 @@ lua_kernel_base::lua_kernel_base()
|
|||
{ "merge", &intf_wml_merge},
|
||||
{ "diff", &intf_wml_diff},
|
||||
{ "patch", &intf_wml_patch},
|
||||
{ "equal", &intf_wml_equal},
|
||||
{ "valid", &intf_wml_valid},
|
||||
{ "matches_filter", &intf_wml_matches_filter},
|
||||
{ "tostring", &intf_wml_tostring},
|
||||
{ "tovconfig", &lua_common::intf_tovconfig},
|
||||
{ nullptr, nullptr },
|
||||
};
|
||||
lua_newtable(L);
|
||||
|
|
Loading…
Add table
Reference in a new issue