Advertisement
SenpaiJody

Untitled

Oct 17th, 2022 (edited)
63
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 12.69 KB | None | 0 0
  1. --JPERIPHERALS
  2.  
  3.  
  4. --[[- Find and control peripherals attached to this computer.
  5.  
  6. Peripherals are blocks (or turtle and pocket computer upgrades) which can
  7. be controlled by a computer. For instance, the @{speaker} peripheral allows a
  8. computer to play music and the @{monitor} peripheral allows you to display text
  9. in the world.
  10.  
  11. ## Referencing peripherals
  12.  
  13. Computers can interact with adjacent peripherals. Each peripheral is given a
  14. name based on which direction it is in. For instance, a disk drive below your
  15. computer will be called `"bottom"` in your Lua code, one to the left called
  16. `"left"` , and so on for all 6 directions (`"bottom"`, `"top"`, `"left"`,
  17. `"right"`, `"front"`, `"back"`).
  18.  
  19. You can list the names of all peripherals with the `peripherals` program, or the
  20. @{peripheral.getNames} function.
  21.  
  22. It's also possible to use peripherals which are further away from your computer
  23. through the use of @{modem|Wired Modems}. Place one modem against your computer,
  24. run Networking Cable to your peripheral, and then place another modem against
  25. that block. You can then right click the modem to use (or *attach*) the
  26. peripheral. This will print a peripheral name to chat, which can then be used
  27. just like a direction name to access the peripheral. You can click on the message
  28. to copy the name to your clipboard.
  29.  
  30. ## Using peripherals
  31.  
  32. Once you have the name of a peripheral, you can call functions on it using the
  33. @{peripheral.call} function. This takes the name of our peripheral, the name of
  34. the function we want to call, and then its arguments.
  35.  
  36. :::info
  37. Some bits of the peripheral API call peripheral functions *methods* instead
  38. (for example, the @{peripheral.getMethods} function). Don't worry, they're the
  39. same thing!
  40. :::
  41.  
  42. Let's say we have a monitor above our computer (and so "top") and want to
  43. @{monitor.write|write some text to it}. We'd write the following:
  44.  
  45. ```lua
  46. peripheral.call("top", "write", "This is displayed on a monitor!")
  47. ```
  48.  
  49. Once you start calling making a couple of peripheral calls this can get very
  50. repetitive, and so we can @{peripheral.wrap|wrap} a peripheral. This builds a
  51. table of all the peripheral's functions so you can use it like an API or module.
  52.  
  53. For instance, we could have written the above example as follows:
  54.  
  55. ```lua
  56. local my_monitor = peripheral.wrap("top")
  57. my_monitor.write("This is displayed on a monitor!")
  58. ```
  59.  
  60. ## Finding peripherals
  61.  
  62. Sometimes when you're writing a program you don't care what a peripheral is
  63. called, you just need to know it's there. For instance, if you're writing a
  64. music player, you just need a speaker - it doesn't matter if it's above or below
  65. the computer.
  66.  
  67. Thankfully there's a quick way to do this: @{peripheral.find}. This takes a
  68. *peripheral type* and returns all the attached peripherals which are of this
  69. type.
  70.  
  71. What is a peripheral type though? This is a string which describes what a
  72. peripheral is, and so what functions are available on it. For instance, speakers
  73. are just called `"speaker"`, and monitors `"monitor"`. Some peripherals might
  74. have more than one type - a Minecraft chest is both a `"minecraft:chest"` and
  75. `"inventory"`.
  76.  
  77. You can get all the types a peripheral has with @{peripheral.getType}, and check
  78. a peripheral is a specific type with @{peripheral.hasType}.
  79.  
  80. To return to our original example, let's use @{peripheral.find} to find an
  81. attached speaker:
  82.  
  83. ```lua
  84. local speaker = peripheral.find("speaker")
  85. speaker.playNote("harp")
  86. ```
  87.  
  88. @module peripheral
  89. @see event!peripheral This event is fired whenever a new peripheral is attached.
  90. @see event!peripheral_detach This event is fired whenever a peripheral is detached.
  91. @since 1.3
  92. @changed 1.51 Add support for wired modems.
  93. @changed 1.99 Peripherals can have multiple types.
  94. ]]
  95.  
  96. local expect = dofile("rom/modules/main/cc/expect.lua").expect
  97.  
  98. local native = peripheral
  99. for k, v in pairs(native) do
  100.     print(k)
  101.     end
  102. local sides = rs.getSides()
  103.  
  104. --- Provides a list of all peripherals available.
  105. --
  106. -- If a device is located directly next to the system, then its name will be
  107. -- listed as the side it is attached to. If a device is attached via a Wired
  108. -- Modem, then it'll be reported according to its name on the wired network.
  109. --
  110. -- @treturn { string... } A list of the names of all attached peripherals.
  111. -- @since 1.51
  112. function getNames()
  113.     local results = {}
  114.     for n = 1, #sides do
  115.         local side = sides[n]
  116.         if native.isPresent(side) then
  117.             table.insert(results, side)
  118.             if native.hasType(side, "modem") and not native.call(side, "isWireless") then
  119.                 local remote = native.call(side, "getNamesRemote")
  120.                 for _, name in ipairs(remote) do
  121.                     table.insert(results, name)
  122.                 end
  123.             end
  124.         end
  125.     end
  126.     return results
  127. end
  128.  
  129. --- Determines if a peripheral is present with the given name.
  130. --
  131. -- @tparam string name The side or network name that you want to check.
  132. -- @treturn boolean If a peripheral is present with the given name.
  133. -- @usage peripheral.isPresent("top")
  134. -- @usage peripheral.isPresent("monitor_0")
  135. function isPresent(name)
  136.     expect(1, name, "string")
  137.     if native.isPresent(name) then
  138.         return true
  139.     end
  140.  
  141.     for n = 1, #sides do
  142.         local side = sides[n]
  143.         if native.hasType(side, "modem") and not native.call(side, "isWireless") and
  144.             native.call(side, "isPresentRemote", name)
  145.         then
  146.             return true
  147.         end
  148.     end
  149.     return false
  150. end
  151.  
  152. --[[- Get the types of a named or wrapped peripheral.
  153.  
  154. @tparam string|table peripheral The name of the peripheral to find, or a
  155. wrapped peripheral instance.
  156. @treturn string... The peripheral's types, or `nil` if it is not present.
  157. @changed 1.88.0 Accepts a wrapped peripheral as an argument.
  158. @changed 1.99 Now returns multiple types.
  159. @usage Get the type of a peripheral above this computer.
  160.  
  161.     peripheral.getType("top")
  162. ]]
  163. function getType(peripheral)
  164.     expect(1, peripheral, "string", "table")
  165.     if type(peripheral) == "string" then -- Peripheral name passed
  166.         if native.isPresent(peripheral) then
  167.             return native.getType(peripheral)
  168.         end
  169.         for n = 1, #sides do
  170.             local side = sides[n]
  171.             if native.hasType(side, "modem") and not native.call(side, "isWireless") and
  172.                 native.call(side, "isPresentRemote", peripheral)
  173.             then
  174.                 return native.call(side, "getTypeRemote", peripheral)
  175.             end
  176.         end
  177.         return nil
  178.     else
  179.         local mt = getmetatable(peripheral)
  180.         if not mt or mt.__name ~= "peripheral" or type(mt.types) ~= "table" then
  181.             error("bad argument #1 (table is not a peripheral)", 2)
  182.         end
  183.         return table.unpack(mt.types)
  184.     end
  185. end
  186.  
  187. --[[- Check if a peripheral is of a particular type.
  188.  
  189. @tparam string|table peripheral The name of the peripheral or a wrapped peripheral instance.
  190. @tparam string peripheral_type The type to check.
  191.  
  192. @treturn boolean|nil If a peripheral has a particular type, or `nil` if it is not present.
  193. @since 1.99
  194. ]]
  195. function hasType(peripheral, peripheral_type)
  196.     expect(1, peripheral, "string", "table")
  197.     expect(2, peripheral_type, "string")
  198.     if type(peripheral) == "string" then -- Peripheral name passed
  199.         if native.isPresent(peripheral) then
  200.             return native.hasType(peripheral, peripheral_type)
  201.         end
  202.         for n = 1, #sides do
  203.             local side = sides[n]
  204.             if native.hasType(side, "modem") and not native.call(side, "isWireless") and
  205.                 native.call(side, "isPresentRemote", peripheral)
  206.             then
  207.                 return native.call(side, "hasTypeRemote", peripheral, peripheral_type)
  208.             end
  209.         end
  210.         return nil
  211.     else
  212.         local mt = getmetatable(peripheral)
  213.         if not mt or mt.__name ~= "peripheral" or type(mt.types) ~= "table" then
  214.             error("bad argument #1 (table is not a peripheral)", 2)
  215.         end
  216.         return mt.types[peripheral_type] ~= nil
  217.     end
  218. end
  219.  
  220. --- Get all available methods for the peripheral with the given name.
  221. --
  222. -- @tparam string name The name of the peripheral to find.
  223. -- @treturn { string... }|nil A list of methods provided by this peripheral, or `nil` if
  224. -- it is not present.
  225. function getMethods(name)
  226.     expect(1, name, "string")
  227.     if native.isPresent(name) then
  228.         return native.getMethods(name)
  229.     end
  230.     for n = 1, #sides do
  231.         local side = sides[n]
  232.         if native.hasType(side, "modem") and not native.call(side, "isWireless") and
  233.             native.call(side, "isPresentRemote", name)
  234.         then
  235.             return native.call(side, "getMethodsRemote", name)
  236.         end
  237.     end
  238.     return nil
  239. end
  240.  
  241. --- Get the name of a peripheral wrapped with @{peripheral.wrap}.
  242. --
  243. -- @tparam table peripheral The peripheral to get the name of.
  244. -- @treturn string The name of the given peripheral.
  245. -- @since 1.88.0
  246. function getName(peripheral)
  247.     expect(1, peripheral, "table")
  248.     local mt = getmetatable(peripheral)
  249.     if not mt or mt.__name ~= "peripheral" or type(mt.name) ~= "string" then
  250.         error("bad argument #1 (table is not a peripheral)", 2)
  251.     end
  252.     return mt.name
  253. end
  254.  
  255. --- Call a method on the peripheral with the given name.
  256. --
  257. -- @tparam string name The name of the peripheral to invoke the method on.
  258. -- @tparam string method The name of the method
  259. -- @param ... Additional arguments to pass to the method
  260. -- @return The return values of the peripheral method.
  261. --
  262. -- @usage Open the modem on the top of this computer.
  263. --
  264. --     peripheral.call("top", "open", 1)
  265. function call(name, method, ...)
  266.     expect(1, name, "string")
  267.     expect(2, method, "string")
  268.     if native.isPresent(name) then
  269.         return native.call(name, method, ...)
  270.     end
  271.  
  272.     for n = 1, #sides do
  273.         local side = sides[n]
  274.         if native.hasType(side, "modem") and not native.call(side, "isWireless") and
  275.             native.call(side, "isPresentRemote", name)
  276.         then
  277.             return native.call(side, "callRemote", name, method, ...)
  278.         end
  279.     end
  280.     return nil
  281. end
  282.  
  283. --- Get a table containing all functions available on a peripheral. These can
  284. -- then be called instead of using @{peripheral.call} every time.
  285. --
  286. -- @tparam string name The name of the peripheral to wrap.
  287. -- @treturn table|nil The table containing the peripheral's methods, or `nil` if
  288. -- there is no peripheral present with the given name.
  289. -- @usage Open the modem on the top of this computer.
  290. --
  291. --     local modem = peripheral.wrap("top")
  292. --     modem.open(1)
  293. function wrap(name)
  294.     expect(1, name, "string")
  295.  
  296.     local methods = peripheral.getMethods(name)
  297.     if not methods then
  298.         return nil
  299.     end
  300.  
  301.     -- We store our types array as a list (for getType) and a lookup table (for hasType).
  302.     local types = { peripheral.getType(name) }
  303.     for i = 1, #types do types[types[i]] = true end
  304.     local result = setmetatable({}, {
  305.         __name = "peripheral",
  306.         name = name,
  307.         type = types[1],
  308.         types = types,
  309.     })
  310.     for _, method in ipairs(methods) do
  311.         result[method] = function(...)
  312.             return peripheral.call(name, method, ...)
  313.         end
  314.     end
  315.     return result
  316. end
  317.  
  318. --[[- Find all peripherals of a specific type, and return the
  319. @{peripheral.wrap|wrapped} peripherals.
  320.  
  321. @tparam string ty The type of peripheral to look for.
  322. @tparam[opt] function(name:string, wrapped:table):boolean filter A
  323. filter function, which takes the peripheral's name and wrapped table
  324. and returns if it should be included in the result.
  325. @treturn table... 0 or more wrapped peripherals matching the given filters.
  326. @usage Find all monitors and store them in a table, writing "Hello" on each one.
  327.  
  328.     local monitors = { peripheral.find("monitor") }
  329.     for _, monitor in pairs(monitors) do
  330.       monitor.write("Hello")
  331.     end
  332.  
  333. @usage Find all wireless modems connected to this computer.
  334.  
  335.     local modems = { peripheral.find("modem", function(name, modem)
  336.         return modem.isWireless() -- Check this modem is wireless.
  337.     end) }
  338.  
  339. @usage This abuses the `filter` argument to call @{rednet.open} on every modem.
  340.  
  341.     peripheral.find("modem", rednet.open)
  342. @since 1.6
  343. ]]
  344. function find(ty, filter)
  345.     expect(1, ty, "string")
  346.     expect(2, filter, "function", "nil")
  347.  
  348.     local results = {}
  349.     for _, name in ipairs(peripheral.getNames()) do
  350.         if peripheral.hasType(name, ty) then
  351.             local wrapped = peripheral.wrap(name)
  352.             if filter == nil or filter(name, wrapped) then
  353.                 table.insert(results, wrapped)
  354.             end
  355.         end
  356.     end
  357.     return table.unpack(results)
  358. end
  359.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement