peripheral overhaul

This commit is contained in:
kepler155c@gmail.com 2018-01-06 06:07:49 -05:00
parent 1528bab3ac
commit 911fec9118
5 changed files with 188 additions and 3 deletions

View File

@ -1,4 +1,6 @@
local Util = require('util')
local Event = require('event')
local Socket = require('socket')
local Util = require('util')
local Peripheral = Util.shallowCopy(_G.peripheral)
@ -90,6 +92,10 @@ function Peripheral.get(args)
args = { type = args }
end
if args.device then
return _G.device[args.device]
end
if args.type then
local p = Peripheral.getByType(args.type)
if p then
@ -112,4 +118,111 @@ function Peripheral.get(args)
end
end
local function getProxy(pi)
local socket = Socket.connect(pi.host, 189)
if not socket then
error("Timed out attaching peripheral: " .. pi.uri)
end
socket:write(pi.path)
local proxy = socket:read(3)
if not proxy then
error("Timed out attaching peripheral: " .. pi.uri)
end
local methods = proxy.methods
proxy.methods = nil
for _,method in pairs(methods) do
proxy[method] = function(...)
socket:write({ fn = method, args = { ... } })
local resp = socket:read()
if not resp then
error("Timed out communicating with peripheral: " .. pi.uri)
end
return table.unpack(resp)
end
end
if proxy.blit then
local methods = { 'clear', 'clearLine', 'setCursorPos', 'write', 'blit',
'setTextColor', 'setTextColour', 'setBackgroundColor',
'setBackgroundColour', 'scroll', 'setCursorBlink', }
local queue = nil
for _,method in pairs(methods) do
proxy[method] = function(...)
if not queue then
queue = { }
Event.onTimeout(0, function()
socket:write({ fn = 'fastBlit', args = { queue } })
queue = nil
socket:read()
end)
end
table.insert(queue, {
fn = method,
args = { ... },
})
end
end
end
if proxy.type == 'monitor' then
Event.addRoutine(function()
while true do
local event = socket:read()
if not event then
break
end
if not Util.empty(event) then
os.queueEvent(table.unpack(event))
end
end
end)
end
return proxy
end
--[[
Parse a uri into it's components
Examples:
monitor = { device = 'monitor' }
side/top = { side = 'top' }
method/list = { method = 'list' }
12://device/monitor = { host = 12, device = 'monitor' }
]]--
local function parse(uri)
local pi = Util.split(uri:gsub('^%d*://', ''), '(.-)/')
if #pi == 1 then
pi = {
'device',
pi[1],
}
end
return {
host = uri:match('^(%d*)%:'), -- 12
uri = uri, -- 12://device/monitor
path = uri:gsub('^%d*://', ''), -- device/monitor
[ pi[1] ] = pi[2], -- device = 'monitor'
}
end
function Peripheral.lookup(uri)
local pi = parse(uri)
if pi.host then
return getProxy(pi)
end
return Peripheral.get(pi)
end
return Peripheral

View File

@ -2,6 +2,7 @@ local Canvas = require('ui.canvas')
local class = require('class')
local Event = require('event')
local Input = require('input')
local Peripheral = require('peripheral')
local Transition = require('ui.transition')
local Util = require('util')
@ -190,7 +191,7 @@ function Manager:configure(appName, ...)
if defaults.device.name == 'terminal' then
dev = term.current()
else
dev = device[defaults.device.name]
dev = Peripheral.lookup(defaults.device.name) --- device[defaults.device.name]
end
if not dev then

View File

@ -3,3 +3,6 @@ _G.requireInjector()
local Peripheral = require('peripheral')
_G.device = Peripheral.getList()
-- register the main term in the devices list
_G.device.terminal = _G.term.current()

View File

@ -0,0 +1,68 @@
--[[
Allow sharing of local peripherals.
]]--
local Event = require('event')
local Peripheral = require('peripheral')
local Socket = require('socket')
local Util = require('util')
Event.addRoutine(function()
while true do
print('peripheral: listening on port 189')
local socket = Socket.server(189)
print('peripheral: connection from ' .. socket.dhost)
Event.addRoutine(function()
local uri = socket:read(2)
if uri then
local peripheral = Peripheral.lookup(uri)
if peripheral then
print('peripheral: proxing ' .. uri)
local proxy = {
methods = { }
}
if peripheral.blit then
peripheral = Util.shallowCopy(peripheral)
peripheral.fastBlit = function(data)
for _,v in ipairs(data) do
peripheral[v.fn](unpack(v.args))
end
end
end
for k,v in pairs(peripheral) do
if type(v) == 'function' then
table.insert(proxy.methods, k)
else
proxy[k] = v
end
end
socket:write(proxy)
if proxy.type == 'monitor' then
local h
h = Event.on('monitor_touch', function(...)
if not socket:write({ ... }) then
Event.off(h)
end
end)
end
while true do
local data = socket:read()
if not data then
print('peripheral: lost connection from ' .. socket.dhost)
break
end
socket:write({ peripheral[data.fn](table.unpack(data.args)) })
end
end
end
end)
end
end)

View File

@ -17,7 +17,7 @@ local function telnetHost(socket)
local termInfo = socket:read(5)
if not termInfo then
_G.printtError('read failed')
_G.printError('read failed')
return
end