Advertisement
SirSheepe

SPM Network

May 14th, 2023 (edited)
22
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.30 KB | None | 0 0
  1. -- local Turtle = {}
  2. -- Turtle.__index = Turtle
  3.  
  4. local Network = {}
  5. Network.__index = Network
  6.  
  7. function Network.new(modem)
  8. local self = setmetatable({}, Network)
  9.  
  10. if modem == nil then
  11. error("Unable to create network, no modem provided", 2)
  12. end
  13.  
  14. self.DEFAULT_CHANNEL = 42424
  15. self.expectedPackets = {}
  16. self.connectedTurtles = {}
  17. self.modems = { modem }
  18.  
  19. return self
  20. end
  21.  
  22. function Network:Listen()
  23. while true do
  24. local event, id, channel, reply, message = os.pullEvent()
  25.  
  26. if event == "network_disconnect" then
  27. self.expectedPackets = {}
  28. break
  29. end
  30.  
  31. if event == "timer" or event == "modem_message" then
  32. local closed = {}
  33.  
  34. for i = 1, #self.expectedPackets do
  35. local packet = self.expectedPackets[i]
  36.  
  37. if event == "timer" and id == packet.timeout then
  38. table.remove(self.expectedPackets, i)
  39. i = i - 1
  40. end
  41.  
  42. if event == "modem_message" and channel == packet.channel and message == packet.message then
  43. table.remove(self.expectedPackets, i)
  44. table.insert(closed, channel)
  45. os.queueEvent(packet.uuid)
  46. os.cancelTimer(packet.timout)
  47. i = i - 1
  48. end
  49. end
  50.  
  51. for i = 1, #closed do
  52. local required = false
  53.  
  54. for _, packet in pairs(self.expectedPackets) do
  55. local channel = closed[i]
  56.  
  57. if packet.channel == channel then
  58. required = true
  59. break
  60. end
  61. end
  62.  
  63. if not required then
  64. self:CloseChannel(channel)
  65. end
  66. end
  67.  
  68. if event == "modem_message" then
  69. end
  70. end
  71. end
  72. end
  73.  
  74. -- https://gist.github.com/jrus/3197011
  75. function Network:GenerateEventUUID()
  76. local template = "STNPxxxx-xxxx-xxxx"
  77. return string.gsub(template, "[x]", function(c)
  78. return string.format("%x", math.random(0, 0xf))
  79. end)
  80. end
  81.  
  82. function Network:Stop()
  83. os.queueEvent("network_disconnect")
  84. end
  85.  
  86. function Network:WaitForAll(timeout)
  87. local timerID = os.startTimer(timeout or 60)
  88.  
  89. while #self.expectedPackets > 0 do
  90. local event, id = os.pullEvent()
  91.  
  92. if event == "timer" and id == timerID then
  93. break
  94. end
  95. end
  96.  
  97. return #self.expectedPackets == 0
  98. end
  99.  
  100. function Network:WaitForBatch(batch, timeout)
  101. local events = {}
  102. local result = {}
  103.  
  104. for i, packet in pairs(batch) do
  105. table.insert(
  106. events,
  107. Network:Expect(packet.channel, packet.message, timeout, function(success)
  108. result[i] = success
  109. return packet.callback(success)
  110. end)
  111. )
  112. end
  113.  
  114. parallel.waitForAll(unpack(events))
  115.  
  116. return result
  117. end
  118.  
  119. function Network:Wait(channel, message, timeout, callback)
  120. return self:Expect(channel, message, timeout, callback)()
  121. end
  122.  
  123. function Network:Expect(channel, message, timeout, callback)
  124. local packetUUID = self:GenerateEventUUID()
  125. local timerID = timeout == false and -1 or os.startTimer(timeout or 30)
  126.  
  127. self:OpenChannel(channel)
  128.  
  129. table.insert(self.expectedPackets, {
  130. channel = channel,
  131. message = message,
  132. timeout = timerID,
  133. uuid = packetUUID,
  134. })
  135.  
  136. return function()
  137. while true do
  138. local event, id = os.pullEvent()
  139.  
  140. if event == "timer" and id == timerID then
  141. if callback then
  142. return callback(false)
  143. end
  144. return false
  145. end
  146.  
  147. if event == packetUUID then
  148. if callback then
  149. return callback(false)
  150. end
  151. return true
  152. end
  153. end
  154. end
  155. end
  156.  
  157. function Network:HasModem(otherModem)
  158. for i, modem in pairs(self.modems) do
  159. for channel = 1, 65535 do
  160. if not (modem.isOpen(channel) or otherModem.isOpen(channel)) then
  161. modem.open(channel)
  162.  
  163. local newOpen = otherModem.isOpen(channel)
  164. modem.close(channel)
  165.  
  166. return newOpen
  167. end
  168. end
  169. end
  170. return false
  171. end
  172.  
  173. function Network:AddModem(newModem)
  174. if self:HasModem(newModem) then
  175. return false
  176. end
  177.  
  178. table.insert(self.modems, newModem)
  179.  
  180. return true
  181. end
  182.  
  183. function Network:OpenChannel(channel)
  184. for i, v in pairs(self.modems) do
  185. if v.isOpen(channel) then
  186. return
  187. end
  188. end
  189.  
  190. for i, v in pairs(self.modems) do
  191. if pcall(v.open, channel) then
  192. return
  193. end
  194. end
  195.  
  196. error("Too many channels open, no modems available", 2)
  197. end
  198.  
  199. function Network:Send() end
  200.  
  201. function Network:Connect() end
  202.  
  203. -- local remote = Network.new(peripheral.wrap("top"))
  204. -- print(remote:HasModem(peripheral.wrap("right")))
  205.  
  206. -- -- parallel.waitForAll(Network.Listen(Network), Network.Wait(Network, 30, "cats", 60))
  207.  
  208. return Network
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement