Difference between revisions of "Module:DefInfo"

From RimWorld Wiki
Jump to navigation Jump to search
(beta, slightly leaning towards alpha (there will be insects))
m (Blanked the page)
Tag: Blanking
 
Line 1: Line 1:
----------------------------------------------
 
-- deal with differences in the environment --
 
----------------------------------------------
 
  
if mw then
 
  ENV = "wiki"
 
  log = mw.log
 
 
  util = require("Module:Test/lib/util")
 
  search = require("Module:Test/lib/search")
 
else
 
  ENV = "dev"
 
 
  mw = {}
 
  log = {}
 
 
  inspect = require './lib/inspect'
 
  util = require("./lib/util")
 
  search = require("./lib/search")
 
 
  function pinspect(tbl, title)
 
    util.hl(title)
 
    print(inspect(tbl))
 
  end
 
 
  -- define used mw functions that don't exist in dev environment
 
  mw.logObject = function(obj, prefix)
 
    if prefix then
 
      assert(type(prefix) == "string")
 
      table.insert(log, prefix .. " = " .. inspect(obj))
 
    else
 
      table.insert(log, inspect(obj))
 
    end
 
  end
 
 
  mw.dumpObject = function(arg)
 
    return inspect(arg)
 
  end
 
 
  mw.log = function(arg)
 
    table.insert(log, arg)
 
  end
 
end
 
 
---------------
 
-- load data --
 
---------------
 
 
data = {}
 
 
if ENV == "dev" then
 
  data["Biomes"] = loadfile("./data/BiomeDefs.lua")()
 
  data["Races"] = loadfile("./data/ThingDefs_Races.lua")()
 
elseif ENV == "wiki" then
 
  data["Biomes"] = mw.loadData('Module:Test/data/biomes')
 
  data["Races"] = mw.loadData('Module:Test/data/races')
 
end
 
 
------------------
 
-- virtual keys --
 
------------------
 
 
-- this could be implemented with metatable events
 
-- they get added in get(id_pair)
 
 
local virtual_keys = {
 
  ["Races"] = {
 
    ["lives_in"] = function (race, biomes)
 
      local list = {}
 
      for biome_key, biome in pairs(biomes) do
 
        for _,animal in ipairs(biome.wildAnimals) do
 
          if race.defName == animal then
 
            table.insert(list, biome_key)
 
          end
 
        end
 
      end
 
      return list
 
    end
 
  }
 
}
 
 
-------------
 
-- private --
 
-------------
 
 
local function vardefine(name, value)
 
  local f_name = "vardefine"
 
  assert(var_name, string.format("bad argument #1 to '%s' (argument missing, name of variable to define)", f_name))
 
  assert(var_name == "string", string.format("bad argument #1 to '%s' (string expected, got %s)", f_name, type(var_name)))
 
  assert(var_value, string.format("bad argument #2 to '%s' (argument missing, value to assign to variable)", f_name))
 
  assert(var_value == "string" or var_value == "number", string.format("bad argument #2 to '%s' (string or number expected, got %s)", f_name, type(var_value)))
 
 
  frame:callParserFunction('#vardefine', var_name, var_value)
 
end
 
 
 
local function search_parent_def_table(key, def_table)
 
  local ParentName = getParentName(def_table)
 
  if not ParentName then return nil end
 
  local parentdef_table = search_table_recursive(ParentName, data)
 
  if not parentdef_table then return nil end
 
 
  local found = search_table_recursive(key, parentdef_table)
 
  if found then return found
 
  else
 
    found = search_parent_def_table(key, parentdef_table)
 
    if found then return found end
 
  end
 
end
 
 
 
local function merge_def(base_def_table, def_category, ignore_keys)
 
 
  local ancestors = {}
 
  local parent_name = base_def_table["ParentName"]
 
  local parent_table = data[def_category][parent_name]
 
 
  while parent_name do
 
    table.insert(ancestors, parent_name)
 
    parent_name = parent_table["ParentName"]
 
    parent_table = data[def_category][parent_name]
 
  end
 
 
  local inheritance_chain = util.shallowcopy(util.reverse_numeric_table(ancestors))
 
  table.insert(inheritance_chain, base_def_table.defName)
 
 
  local merged = {}
 
  for i,v in ipairs(inheritance_chain) do
 
    util.overwrite_first_table_with_second(merged, data[def_category][inheritance_chain[i]], ignore_keys)
 
  end
 
 
  return merged
 
end
 
 
 
