Editing Module:Test

Jump to navigation Jump to search

Warning: You are not logged in. Your IP address will be publicly visible if you make any edits. If you log in or create an account, your edits will be attributed to your username, along with other benefits.

The edit can be undone. Please check the comparison below to verify that this is what you want to do, and then save the changes below to finish undoing the edit.

Latest revision Your text
Line 1: Line 1:
DefInfo = {}
+
-- redefine the print function to use mw.log
local wiki = {}
+
print = mw.log
  
local function runTime()
+
---------------
  return string.format("%i", os.clock() * 1000)
+
-- load data --
end
+
---------------
 
 
------------------------------------------------------------------
 
-- deal with differences between MediaWiki and dev environments --
 
------------------------------------------------------------------
 
 
 
if mw then
 
  
  log = mw.log
+
-- wiki environment --
  logObject = mw.logObject
 
  
  local timeDataStart = runTime()
+
local Biomes = mw.loadData('Module:Test/data/biomes')
 
+
--local Buildings = mw.loadData('Module:Test/data/buildings')
  Data  = mw.loadData('Module:Test/data')
+
local Races = mw.loadData('Module:Test/data/races')
  
  local timeDataEnd = runTime()
+
-- dev environment --
  log(string.format('@%ims, data loaded in %ims', timeDataEnd, timeDataEnd - timeDataStart))
 
  
  Util  = require("Module:Test/lib/util")
+
--local Biomes = loadfile("./data/BiomeDefs.lua")()
  Search = require("Module:Test/lib/search")
+
--local Buildings = loadfile("./data/ThingDefs_Buildings.lua")()
  VF    = require("Module:Test/data/virtual")
+
--local Races = loadfile("./data/ThingDefs_Races.lua")()
  
  log(string.format('@%ims, modules loaded', runTime()))
+
-- aggregate the categories --
  
else
+
local data = {}
 +
data["Biomes"] = Biomes
 +
--data["Buildings"] = Buildings
 +
data["Races"] = Races
  
  logDevStore = {}
+
------------------------
 +
-- pretty print table --
 +
------------------------
  
  log = function(str)
+
--[[ procedure: tprint ]]--
    table.insert(logDevStore, str)
 
  end
 
  
  logObject = function(obj, prefix)
+
function tprint (tbl, indent)
    if prefix then
+
  if not indent then indent = 0 end
      assert(type(prefix) == "string")
+
  for k, v in pairs(tbl) do
       table.insert(logDevStore, prefix .. " = " .. Inspect(obj))
+
    formatting = string.rep("  ", indent) .. k .. ": "
 +
    if type(v) == "table" then
 +
      print(formatting)
 +
       tprint(v, indent+1)
 +
    elseif type(v) == 'boolean' then
 +
      print(formatting .. tostring(v))
 
     else
 
     else
       table.insert(logDevStore, Inspect(obj))
+
       print(formatting .. v)
 
     end
 
     end
 
   end
 
   end
 +
end
  
  function pp(tbl, title) -- pretty print tables
+
--[[ function: shallowcopy ]]--
    Util.hl(title)
 
    print(Inspect(tbl))
 
  end
 
  
  local timeDataStart = runTime()
+
function shallowcopy(original_table)
 +
    local orig_type = type(original_table)
 +
    local copy
 +
    if orig_type == 'table' then
 +
        copy = {}
 +
        for orig_key, orig_value in pairs(original_table) do
 +
            copy[orig_key] = orig_value
 +
        end
 +
    else -- number, string, boolean, etc
 +
        copy = original_table
 +
    end
 +
    return copy
 +
end
  
  Data    = require "data/data"
+
--[[ function: reverse_numeric_table ]]--
  
  local timeDataEnd = runTime()
+
function reverse_numeric_table(tbl)
  log(string.format('@%ims, data loaded in %ims', timeDataEnd, timeDataEnd - timeDataStart))
+
    local reversed_table = {}
 +
    local length = #tbl
 +
    for i,v in ipairs(tbl) do
 +
        reversed_table[length + 1 - i] = v
 +
    end
 +
    return reversed_table
 +
end
  
  Util    = require "lib/util"
+
-----------------------------
  Search  = require "lib/search"
+
-- small utility functions --
  Inspect = require "lib/inspect"
+
-----------------------------
  VF      = require "data/virtual"
 
 
 
  log(string.format('@%ims, modules loaded', runTime()))
 
  
 +
--[[ function: find_key_name_of_value ]]--
 +
