Модуль:Сущность/data: различия между версиями

мНет описания правки
Нет описания правки
 
(не показано 13 промежуточных версий этого же участника)
Строка 2: Строка 2:
local getArgs = require('Module:Arguments').getArgs
local getArgs = require('Module:Arguments').getArgs
local JsonPaths = require('Module:JsonPaths')
local JsonPaths = require('Module:JsonPaths')
local dp = require( "Module:GetField")


local dpOk, dpModule = pcall(require, "Module:GetField")
local function load_data_page(page)
local dp = dpOk and dpModule or nil
    local moduleName = JsonPaths.get(page)
    local ok, data = pcall(mw.loadData, moduleName)
    if not ok or type(data) ~= "table" then
        return nil
    end
    return data
end


local switchModeRegistry = {}
local switchModeRegistry = {}
Строка 24: Строка 31:
         end
         end
     end
     end
end
local function load_module_data(page)
    local moduleName = JsonPaths.get(page)
    local ok, data = pcall(mw.loadData, moduleName)
    if not ok then
        return nil
    end
    return data
end
end


Строка 47: Строка 45:
end
end


local function lcfirst(s)
function p.loadEntityComponents(entityId)
     if not s or s == "" then return s end
     if not entityId or entityId == "" then
     return string.lower(s:sub(1, 1)) .. (s:sub(2) or "")
        return {}
    end
     local entity = dp.loadEntityData(entityId)
    if entity then
        return dp.collectEntityComponents(entity)
    end
    return {}
end
 
function p.entityHasComponent(entityOrId, compName)
    if not compName or compName == "" then
        return false
    end
 
    local entity
    if type(entityOrId) == "string" then
        entity = dp and dp.loadEntityData(entityOrId) or load_data_page("prototype/Entity/" .. entityOrId .. ".json")
        if not entity then
            return false
        end
    else
        entity = entityOrId
    end
 
    return dp.entityHasComponent(entity, compName)
end
end


Строка 100: Строка 122:
end
end


local function make_source(kind, name, pathName, tplPath)
local function make_source(kind, name, tplPath)
     return { kind = kind, name = name, pathName = pathName, tplPath = tplPath }
     return { kind = kind, name = name, tplPath = tplPath }
end
end


Строка 239: Строка 261:


     return table.concat(out, "\n")
     return table.concat(out, "\n")
end
local function normalizeFilterKey(s)
    s = trim(s or "")
    s = s:gsub("%s*_%s*", "_")
    return s
end
end


Строка 245: Строка 273:
         return false
         return false
     end
     end
    callKey = normalizeFilterKey(callKey)
    compositeKey = normalizeFilterKey(compositeKey)
     return list[callKey] or list[compositeKey] or false
     return list[callKey] or list[compositeKey] or false
end
end
Строка 512: Строка 542:
     if not str or str == "" then return res end
     if not str or str == "" then return res end
     for item in string.gmatch(str, "[^,]+") do
     for item in string.gmatch(str, "[^,]+") do
         local s = trim(item)
         local s = normalizeFilterKey(item)
         if s ~= "" then
         if s ~= "" then
             local a, b = s:match("^([^_]+)_(.+)$")
             local a, b = s:match("^([^_]+)_(.+)$")
Строка 590: Строка 620:
end
end


local function collect_entity_sets(id, componentDefs, prototypeStoreDefs,
local function collect_entity_sets(id, prototypeStoreDefs, componentWhitelist, componentBlacklist, prototypeWhitelist, prototypeBlacklist)
                                  componentWhitelist, componentBlacklist, prototypeWhitelist, prototypeBlacklist)
     local foundComponents, foundPrototypes = {}, {}
     local foundComponents, foundPrototypes = {}, {}


     local compList = componentDefs[id]
     local compList = p.loadEntityComponents(id)
     if type(compList) == "table" then
     if type(compList) == "table" then
         for _, v in ipairs(compList) do
         for _, v in ipairs(compList) do
             if type(v) == "string" then
             if type(v) == "string" and v ~= "" then
                 foundComponents[v] = true
                 foundComponents[v] = true
             end
             end