function get_def(defName)
 
  local base_def_table
 
  local def_category
 
 
  for catK,_ in pairs(data) do
 
    for defK,def in pairs(data[catK]) do
 
      if defK == defName then
 
        base_def_table = def
 
        def_category = catK
 
      end
 
    end
 
  end
 
 
  if not base_def_table then return nil end
 
 
  local def = merge_def(base_def_table, def_category, {"ParentName", "Abstract"})
 
 
  -- add virtual keys
 
  if virtual_keys[def_category] then
 
    def._virtual = {}
 
    for k,func in pairs(virtual_keys[def_category]) do
 
      def._virtual[k] = func(def, data.Biomes)
 
    end
 
  end
 
 
--~  mw.logObject(def, "def")
 
  return def
 
end
 
 
------------
 
-- public --
 
------------
 
 
local p = {}
 
 
 
-- will expect frame.args[1] to be the label
 
function p.getDefName(frame)
 
  local defName
 
  for catK,_ in pairs(data) do
 
    for defK,def in pairs(data[catK]) do
 
      if def["label"] then
 
        if string.upper(def["label"]) == string.upper(frame.args[1]) then defName = defK end
 
      end
 
    end
 
  end
 
 
  if not defName then
 
    mw.logObject(frame.args, "frame.args")
 
    mw.log(string.format("'%s' not found", frame.args[1]))
 
  end
 
 
  return defName
 
end
 
 
function p.count(frame)
 
  local query = p.query(frame)
 
  return #query
 
end
 
 
-- one function to rule them all, and in the darkness bind them
 
function p.query(frame)
 
 
  -- implement shitloads of checks for arguments and the log so we know what's going on
 
  -- use them as a kind of usage guide (give as much info as possible)
 
  -- if wrong arguments are passed to private functions they will cause errors (they better)
 
 
  if not frame.args[1] then
 
    mw.logObject(frame.args, "frame.args")
 
    mw.log("missing argument #1 (defName)")
 
    return nil
 
  end
 
 
  local def = get_def(frame.args[1])
 
 
  if not def then
 
    mw.logObject(frame.args, "frame.args")
 
    mw.log(string.format("bad argument #1 ('%s' not found)", frame.args[1]))
 
    return nil
 
  end
 
 
  local prune = def
 
 
  -- #frame.args won't work as expected, check the doc
 
  local arg_count = util.count(frame.args, "number")
 
 
  -- look at all the beautiful ifs!
 
  for i,arg in ipairs(frame.args) do
 
    -- frame.args are always strings on MediaWiki so convert the numbers back to numbers
 
    arg = tonumber(arg) or arg
 
 
    -- do stuff for additional arguments
 
    if i > 1 then
 
 
      -- special checks for the final argument
 
      if i == arg_count then
 
 
        -- sibling
 
        if frame.args["sibling"] then
 
          prune = search.conductor({nil, frame.args["sibling"]} , prune)
 
          if not prune then
 
            mw.logObject(frame.args, "frame.args")
 
            mw.log(string.format("bad argument 'sibling' ('%s' not found in '%s')", frame.args["sibling"], frame.args[i-1]))
 
            return nil
 
          else
 
            prune = prune.parent.table[arg]
 
            if not prune then
 
              mw.logObject(frame.args, "frame.args")
 
              mw.log(string.format("bad argument #%i ('%s' is not a sibling of '%s')", i, arg, frame.args["sibling"]))
 
            end
 
          end
 
        else
 
          prune = search.conductor(arg, prune)
 
          if not prune then
 
            mw.logObject(frame.args, "frame.args")
 
            mw.log(string.format("bad argument #%i ('%s' not found in '%s')", i, frame.args[i], frame.args[i-1]))
 
            return nil
 
          else
 
            prune = prune.value
 
          end
 
        end
 
 
      else
 
        prune = search.conductor(arg, prune)
 
        if not prune then
 
          mw.logObject(frame.args, "frame.args")
 
          mw.log(string.format("bad argument #%i ('%s' not found in '%s')", i, frame.args[i], frame.args[i-1]))
 
          return nil
 
        else
 
          prune = prune.value
 
        end
 
      end
 
 
    end
 
 
  end
 
 
  if type(prune) == "table" then mw.logObject(prune) end
 
  return prune
 
end
 
 
function p.logObject(frame)
 
  mw.logObject(get(frame))
 
end
 
 
function p.dumpObject(frame)
 
  return mw.dumpObject(get(frame))
 
end
 
 
 
local clock = string.format("os.clock(): %i ms", os.clock() * 1000)
 
mw.log("--" .. string.rep("-", #clock) .. "--")
 
mw.log("- " .. clock .. " -")
 
mw.log("--" .. string.rep("-", #clock) .. "--")
 
 
----------------------------------------
 
-- simulate wiki log while developing --
 
----------------------------------------
 
 
if ENV == "dev" then
 
  util.hl("log")
 
  for _,v in ipairs(log) do
 
    print(v)
 
  end
 
end
 
 
return p
 

Latest revision as of 14:34, 9 May 2021

Dev version at Module:Test