Advertisement
Guest User

radar.lua

a guest
Oct 16th, 2018
92
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 8.19 KB | None | 0 0
  1. local inspect = { }
  2.  
  3. local tostring = tostring
  4.  
  5. inspect.KEY       = setmetatable({}, {__tostring = function() return 'inspect.KEY' end})
  6. inspect.METATABLE = setmetatable({}, {__tostring = function() return 'inspect.METATABLE' end})
  7.  
  8. local function rawpairs(t)
  9.   return next, t, nil
  10. end
  11.  
  12. -- Apostrophizes the string if it has quotes, but not aphostrophes
  13. -- Otherwise, it returns a regular quoted string
  14. local function smartQuote(str)
  15.   if str:match('"') and not str:match("'") then
  16.     return "'" .. str .. "'"
  17.   end
  18.   return '"' .. str:gsub('"', '\\"') .. '"'
  19. end
  20.  
  21. -- \a => '\\a', \0 => '\\0', 31 => '\31'
  22. local shortControlCharEscapes = {
  23.   ["\a"] = "\\a",  ["\b"] = "\\b", ["\f"] = "\\f", ["\n"] = "\\n",
  24.   ["\r"] = "\\r",  ["\t"] = "\\t", ["\v"] = "\\v"
  25. }
  26. local longControlCharEscapes = {} -- \a => nil, \0 => \000, 31 => \031
  27. for i=0, 31 do
  28.   local ch = string.char(i)
  29.   if not shortControlCharEscapes[ch] then
  30.     shortControlCharEscapes[ch] = "\\"..i
  31.     longControlCharEscapes[ch]  = string.format("\\%03d", i)
  32.   end
  33. end
  34.  
  35. local function escape(str)
  36.   return (str:gsub("\\", "\\\\")
  37.              :gsub("(%c)%f[0-9]", longControlCharEscapes)
  38.              :gsub("%c", shortControlCharEscapes))
  39. end
  40.  
  41. local function isIdentifier(str)
  42.   return type(str) == 'string' and str:match( "^[_%a][_%a%d]*$" )
  43. end
  44.  
  45. local function isSequenceKey(k, sequenceLength)
  46.   return type(k) == 'number'
  47.      and 1 <= k
  48.      and k <= sequenceLength
  49.      and math.floor(k) == k
  50. end
  51.  
  52. local defaultTypeOrders = {
  53.   ['number']   = 1, ['boolean']  = 2, ['string'] = 3, ['table'] = 4,
  54.   ['function'] = 5, ['userdata'] = 6, ['thread'] = 7
  55. }
  56.  
  57. local function sortKeys(a, b)
  58.   local ta, tb = type(a), type(b)
  59.  
  60.   -- strings and numbers are sorted numerically/alphabetically
  61.   if ta == tb and (ta == 'string' or ta == 'number') then return a < b end
  62.  
  63.   local dta, dtb = defaultTypeOrders[ta], defaultTypeOrders[tb]
  64.   -- Two default types are compared according to the defaultTypeOrders table
  65.   if dta and dtb then return defaultTypeOrders[ta] < defaultTypeOrders[tb]
  66.   elseif dta     then return true  -- default types before custom ones
  67.   elseif dtb     then return false -- custom types after default ones
  68.   end
  69.  
  70.   -- custom types are sorted out alphabetically
  71.   return ta < tb
  72. end
  73.  
  74. -- For implementation reasons, the behavior of rawlen & # is "undefined" when
  75. -- tables aren't pure sequences. So we implement our own # operator.
  76. local function getSequenceLength(t)
  77.   local len = 1
  78.   local v = rawget(t,len)
  79.   while v ~= nil do
  80.     len = len + 1
  81.     v = rawget(t,len)
  82.   end
  83.   return len - 1
  84. end
  85.  
  86. local function getNonSequentialKeys(t)
  87.   local keys, keysLength = {}, 0
  88.   local sequenceLength = getSequenceLength(t)
  89.   for k,_ in rawpairs(t) do
  90.     if not isSequenceKey(k, sequenceLength) then
  91.       keysLength = keysLength + 1
  92.       keys[keysLength] = k
  93.     end
  94.   end
  95.   table.sort(keys, sortKeys)
  96.   return keys, keysLength, sequenceLength
  97. end
  98.  
  99. local function countTableAppearances(t, tableAppearances)
  100.   tableAppearances = tableAppearances or {}
  101.  
  102.   if type(t) == 'table' then
  103.     if not tableAppearances[t] then
  104.       tableAppearances[t] = 1
  105.       for k,v in rawpairs(t) do
  106.         countTableAppearances(k, tableAppearances)
  107.         countTableAppearances(v, tableAppearances)
  108.       end
  109.       countTableAppearances(getmetatable(t), tableAppearances)
  110.     else
  111.       tableAppearances[t] = tableAppearances[t] + 1
  112.     end
  113.   end
  114.  
  115.   return tableAppearances
  116. end
  117.  
  118. local copySequence = function(s)
  119.   local copy, len = {}, #s
  120.   for i=1, len do copy[i] = s[i] end
  121.   return copy, len
  122. end
  123.  
  124. local function makePath(path, ...)
  125.   local keys = {...}
  126.   local newPath, len = copySequence(path)
  127.   for i=1, #keys do
  128.     newPath[len + i] = keys[i]
  129.   end
  130.   return newPath
  131. end
  132.  
  133. local function processRecursive(process, item, path, visited)
  134.   if item == nil then return nil end
  135.   if visited[item] then return visited[item] end
  136.  
  137.   local processed = process(item, path)
  138.   if type(processed) == 'table' then
  139.     local processedCopy = {}
  140.     visited[item] = processedCopy
  141.     local processedKey
  142.  
  143.     for k,v in rawpairs(processed) do
  144.       processedKey = processRecursive(process, k, makePath(path, k, inspect.KEY), visited)
  145.       if processedKey ~= nil then
  146.         processedCopy[processedKey] = processRecursive(process, v, makePath(path, processedKey), visited)
  147.       end
  148.     end
  149.  
  150.     local mt  = processRecursive(process, getmetatable(processed), makePath(path, inspect.METATABLE), visited)
  151.     if type(mt) ~= 'table' then mt = nil end -- ignore not nil/table __metatable field
  152.     setmetatable(processedCopy, mt)
  153.     processed = processedCopy
  154.   end
  155.   return processed
  156. end
  157.  
  158.  
  159.  
  160. -------------------------------------------------------------------
  161.  
  162. local Inspector = {}
  163. local Inspector_mt = {__index = Inspector}
  164.  
  165. function Inspector:puts(...)
  166.   local args   = {...}
  167.   local buffer = self.buffer
  168.   local len    = #buffer
  169.   for i=1, #args do
  170.     len = len + 1
  171.     buffer[len] = args[i]
  172.   end
  173. end
  174.  
  175. function Inspector:down(f)
  176.   self.level = self.level + 1
  177.   f()
  178.   self.level = self.level - 1
  179. end
  180.  
  181. function Inspector:tabify()
  182.   self:puts(self.newline, string.rep(self.indent, self.level))
  183. end
  184.  
  185. function Inspector:alreadyVisited(v)
  186.   return self.ids[v] ~= nil
  187. end
  188.  
  189. function Inspector:getId(v)
  190.   local id = self.ids[v]
  191.   if not id then
  192.     local tv = type(v)
  193.     id              = (self.maxIds[tv] or 0) + 1
  194.     self.maxIds[tv] = id
  195.     self.ids[v]     = id
  196.   end
  197.   return tostring(id)
  198. end
  199.  
  200. function Inspector:putKey(k)
  201.   if isIdentifier(k) then return self:puts(k) end
  202.   self:puts("[")
  203.   self:putValue(k)
  204.   self:puts("]")
  205. end
  206.  
  207. function Inspector:putTable(t)
  208.   if t == inspect.KEY or t == inspect.METATABLE then
  209.     self:puts(tostring(t))
  210.   elseif self:alreadyVisited(t) then
  211.     self:puts('<table ', self:getId(t), '>')
  212.   elseif self.level >= self.depth then
  213.     self:puts('{...}')
  214.   else
  215.     if self.tableAppearances[t] > 1 then self:puts('<', self:getId(t), '>') end
  216.  
  217.     local nonSequentialKeys, nonSequentialKeysLength, sequenceLength = getNonSequentialKeys(t)
  218.     local mt                = getmetatable(t)
  219.  
  220.     self:puts('{')
  221.     self:down(function()
  222.       local count = 0
  223.       for i=1, sequenceLength do
  224.         if count > 0 then self:puts(',') end
  225.         self:puts(' ')
  226.         self:putValue(t[i])
  227.         count = count + 1
  228.       end
  229.  
  230.       for i=1, nonSequentialKeysLength do
  231.         local k = nonSequentialKeys[i]
  232.         if count > 0 then self:puts(',') end
  233.         self:tabify()
  234.         self:putKey(k)
  235.         self:puts(' = ')
  236.         self:putValue(t[k])
  237.         count = count + 1
  238.       end
  239.  
  240.       if type(mt) == 'table' then
  241.         if count > 0 then self:puts(',') end
  242.         self:tabify()
  243.         self:puts('<metatable> = ')
  244.         self:putValue(mt)
  245.       end
  246.     end)
  247.  
  248.     if nonSequentialKeysLength > 0 or type(mt) == 'table' then -- result is multi-lined. Justify closing }
  249.       self:tabify()
  250.     elseif sequenceLength > 0 then -- array tables have one extra space before closing }
  251.       self:puts(' ')
  252.     end
  253.  
  254.     self:puts('}')
  255.   end
  256. end
  257.  
  258. function Inspector:putValue(v)
  259.   local tv = type(v)
  260.  
  261.   if tv == 'string' then
  262.     self:puts(smartQuote(escape(v)))
  263.   elseif tv == 'number' or tv == 'boolean' or tv == 'nil' or
  264.          tv == 'cdata' or tv == 'ctype' then
  265.     self:puts(tostring(v))
  266.   elseif tv == 'table' then
  267.     self:putTable(v)
  268.   else
  269.     self:puts('<', tv, ' ', self:getId(v), '>')
  270.   end
  271. end
  272.  
  273. -------------------------------------------------------------------
  274.  
  275. function inspect.inspect(root, options)
  276.   options       = options or {}
  277.  
  278.   local depth   = options.depth   or math.huge
  279.   local newline = options.newline or '\n'
  280.   local indent  = options.indent  or '  '
  281.   local process = options.process
  282.  
  283.   if process then
  284.     root = processRecursive(process, root, {}, {})
  285.   end
  286.  
  287.   local inspector = setmetatable({
  288.     depth            = depth,
  289.     level            = 0,
  290.     buffer           = {},
  291.     ids              = {},
  292.     maxIds           = {},
  293.     newline          = newline,
  294.     indent           = indent,
  295.     tableAppearances = countTableAppearances(root)
  296.   }, Inspector_mt)
  297.  
  298.   inspector:putValue(root)
  299.  
  300.   return table.concat(inspector.buffer)
  301. end
  302.  
  303. setmetatable(inspect, { __call = function(_, ...) return inspect.inspect(...) end })
  304.  
  305. -- return inspect
  306.  
  307.  
  308.  
  309. local component = require("component")
  310. local computer = require("computer")
  311. local event = require("event")
  312.  
  313. print(inspect(component.radar.getPlayers())[1])
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement