OpenComputers Von Neumann Machine Programs
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

105 lines
2.8 KiB

local computer = computer or require("computer")
local event = event or require("event")
local Queue = require("queue")
local net = require("net")
-- Sockets allow for simplier 2 way communicatation
-- An event listener is created to recieve incoming messages and automatically queue them
-- You should probably remember to close the socket when your done
-- You don't _nessacrily_ have to create a socket on both sides
local Socket = {}
Socket.__index = Socket
setmetatable(Socket, {
__call = function (cls, ...)
return cls.new(...)
end,
})
function Socket.new(raddr, port)
local self = setmetatable({}, Socket)
self.raddr = net.checkAddr(raddr)
self.port = port
self._queue = Queue()
-- name, local addr, remote addr, port, distance, msg
listener = function(...)
tmp = {...}
for k, v in pairs(tmp) do print(k, v) end
-- Check if port and raddr match
if tmp[3] ~= self.raddr or tmp[4] ~= self.port then
print("denied")
return
end
print("accepted")
pkt = {}
pkt.laddr, pkt.raddr, pkt.port, pkt.distance, pkt.msg = tmp[2], tmp[3], tmp[4], tmp[5], tmp[6]
self._queue:push(pkt)
end
net.open(port)
-- Create modem_message listener
self._listener = event.listen("modem_message", listener)
-- Close socket on interrupt
self._interrupter = event.listen("interrupted", function() self:close() end)
return self
end
function Socket:close()
net.close(self.port)
event.cancel(self._listener)
event.cancel(self._interrupter)
-- Mark for garbage collection. Maybe this isn't needed?
self._queue = nil
self = nil
end
-- Send along msg, data
function Socket:send(msg, ...)
t = {...}
if t ~= nil then
print("Sending " .. self.raddr .. " " .. tostring(self.port) .. " " .. msg .. " ")
else
print("Sending " .. self.raddr .. " " .. tostring(self.port) .. " " .. msg .. " ")
end
net.send(self.raddr, self.port, msg, ...)
end
-- Pop off the queue
-- blocking true if you want to block main execution until we recieve a message
-- if blocking is true you can also optionally add a timeout
function Socket:recieve(blocking, timeout)
if blocking == nil then blocking = false end
-- Get the result from the queue
local result = self._queue:pop()
-- If there is not a result and we're blocking then wait until we recieve one
if result == nil and blocking then
print("blocking")
if timeout == nil then
pkt, err = net.recv{self.port, self.raddr}
else
pkt, err = net.recv{self.port, self.raddr, timeout=timeout}
end
result = pkt
print("Some reason we got : " .. pkt.laddr .. " " .. pkt.raddr)
end
return result
end
return Socket