local function find_key_name_of_value(value, tbl)
 +
  for k,v in pairs(tbl) do
 +
    if v == value then return k end
 +
  end
 
end
 
end
  
-----------------------
+
--[[ function: search_table_recursive ]]--
-- private functions --
 
-----------------------
 
 
 
function DefInfo.vardefine(name, value, frame)
 
  assert(name, "vardefine: missing argument #1 (variable to definePrefix)")
 
  assert(type(name) == "string", string.format("vardefine: bad argument #1 (string expected, got %s)", type(name)))
 
  assert(value, "vardefine: missing argument #2 (value to assign)")
 
  assert(type(value) == "string" or type(value) == "number" or type(value) =="boolean", string.format("vardefine: bad argument #2 (string, number or boolean expected, got %s)", type(value)))
 
  assert(frame, "vardefine: 'frame' missing")
 
  frame:callParserFunction('#vardefine', name, value)
 
end
 
  
function DefInfo.expandDef(def, runMe)
+
-- returns the value found by first occurrence of a key within a table (recursive)
  if not runMe then return nil end
+
local function search_table_recursive(key, tbl)
  local vFuncs = VF
+
   for k, v in pairs(tbl) do
   for fName,func in pairs(vFuncs) do
+
     if k == key then return v
     if func(def) then
+
    elseif type(v) == "table" then
       log(string.format('@%ims, expandDef: %s expanded with %s', runTime(), def.defName, fName))
+
       local found = search_table_recursive(key, v)
 +
      if found then return found end
 
     end
 
     end
 
   end
 
   end
 
end
 
end
  
function DefInfo.mergeParents(baseDef, ignoreKeys)
+
--[[ function: find_parent_table ]]--
  local ancestorIDs = {}
 
  local mergedDef = {}
 
  local def = baseDef
 
  
   while def._.ParentName do
+
-- returns the parent table of an element specified by key, value (recursive)
     local parentID = def._.DefCategory .. ":" .. def._.ParentName
+
local function find_parent_table(key, value, tbl)
    table.insert(ancestorIDs, parentID)
+
   for k, v in pairs(tbl) do
     def = Data[parentID]
+
     if k == key and v == value then return tbl
 +
    elseif type(v) == "table" then
 +
      local found = find_parent_table(key, value, v)
 +
      if found then return found end
 +
     end
 
   end
 
   end
 +
end
  
  ancestorIDs = Util.table.reverse(ancestorIDs)
+
--[[ procedure: vardefine ]]--
  table.insert(ancestorIDs, baseDef._.DefCategory .. ":" .. baseDef.defName)
 
  
   for _,parentID in ipairs(ancestorIDs) do
+
local function vardefine(var_name, var_value)
    Util.table.overwrite(mergedDef, Data[parentID], ignoreKeys)
+
   local fName = debug.getinfo(1,"n").name
   end
+
  assert(var_name, string.format("bad argument #1 to '%s' (argument missing, name of variable to define)", fName))
 +
  assert(var_name == "string", string.format("bad argument #1 to '%s' (string expected, got %s)", fName, type(var_name)))
 +
  assert(var_value, string.format("bad argument #2 to '%s' (argument missing, value to assign to variable)", fName))
 +
   assert(var_value == "string" or var_value == "number", string.format("bad argument #2 to '%s' (string or number expected, got %s)", fName, type(var_value)))
  
   return mergedDef
+
   frame:callParserFunction('#vardefine', var_name, var_value)
 
end
 
end
  
function DefInfo.getDef(defID, expandVF)
+
--[[ procedure: overwrite_first_table_with_second ]]--
   if expandVF ~= false then expandVF = true end
+
 
 +
local function overwrite_first_table_with_second(first_table, second_table, ignore_keys)
 +
   ignore_keys = ignore_keys or {}
  
   local ignoreKeys = {"Abstract", "Name", "ParentName"}
+
   for k,v in pairs(second_table) do
  local baseDef
+
    local ignore = false
  local def
 
  
  if not defID then return nil end
+
    for _, ignored_key in ipairs(ignore_keys) do
 +
      if k == ignored_key then ignore = true end
 +
    end
  
  for _,def in pairs(Data) do
+
    if not ignore then
    if def.defName == defID then
+
      if type(v) == "table" then
      baseDef = def
+
        if type(first_table[k]) == "table" then
      break
+
          overwrite_first_table_with_second(first_table[k], v)
    elseif string.upper(def.label or '') == string.upper(defID) then
