Difference between revisions of "Module:Test/lib/util"

From RimWorld Wiki
Jump to navigation Jump to search
(Created page with "local util = { _DESCRIPTION = 'an assortment of useful things', } --ref: https://gist.github.com/ripter/4270799 function util.tprint(tbl, indent) if not indent then inden...")
 
("look before you leap")
(2 intermediate revisions by the same user not shown)
Line 1: Line 1:
local util = {
+
local util = {}
   _DESCRIPTION = 'an assortment of useful things',
+
 
}
+
------------------------
 +
-- table manipulation --
 +
------------------------
 +
 
 +
util.table = {}
 +
 
 +
-- procedure
 +
function util.table.overwrite(dest, source, ignoreKeys)
 +
  ignoreKeys = ignoreKeys or {}
 +
 
 +
  for sK,sV in pairs(source) do
 +
    local ignore = false
 +
 
 +
    for _,ignoredK in ipairs(ignoreKeys) do
 +
      if sK == ignoredK then
 +
        ignore = true
 +
        break
 +
      end
 +
    end
 +
 
 +
    if not ignore then
 +
      if type(sV) == "table" then
 +
        if type(dest[sK]) == "table" then
 +
          util.table.overwrite(dest[sK], sV, ignoreKeys)
 +
        else
 +
          dest[sK] = {}
 +
          util.table.overwrite(dest[sK], sV, ignoreKeys)
 +
        end
 +
      else
 +
        dest[sK] = sV
 +
      end
 +
    end
 +
  end
 +
end
 +
 
 +
--ref: https://gist.github.com/balaam/3122129
 +
function util.table.reverse(tbl)
 +
  local reversed_table = {}
 +
  local length = #tbl
 +
 
 +
  for i,v in ipairs(tbl) do
 +
      reversed_table[length + 1 - i] = v
 +
  end
 +
 
 +
  for k,v in pairs(tbl) do
 +
    if type(k) ~= 'number' then
 +
      reversed_table[k] = v
 +
    end
 +
  end
 +
 
 +
  return reversed_table
 +
end
 +
 
 +
--ref: http://lua-users.org/wiki/CopyTable
 +
function util.table.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
 +
 
 +
-- this is not as strict as # so might bug out in extreme situations
 +
-- needs love
 +
function util.table.count(tbl, key_type)
 +
  local length = 0;
 +
  for k,v in pairs(tbl) do
 +
    if key_type then
 +
      if type(k) == key_type then
 +
        length = length + 1
 +
      end
 +
    else
 +
      length = length + 1
 +
    end
 +
  end
 +
  return length
 +
end
  
--ref: https://gist.github.com/ripter/4270799
+
-- procedure
function util.tprint(tbl, indent)
+
-- ref: https://gist.github.com/ripter/4270799
 +
function util.table.tprint(tbl, indent)
 
   if not indent then indent = 0 end
 
   if not indent then indent = 0 end
  
Line 25: Line 108:
 
end
 
end
  
--ref: http://lua-users.org/wiki/CopyTable
+
-- delimiter must be a single character
function util.shallowcopy(original_table)
+
-- only for strings and numbers
    local orig_type = type(original_table)
+
function util.table.toCSVstring(tbl, delimiter)
    local copy
+
  delimiter = delimiter or ","
    if orig_type == 'table' then
