Editing Module:DefInfo

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:
 +
----------------------------------------------
 +
-- 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

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)

Template used on this page: