Operating system for OpenComputers
Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

198 строки
4.7KB

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