+
        else
       baseDef = def
+
          first_table[k] = {}
       break
+
          overwrite_first_table_with_second(first_table[k], v)
 +
        end
 +
       else
 +
        first_table[k] = v
 +
       end
 
     end
 
     end
 
   end
 
   end
 +
end
  
  if not baseDef then return nil end
+
----------------------
 +
-- dataset specific --
 +
----------------------
  
  def = DefInfo.mergeParents(baseDef, ignoreKeys)
+
--[[ function: find_def_table ]]--
  
  DefInfo.expandDef(def, expandVF)
+
local function find_def_table(def)
 
+
   -- hidden variables: data
  return def
+
   for k1,v1 in pairs(data) do
end
+
     if type(v1) == "table" then
 
+
       for k2,v2 in pairs(v1) do
local function setPrefix(tbl, parentKey)
+
        if k2 == def then return v2 end
   local mt = getmetatable(tbl) or {}
+
       end
 
 
   for k,v in pairs(tbl) do
 
    local prefix = parentKey .. "_" .. k
 
     if type(v) == 'table' then
 
       setPrefix(v, prefix)
 
    else
 
       mt[k] = prefix
 
 
     end
 
     end
 
   end
 
   end
 
  setmetatable(tbl, mt)
 
 
end
 
end
  
local function definePrefixed(tbl, frame)
+
local function find_def_category_table(def)
   for k,v in pairs(tbl) do
+
   for k1,v1 in pairs(data) do
     if type(v) ~= 'table' then
+
     if type(v1) == "table" then
       local mt = getmetatable(tbl)
+
       for k2,v2 in pairs(v1) do
      log(string.format('%s = %s', mt[k], tostring(v)))
+
        if k2 == def then return v1 end
      if mw then DefInfo.vardefine(mt[k], v, frame) end
+
       end
    else
 
       definePrefixed(v, frame)
 
 
     end
 
     end
 
   end
 
   end
 
end
 
end
  
----------------------
+
--[[ function: merge_def_with_parents ]]--
-- public interface --
+
 
----------------------
+
local function merge_def_with_parents(def, ignore_keys)
 +
  -- hidden variables: ParentName and global data
 +
 
 +
  local def_table = find_def_table(def)
 +
  local def_category_table = find_def_category_table(def)
 +
  local parent_names = {}
 +
  local parent_name = def_table["ParentName"]
 +
  local parent_table = def_category_table[parent_name]
  
function wiki.count(frame)
+
  while parent_name do
  local query = wiki.query(frame)
+
    table.insert(parent_names, parent_name)
  if type(wiki.queried) == 'table' then -- WARNING: checks a variable that is set in wiki.query (ugly)
+
    parent_name = parent_table["ParentName"]
     return Util.table.count(wiki.queried)
+
     parent_table = def_category_table[parent_name]
 
   end
 
   end
end
 
 
function wiki.query(frame)
 
  
   local argLen = Util.table.count(frame.args, "number") -- #frame.args won't work as expected, check the doc
+
   local inheritance_chain = shallowcopy(reverse_numeric_table(parent_names))
 +
  table.insert(inheritance_chain, def)
  
   if not frame.args['defName'] and not frame.args['label'] then
+
   local merged = {}
     logObject(frame.args, string.format('query @ %ims: missing an identifying argument (defName or label)\nframe.args', runTime()))
+
  local chain_length = #inheritance_chain
    return nil
+
  for i,v in ipairs(inheritance_chain) do
 +
     overwrite_first_table_with_second(merged, def_category_table[inheritance_chain[i]], ignore_keys)
 
   end
 
   end
  
   local def = DefInfo.getDef(frame.args['defName']) or DefInfo.getDef(frame.args['label'])
+
   return merged
 +
end
  
  if not def then
+
--------------------------------
    logObject(frame.args, string.format("query @ %ims: Def not found\nframe.args", runTime()))
+
-- publicly exposed functions --
    return nil
+
--------------------------------
  end
 
  
  if def and argLen == 0 then
+
local p = {}
    logObject(def, string.format("['%s:%s'] @ %ims", def._.DefCategory, def.defName, runTime()))
 
    return nil
 
  end
 
  
   local processedDef = def
+
function p.query(frame)
 +
   local fName = debug.getinfo(1,"n").name
  
   for i,arg in ipairs(frame.args) do -- arguments
+
   if not (frame.args["defName"] or frame.args["label"]) then
     arg = tonumber(arg) or arg -- frame.args are always strings on MediaWiki so convert back the numbers