Строка 603: Строка 632:
     end
     end


     each_csv_value(id, function(name)
     local protoStore = prototypeStoreDefs and prototypeStoreDefs[id]
         if name ~= id then
    if type(protoStore) == "table" then
             if componentDefs[name] ~= nil then
         for protoName in pairs(protoStore) do
                foundComponents[name] = true
             if type(protoName) == "string" and protoName ~= "" then
            elseif prototypeStoreDefs[name] ~= nil then
                 foundPrototypes[protoName] = true
                 foundPrototypes[name] = true
             end
             end
         end
         end
     end)
     end


     apply_entity_set_filters(foundComponents, parse_csv_set(componentWhitelist), parse_csv_set(componentBlacklist))
     apply_entity_set_filters(foundComponents, parse_csv_set(componentWhitelist), parse_csv_set(componentBlacklist))
Строка 697: Строка 725:
end
end


local function each_entity_data(frame, id, onEntity, onMissing)
local function extract_whitelist_search_strings(keyFilter)
    if not keyFilter or not keyFilter.hasWhitelist then
        return nil
    end
 
    local strings = {}
    for sw, keys in pairs(keyFilter.whitelist) do
        if type(keys) == "table" then
            for key in pairs(keys) do
                strings[#strings + 1] = key
            end
        end
    end
 
    if #strings == 0 then
        return nil
    end
 
    return strings
end
 
local function content_matches_whitelist(content, searchStrings)
    if not searchStrings then
        return true
    end
    if not content then
        return false
    end
 
    for _, s in ipairs(searchStrings) do
        if string.find(content, s, 1, true) then
            return true
        end
    end
 
    return false
end
 
local function each_entity_data(frame, id, onEntity, onMissing, keyFilter)
     local componentWhitelist = frame.args.componentWhitelist or frame.args.componentwhitelist or ""
     local componentWhitelist = frame.args.componentWhitelist or frame.args.componentwhitelist or ""
     local componentBlacklist = frame.args.componentBlacklist or frame.args.componentblacklist or ""
     local componentBlacklist = frame.args.componentBlacklist or frame.args.componentblacklist or ""
Строка 703: Строка 769:
     local prototypeBlacklist = frame.args.prototypeBlacklist or frame.args.prototypeblacklist or ""
     local prototypeBlacklist = frame.args.prototypeBlacklist or frame.args.prototypeblacklist or ""


     local componentDefs = load_module_data("component.json")
     local prototypeStoreDefs = dp.loadCachedData("prototype_store.json")
    local prototypeStoreDefs = load_module_data("prototype_store.json")
     if not prototypeStoreDefs then
     if not componentDefs or not prototypeStoreDefs then
         return false
         return false
     end
     end


     local foundComponents, foundPrototypes = collect_entity_sets(id, componentDefs, prototypeStoreDefs,
     local foundComponents, foundPrototypes = collect_entity_sets(id, prototypeStoreDefs,
         componentWhitelist, componentBlacklist, prototypeWhitelist, prototypeBlacklist)
         componentWhitelist, componentBlacklist, prototypeWhitelist, prototypeBlacklist)


     local function processEntity(kind, name, isStore)
     local compWhitelistSet = parse_csv_set(componentWhitelist)
        local pathName = lcfirst(name)
    local compBlacklistSet = parse_csv_set(componentBlacklist)
        local tplPath = kind .. "/" .. pathName
    local protoWhitelistSet = parse_csv_set(prototypeWhitelist)
        if isStore then
    local protoBlacklistSet = parse_csv_set(prototypeBlacklist)
            tplPath = tplPath .. "/store"
 
        end
    local compHasWhitelist = next(compWhitelistSet) ~= nil
    local protoHasWhitelist = next(protoWhitelistSet) ~= nil
    local anyEntityWhitelist = compHasWhitelist or protoHasWhitelist
 
    local whitelistSearchStrings = extract_whitelist_search_strings(keyFilter)
 
local function processEntity(kind, name, isStore)
local tplPath = kind .. "/" .. dp.ucfirst(name)
if isStore then
tplPath = tplPath .. "/store"
end


         local content = load_template_content(tplPath)
         local content = load_template_content(tplPath)
Строка 724: Строка 799:
                 onMissing(kind, name, isStore, tplPath)
                 onMissing(kind, name, isStore, tplPath)
             end
             end
            return
        end
        if not content_matches_whitelist(content, whitelistSearchStrings) then
             return
             return
         end
         end
Строка 735: Строка 814:
         local paramNames = get_template_params(tplPath, content)
         local paramNames = get_template_params(tplPath, content)
         if dp then
         if dp then
             local dataPage = tplPath .. ".json"
             local dataPage = kind .. "/" .. dp.ucfirst(name) .. ".json"
             extra = get_selective_extra(id, dataPage, paramNames)
             extra = get_selective_extra(id, dataPage, paramNames)
         end
         end
Строка 743: Строка 822:
             id = id,
             id = id,
             extra = extra,
             extra = extra,
             source = make_source(kind, name, pathName, tplPath),
             source = make_source(kind, name, tplPath),
             priority = resolve_priority(parsed)
             priority = resolve_priority(parsed)
         })
         })