+
  assert(#delimiter == 1 and type(delimiter) == 'toCSVstring', "toCSVstring: bad argument #2 (single character expected)")
        copy = {}
+
 
        for orig_key, orig_value in pairs(original_table) do
+
  local csv = ""
            copy[orig_key] = orig_value
+
 
        end
+
  for k,v in pairs(tbl) do
     else -- number, string, boolean, etc
+
    if type(v) == 'string' or type(v) == 'number' then
        copy = original_table
+
      csv = csv .. v .. delimiter
 +
     else
 +
      assert(false, "toCSVstring: can only handle numbers and strings")
 
     end
 
     end
    return copy
+
  end
 +
 
 +
  csv = string.sub(csv, 1, -2) -- remove final delimiter (works only for a single char)
 +
 
 +
  return csv
 
end
 
end
  
--ref: https://gist.github.com/balaam/3122129
+
----------
function util.reverse_numeric_table(tbl)
+
-- misc --
    local reversed_table = {}
+
----------
    local length = #tbl
 
    for i,v in ipairs(tbl) do
 
        reversed_table[length + 1 - i] = v
 
    end
 
    return reversed_table
 
end
 
  
---procedure
+
-- procedure
 
function util.hl(title, width)
 
function util.hl(title, width)
 
   width = width or 80
 
   width = width or 80
Line 64: Line 147:
 
end
 
end
  
function util.count(tbl, key_type)
+
----------
  local length = 0;
+
-- diet --
  for k,v in pairs(tbl) do
+
----------
    if key_type then
 
      if type(k) == key_type then
 
        length = length + 1
 
      end
 
    else
 
      length = length + 1
 
    end
 
  end
 
  return length
 
end
 
  
-- "delimiter" must be a single character or the removal of the final one won't work
+
util.diet = {}
function util.table_to_csv_string(simple_table, delimiter)
 
  local f_name = "string_csv"
 
  delimiter = tostring(delimiter) or ","
 
  assert(#delimiter == 1, string.format("bad argument #2 to '%s' (single character expected)", f_name))
 
  
   local list = ""
+
util.diet.foodType = {
 +
  None = true,
 +
  VegetableOrFruit = true,
 +
  Meat = true,
 +
  Fluid = true,
 +
  Corpse = true,
 +
  Seed = true,
 +
  AnimalProduct = true,
 +
  Plant = true,
 +
  Tree = true,
 +
  Meal = true,
 +
  Processed = true,
 +
  Liquor = true,
 +
  Kibble = true,
 +
  VegetarianAnimal = {
 +
    VegetableOrFruit = true,
 +
    Seed = true,
 +
    Meal = true,
 +
    Processed = true,
 +
    Liquor = true,
 +
    Kibble = true
 +
  },
 +
  VegetarianRoughAnimal = {
 +
    VegetableOrFruit = true,
 +
    Seed = true,
 +
    Plant = true,
 +
    Meal = true,
 +
    Processed = true,
 +
    Liquor = true,
 +
    Kibble = true
 +
  },
 +
  CarnivoreAnimal = {
 +
    Meat = true,
 +
    Corpse = true,
 +
    Meal = true,
 +
    Processed = true,
 +
    Kibble = true
 +
  },
 +
  CarnivoreAnimalStrict = {
 +
    Meat = true,
 +
    Corpse = true
 +
  },
 +
  OmnivoreAnimal = {
 +
    VegetableOrFruit = true,
 +
    Meat = true,
 +
    Corpse = true,
 +
    Seed = true,
 +
    Meal = true,
 +
    Processed = true,
 +
    Liquor = true,
 +
    Kibble = true
 +
  },
 +
  OmnivoreRoughAnimal = {
 +
    VegetableOrFruit = true,
 +
    Meat = true,
 +
    Corpse = true,
 +
    Seed = true,
 +
    Plant = true,
 +
    Meal = true,
 +
    Processed = true,
 +
    Liquor = true,
 +
    Kibble = true
 +
  },
 +
  DendrovoreAnimal = {
 +
    VegetableOrFruit = true,
 +
    Seed = true,
 +
    Tree = true,
 +
    Processed = true,
 +
    Kibble = true
 +
  },
 +
   OvivoreAnimal = {
 +
    AnimalProduct = true,
 +
    Meal = true,
 +
    Processed = true,
 +
    Kibble = true
 +
  },
 +
  OmnivoreHuman = {
 +
    VegetableOrFruit = true,
 +
    Meat = true,
 +
    Fluid = true,
 +
    Corpse = true,
 +
    Seed = true,
 +
    AnimalProduct = true,
 +
    Meal = true,
 +
    Processed = true,
 +
    Liquor = true,
 +
    Kibble = true
 +
  }
 +
}
  
  for k,v in pairs(simple_table) do
+
function util.diet.resolveDietCategory(foodType)
    list = tostring(list) .. v .. delimiter
+
  if util.diet[foodType].None then
 +
      return "Never eats"
 
   end
 
   end
   list = string.sub(list, 1, -2)
+
   if util.diet[foodType].Tree then
  return list
+
      return "Dendrovorous"
end
+
   end
 
+
   if util.diet[foodType].Meat then
---procedure
+
       if util.diet[foodType].VegetableOrFruit or util.diet[foodType].Plant then
-- this could be implemented with metatable events
+
          return "Omnivorous"
-- ignore_keys: {"foo", "bar", ... }
 
function util.overwrite_first_table_with_second(first_table, second_table, ignore_keys)
 
   ignore_keys = ignore_keys or {}
 
 
 
   for k,v in pairs(second_table) do
 
    local ignore = false
 
 
 
    for _, ignored_key in ipairs(ignore_keys) do
 
      if k == ignored_key then ignore = true end
 
    end
 
 
 
    if not ignore then
 
       if type(v) == "table" then
 
        if type(first_table[k]) == "table" then
 
          util.overwrite_first_table_with_second(first_table[k], v)
 
        else
 
          first_table[k] = {}
 
          util.overwrite_first_table_with_second(first_table[k], v)
 
        end
 
      else
 
        first_table[k] = v
 
 
       end
 
       end
    end
+
      return "Carnivorous"
 +
  end
 +
  if util.diet[foodType].AnimalProduct then
 +
      return "Ovivorous"
 
   end
 
   end
 +
  return "Herbivorous"
 
end
 
end
  
return util
+
return util -- return module

Revision as of 14:48, 9 May 2021


local util = {}

------------------------
-- table manipulation --
------------------------

util.table = {}

-- procedure
function util.table.overwrite(dest, source, ignoreKeys)
  ignoreKeys = ignoreKeys or {}

  for sK,sV in pairs(source) do
    local ignore = false

    for _,ignoredK in ipairs(ignoreKeys) do
      if sK == ignoredK then
        ignore = true
        break
      end
    end

    if not ignore then
      if type(sV) == "table" then
        if type(dest[sK]) == "table" then
          util.table.overwrite(dest[sK], sV, ignoreKeys)
        else
          dest[sK] = {}
          util.table.overwrite(dest[sK], sV, ignoreKeys)
        end
      else
        dest[sK] = sV
      end
    end
  end
end

--ref: https://gist.github.com/balaam/3122129
function util.table.reverse(tbl)
  local reversed_table = {}
  local length = #tbl

  for i,v in ipairs(tbl) do
      reversed_table[length + 1 - i] = v
  end

  for k,v in pairs(tbl) do
    if type(k) ~= 'number' then
      reversed_table[k] = v
    end
  end

  return reversed_table
end

--ref: http://lua-users.org/wiki/CopyTable
function util.table.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

-- this is not as strict as # so might bug out in extreme situations
-- needs love
function util.table.count(tbl, key_type)
  local length = 0;
  for k,v in pairs(tbl) do
    if key_type then
      if type(k) == key_type then
        length = length + 1
      end
    else
      length = length + 1
    end
  end
  return length
end

-- procedure
-- ref: https://gist.github.com/ripter/4270799
function util.table.tprint(tbl, indent)
  if not indent then indent = 0 end

  if type(tbl) ~= "table" then
    print(tbl)
    return 0
  end

  for k, v in pairs(tbl) do
    formatting = string.rep("  ", indent) .. k .. ": "
    if type(v) == "table" then
      print(formatting)
      util.tprint(v, indent+1)
    elseif type(v) == 'boolean' then
      print(formatting .. tostring(v))
    else
      print(formatting .. v)
    end
  end
end

-- delimiter must be a single character
-- only for strings and numbers
function util.table.toCSVstring(tbl, delimiter)
  delimiter = delimiter or ","
  assert(#delimiter == 1 and type(delimiter) == 'toCSVstring', "toCSVstring: bad argument #2 (single character expected)")

  local csv = ""

  for k,v in pairs(tbl) do
    if type(v) == 'string' or type(v) == 'number' then
      csv = csv .. v .. delimiter
    else
      assert(false, "toCSVstring: can only handle numbers and strings")
    end
  end

  csv = string.sub(csv, 1, -2) -- remove final delimiter (works only for a single char)

  return csv
end

----------
-- misc --
----------

-- procedure
function util.hl(title, width)
  width = width or 80

  if type(title) == "string" then
    title = " " .. title .. " "
    local before = math.floor((width - #title) / 2)
    local after = width - before - #title
    print(string.rep("-", before) .. title .. string.rep("-", after))
  else
    print(string.rep("-", width))
  end
end

----------
-- diet --
----------

util.diet = {}

util.diet.foodType = {
  None = true,
  VegetableOrFruit = true,
  Meat = true,
  Fluid = true,
  Corpse = true,
  Seed = true,
  AnimalProduct = true,
  Plant = true,
  Tree = true,
  Meal = true,
  Processed = true,
  Liquor = true,
  Kibble = true,
  VegetarianAnimal = {
    VegetableOrFruit = true,
    Seed = true,
    Meal = true,
    Processed = true,
    Liquor = true,
    Kibble = true
  },
  VegetarianRoughAnimal = {
    VegetableOrFruit = true,
    Seed = true,
    Plant = true,
    Meal = true,
    Processed = true,
    Liquor = true,
    Kibble = true
  },
  CarnivoreAnimal = {
    Meat = true,
    Corpse = true,
    Meal = true,
    Processed = true,
    Kibble = true
  },
  CarnivoreAnimalStrict = {
    Meat = true,
    Corpse = true
  },
  OmnivoreAnimal = {
    VegetableOrFruit = true,
    Meat = true,
    Corpse = true,
    Seed = true,
    Meal = true,
    Processed = true,
    Liquor = true,
    Kibble = true
  },
  OmnivoreRoughAnimal = {
    VegetableOrFruit = true,
    Meat = true,
    Corpse = true,
    Seed = true,
    Plant = true,
    Meal = true,
    Processed = true,
    Liquor = true,
    Kibble = true
  },
  DendrovoreAnimal = {
    VegetableOrFruit = true,
    Seed = true,
    Tree = true,
    Processed = true,
    Kibble = true
  },
  OvivoreAnimal = {
    AnimalProduct = true,
    Meal = true,
    Processed = true,
    Kibble = true
  },
  OmnivoreHuman = {
    VegetableOrFruit = true,
    Meat = true,
    Fluid = true,
    Corpse = true,
    Seed = true,
    AnimalProduct = true,
    Meal = true,
    Processed = true,
    Liquor = true,
    Kibble = true
  }
}

function util.diet.resolveDietCategory(foodType)
  if util.diet[foodType].None then
      return "Never eats"
  end
  if util.diet[foodType].Tree then
      return "Dendrovorous"
  end
  if util.diet[foodType].Meat then
      if util.diet[foodType].VegetableOrFruit or util.diet[foodType].Plant then
          return "Omnivorous"
      end
      return "Carnivorous"
  end
  if util.diet[foodType].AnimalProduct then
      return "Ovivorous"
  end
  return "Herbivorous"
end

return util -- return module