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

Нет описания правки
Отмена версии 315901, сделанной Pok (обсуждение)
Метка: отмена
 
(не показано 6 промежуточных версий этого же участника)
Строка 6: Строка 6:
local dp = dpOk and dpModule or nil
local dp = dpOk and dpModule or nil


local moduleDataCache = {}
local templateContentCache = {}
local templateMetaCache = {}
local templateArgCache = {}
local flattenExtraCache = {}
local switchModeRegistry = {}
local switchModeRegistry = {}
local switchModeOrder = {}
local switchModeOrder = {}
Строка 33: Строка 28:
local function load_module_data(page)
local function load_module_data(page)
     local moduleName = JsonPaths.get(page)
     local moduleName = JsonPaths.get(page)
    if moduleDataCache[moduleName] ~= nil then
        return moduleDataCache[moduleName]
    end
     local ok, data = pcall(mw.loadData, moduleName)
     local ok, data = pcall(mw.loadData, moduleName)
     if not ok then
     if not ok then
        moduleDataCache[moduleName] = nil
         return nil
         return nil
     end
     end
    moduleDataCache[moduleName] = data
     return data
     return data
end
end


local function load_template_content(path)
local function load_template_content(path)
    if templateContentCache[path] ~= nil then
        return templateContentCache[path] or nil
    end
     local title = mw.title.new("Template:" .. path)
     local title = mw.title.new("Template:" .. path)
     if not title then
     if not title then
        templateContentCache[path] = false
         return nil
         return nil
     end
     end
     local ok, content = pcall(title.getContent, title)
     local ok, content = pcall(title.getContent, title)
     if not ok then
     if not ok then
        templateContentCache[path] = false
         return nil
         return nil
     end
     end
    templateContentCache[path] = content or false
     return content
     return content
end
end
Строка 111: Строка 90:


local function get_template_params(tplPath, content)
local function get_template_params(tplPath, content)
     local cached = templateArgCache[tplPath]
     return collect_template_params(content)
    if cached ~= nil then
        return cached
    end
 
    local params = collect_template_params(content)
    templateArgCache[tplPath] = params
    return params
end
end


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


     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


Строка 273: Строка 251:
         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
Строка 507: Строка 487:


local function getTemplateMeta(frame, tplPath)
local function getTemplateMeta(frame, tplPath)
    if templateMetaCache[tplPath] ~= nil then
        return templateMetaCache[tplPath] or ""
    end
     local expanded = frame:expandTemplate {
     local expanded = frame:expandTemplate {
         title = tplPath,
         title = tplPath,
Строка 518: Строка 494:
     local ok, data = pcall(mw.text.jsonDecode, expanded)
     local ok, data = pcall(mw.text.jsonDecode, expanded)
     if not ok or type(data) ~= "table" then
     if not ok or type(data) ~= "table" then
        templateMetaCache[tplPath] = false
         return ""
         return ""
     end
     end
Строка 538: Строка 513:
     end
     end


    templateMetaCache[tplPath] = data
     return data
     return data
end
end
Строка 546: Строка 520:
     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("^([^_]+)_(.+)$")
Строка 676: Строка 650:
     end
     end


     local cacheKey = dataPage .. "\31" .. id .. "\31" .. table.concat(paramNames, "\30")
     return dp.flattenFieldSelectiveDirect(id, dataPage, paramNames) or ""
    if flattenExtraCache[cacheKey] ~= nil then
        return flattenExtraCache[cacheKey]
    end
 
    local extra = dp.flattenFieldSelectiveDirect(id, dataPage, paramNames) or ""
    flattenExtraCache[cacheKey] = extra
    return extra
end
end


Строка 738: Строка 705:
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 ""
Строка 752: Строка 757:
     local foundComponents, foundPrototypes = collect_entity_sets(id, componentDefs, prototypeStoreDefs,
     local foundComponents, foundPrototypes = collect_entity_sets(id, componentDefs, prototypeStoreDefs,
         componentWhitelist, componentBlacklist, prototypeWhitelist, prototypeBlacklist)
         componentWhitelist, componentBlacklist, prototypeWhitelist, prototypeBlacklist)
    local compWhitelistSet = parse_csv_set(componentWhitelist)
    local compBlacklistSet = parse_csv_set(componentBlacklist)
    local protoWhitelistSet = parse_csv_set(prototypeWhitelist)
    local protoBlacklistSet = parse_csv_set(prototypeBlacklist)
    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 function processEntity(kind, name, isStore)
Строка 765: Строка 781:
                 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
Строка 790: Строка 810:


     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 componentStoreDefs = load_module_data("component_store.json")
     local componentStoreDefs = load_module_data("component_store.json")
     if type(componentStoreDefs) == "table" then
     if type(componentStoreDefs) == "table" and (not anyEntityWhitelist or compHasWhitelist) then
         local compStore = componentStoreDefs[id]
         local compStore = componentStoreDefs[id]
         if type(compStore) == "table" then
         if type(compStore) == "table" then
             for compName in pairs(compStore) do
             for compName in pairs(compStore) do
                 processEntity("component", compName, true)
                 local allowed = true
                if compBlacklistSet[compName] then
                    allowed = false
                elseif compHasWhitelist and not compWhitelistSet[compName] then
                    allowed = false
                end
                if allowed then
                    processEntity("component", compName, true)
                end
             end
             end
         end
         end
     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
             for protoName in pairs(protoStore) do
             for protoName in pairs(protoStore) do
                 processEntity("prototype", protoName, true)
                 local allowed = true
                if protoBlacklistSet[protoName] then
                    allowed = false
                elseif protoHasWhitelist and not protoWhitelistSet[protoName] then
                    allowed = false
                end
                if allowed then
                    processEntity("prototype", protoName, true)
                end
             end
             end
         end
         end
Строка 927: Строка 967:
             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