Строка 749: Строка 828:


     for compName in pairs(foundComponents) do
     for compName in pairs(foundComponents) do
         processEntity("component", compName, false)
         if not anyEntityWhitelist or compHasWhitelist then
            processEntity("component", compName, false)
        end
     end
     end
     for protoName in pairs(foundPrototypes) do
     for protoName in pairs(foundPrototypes) do
         processEntity("prototype", protoName, false)
         if not anyEntityWhitelist or protoHasWhitelist then
            processEntity("prototype", protoName, false)
        end
     end
     end


    local compWhitelistSet = parse_csv_set(componentWhitelist)
     local componentStoreDefs = dp.loadCachedData("component_store.json")
    local compBlacklistSet = parse_csv_set(componentBlacklist)
     if type(componentStoreDefs) == "table" and (not anyEntityWhitelist or compHasWhitelist) then
    local protoWhitelistSet = parse_csv_set(prototypeWhitelist)
    local protoBlacklistSet = parse_csv_set(prototypeBlacklist)
 
    local compHasWhitelist = next(compWhitelistSet) ~= nil
    local protoHasWhitelist = next(protoWhitelistSet) ~= nil
 
     local componentStoreDefs = load_module_data("component_store.json")
     if type(componentStoreDefs) == "table" then
         local compStore = componentStoreDefs[id]
         local compStore = componentStoreDefs[id]
         if type(compStore) == "table" then
         if type(compStore) == "table" then
Строка 781: Строка 856:
     end
     end


     if type(prototypeStoreDefs) == "table" then
     if type(prototypeStoreDefs) == "table" and (not anyEntityWhitelist or protoHasWhitelist) then
         local protoStore = prototypeStoreDefs[id]
         local protoStore = prototypeStoreDefs[id]
         if type(protoStore) == "table" then
         if type(protoStore) == "table" then
Строка 910: Строка 985:
             errors[#errors + 1] = build_missing_template_error(kind, name, isStore, tplPath)
             errors[#errors + 1] = build_missing_template_error(kind, name, isStore, tplPath)
         end
         end
     end)
     end, filter)
     if not ok then return "" end
     if not ok then return "" end


Строка 953: Строка 1028:
         id = "",
         id = "",
         extra = "",
         extra = "",
         source = make_source("", tplPath, tplPath, tplPath),
         source = make_source("", tplPath, tplPath),
         priority = 1
         priority = 1
     }, nil, true)
     }, nil, true)