+
     assert(frame.args["defName"], string.format("bad argument to '%s' (missing named argument 'defName' or 'label' needed to find a Def)", fName))
 +
  end
  
    if i == argLen and frame.args["sibling"] then
+
  local def_table
      processedDef = Search.find({nil, frame.args["sibling"]} , processedDef)
+
  if frame.args["defName"] then
      if not processedDef then
+
    def_table = find_def_table(frame.args["defName"])
        logObject(frame.args, string.format("query @ %ims: bad argument 'sibling' ('%s' not found')\nframe.args", runTime(), frame.args["sibling"]))
+
    if def_table then
        return nil
+
      def_table = merge_def_with_parents(frame.args["defName"], {"ParentName", "Abstract"})
      else
 
        processedDef = Search.meta.parent.table[arg]
 
        if not processedDef then
 
          logObject(frame.args, string.format("query @ %ims: bad argument #%i ('%s' is not a sibling of '%s')", runTime(), i, arg, frame.args["sibling"]))
 
          return nil
 
        end
 
      end
 
 
     end
 
     end
 
+
  end
     if i < argLen or i == argLen and not frame.args["sibling"] then
+
  if not def_table then
      processedDef = Search.find(arg, processedDef)
+
     def_table = find_parent_table(find_key_name_of_value(frame.args["label"], frame.args), frame.args["label"], data["Races"])
      if not processedDef then
+
    if def_table then
        logObject(frame.args, string.format("query @ %ims: bad argument #%i ('%s' not found)\nframe.args", runTime(), i, frame.args[i]))
+
       def_table = merge_def_with_parents(def_table["defName"], {"ParentName", "Abstract"})
        return nil
 
       else
 
        if type(processedDef) ~= 'table' and i < argLen then
 
          log(string.format("query @ %ims: warning Def ['%s'] argument #%i ('%s' returns a value, all extra arguments ignored)", runTime(), def['label'], i, frame.args[i]))
 
          return processedDef
 
        end
 
      end
 
 
     end
 
     end
 +
  end
  
   end -- for arguments
+
   assert(def_table, "Def not found")
  
   if type(processedDef) == "table" then
+
   -- if there are no numeric arguments, output the def to log
    log(string.format("@%ims, query: table vardefined", runTime()))
+
  local args_length = #frame.args
    setPrefix(processedDef, frame.args[argLen])
+
  if args_length == 0 then
    definePrefixed(processedDef, frame)
+
     tprint(def_table)
     wiki.queried = processedDef -- WARNING: sets a variable that is used in another function wiki.count (ugly)
 
    return nil
 
 
   end
 
   end
  
   log(string.format("@%ims, query: %s printed", runTime(), type(processedDef)))
+
   -- get filtered data based on numeric arguments
   return processedDef
+
  local filtered = def_table
end
+
  for i,v in ipairs(frame.args) do
 
+
    filtered = search_table_recursive(v, filtered)
------------------------------------
+
    if type(filtered) == "string" or type(filtered) == "number" and i < args_length then
-- simulate MediaWiki environment --
+
      error(string.format("too many numeric arguments to '%s' (string, number or boolean already found)", fName), 0)
------------------------------------
+
    end
 +
   end
  
if not mw then
+
   return filtered
   local simframe = { ["args"] = {} }
 
  simframe.args['label'] = 'ancient cryptosleep casket'
 
--~  simframe.args[1] = 'verbs'
 
--~  simframe.args[2] = 'label'
 
  wiki.query(simframe)
 
 
end
 
end
  
if not mw then
+
-------------
  Util.hl("DefInfo log")
+
-- logging --
  for _,v in ipairs(logDevStore) do
+
-------------
    print(v)
 
  end
 
end
 
  
------------
+
--mw.log("Module:DefInfo:os.clock() " .. os.clock()*1000 .. " ms")
-- return --
+
print("Module:DefInfo:os.clock() " .. os.clock()*1000 .. " ms")
------------
 
  
if mw then
+
return p
  return wiki
 
else
 
  return DefInfo
 
end
 

Please note that all contributions to RimWorld Wiki are considered to be released under the CC BY-SA 3.0 (see RimWorld Wiki:Copyrights for details). If you do not want your writing to be edited mercilessly and redistributed at will, then do not submit it here.
You are also promising us that you wrote this yourself, or copied it from a public domain or similar free resource. Do not submit copyrighted work without permission!

Cancel Editing help (opens in new window)