Operating system for OpenComputers
Du kannst nicht mehr als 25 Themen auswählen Themen müssen entweder mit einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.

201 Zeilen
4.8KB

  1. local component = require("component")
  2. local computer = require("computer")
  3. local proxylist = {}
  4. local proxyobjs = {}
  5. local typelist = {}
  6. local doclist = {}
  7. local oproxy = component.proxy
  8. function component.proxy(address)
  9. checkArg(1,address,"string")
  10. if proxyobjs[address] ~= nil then
  11. return proxyobjs[address]
  12. end
  13. return oproxy(address)
  14. end
  15. local olist = component.list
  16. function component.list(filter, exact)
  17. checkArg(1,filter,"string","nil")
  18. local result = {}
  19. local data = {}
  20. for k,v in olist(filter, exact) do
  21. data[#data + 1] = k
  22. data[#data + 1] = v
  23. result[k] = v
  24. end
  25. for k,v in pairs(typelist) do
  26. if filter == nil or (exact and v == filter) or (not exact and v:find(filter, nil, true)) then
  27. data[#data + 1] = k
  28. data[#data + 1] = v
  29. result[k] = v
  30. end
  31. end
  32. local place = 1
  33. return setmetatable(result,
  34. {__call=function()
  35. local addr,type = data[place], data[place + 1]
  36. place = place + 2
  37. return addr, type
  38. end}
  39. )
  40. end
  41. local otype = component.type
  42. function component.type(address)
  43. checkArg(1,address,"string")
  44. if typelist[address] ~= nil then
  45. return typelist[address]
  46. end
  47. return otype(address)
  48. end
  49. local odoc = component.doc
  50. function component.doc(address, method)
  51. checkArg(1,address,"string")
  52. checkArg(2,method,"string")
  53. if proxylist[address] ~= nil then
  54. if proxylist[address][method] == nil then
  55. error("no such method",2)
  56. end
  57. if doclist[address] ~= nil then
  58. return doclist[address][method]
  59. end
  60. return nil
  61. end
  62. return odoc(address, method)
  63. end
  64. local oslot = component.slot
  65. function component.slot(address)
  66. checkArg(1,address,"string")
  67. if proxylist[address] ~= nil then
  68. return -1 -- vcomponents do not exist in a slot
  69. end
  70. return oslot(address)
  71. end
  72. local omethods = component.methods
  73. function component.methods(address)
  74. checkArg(1,address,"string")
  75. if proxylist[address] ~= nil then
  76. local methods = {}
  77. for k,v in pairs(proxylist[address]) do
  78. if type(v) == "function" then
  79. methods[k] = true -- All vcomponent methods are direct
  80. end
  81. end
  82. return methods
  83. end
  84. return omethods(address)
  85. end
  86. local oinvoke = component.invoke
  87. function component.invoke(address, method, ...)
  88. checkArg(1,address,"string")
  89. checkArg(2,method,"string")
  90. if proxylist[address] ~= nil then
  91. if proxylist[address][method] == nil then
  92. error("no such method",2)
  93. end
  94. return proxylist[address][method](...)
  95. end
  96. return oinvoke(address, method, ...)
  97. end
  98. local ofields = component.fields
  99. function component.fields(address)
  100. checkArg(1,address,"string")
  101. if proxylist[address] ~= nil then
  102. return {} -- What even is this?
  103. end
  104. return ofields(address)
  105. end
  106. local componentCallback =
  107. {
  108. __call = function(self, ...) return proxylist[self.address][self.name](...) end,
  109. __tostring = function(self) return (doclist[self.address] ~= nil and doclist[self.address][self.name] ~= nil) and doclist[self.address][self.name] or "function" end
  110. }
  111. local vcomponent = {}
  112. function vcomponent.register(address, ctype, proxy, doc)
  113. checkArg(1,address,"string")
  114. checkArg(2,ctype,"string")
  115. checkArg(3,proxy,"table")
  116. if proxylist[address] ~= nil then
  117. return nil, "component already at address"
  118. elseif component.type(address) ~= nil then
  119. return nil, "cannot register over real component"
  120. end
  121. proxy.address = address
  122. proxy.type = ctype
  123. local proxyobj = {}
  124. for k,v in pairs(proxy) do
  125. if type(v) == "function" then
  126. proxyobj[k] = setmetatable({name=k,address=address},componentCallback)
  127. else
  128. proxyobj[k] = v
  129. end
  130. end
  131. proxylist[address] = proxy
  132. proxyobjs[address] = proxyobj
  133. typelist[address] = ctype
  134. doclist[address] = doc
  135. computer.pushSignal("component_added",address,ctype)
  136. return true
  137. end
  138. function vcomponent.unregister(address)
  139. checkArg(1,address,"string")
  140. if proxylist[address] == nil then
  141. if component.type(address) ~= nil then
  142. return nil, "cannot unregister real component"
  143. else
  144. return nil, "no component at address"
  145. end
  146. end
  147. local thetype = typelist[address]
  148. proxylist[address] = nil
  149. proxyobjs[address] = nil
  150. typelist[address] = nil
  151. doclist[address] = nil
  152. computer.pushSignal("component_removed",address,thetype)
  153. return true
  154. end
  155. function vcomponent.list()
  156. local list = {}
  157. for k,v in pairs(proxylist) do
  158. list[#list + 1] = {k,typelist[k],v}
  159. end
  160. return list
  161. end
  162. function vcomponent.resolve(address, componentType)
  163. checkArg(1, address, "string")
  164. checkArg(2, componentType, "string", "nil")
  165. for k,v in pairs(typelist) do
  166. if componentType == nil or v == componentType then
  167. if k:sub(1, #address) == address then
  168. return k
  169. end
  170. end
  171. end
  172. return nil, "no such component"
  173. end
  174. local r = math.random
  175. function vcomponent.uuid()
  176. return string.format("%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x",
  177. r(0,255),r(0,255),r(0,255),r(0,255),
  178. r(0,255),r(0,255),
  179. r(64,79),r(0,255),
  180. r(128,191),r(0,255),
  181. r(0,255),r(0,255),r(0,255),r(0,255),r(0,255),r(0,255))
  182. end
  183. return vcomponent