honeylisp/link/udpdebug.fnl

95 lines
2.9 KiB
Plaintext
Raw Normal View History

(local core (require :core))
(local socket (require :socket))
(local {: int16-to-bytes : int32-to-bytes : lo : in-coro} (require :lib.util))
(local config {
2021-09-29 00:19:13 +00:00
:host "172.24.1.6"
:port 6502
})
{:cmd {
:write 0
:read 1
:jmp 2
:pause 3
:ping 4
}
:response {
:ack 0
:data 1
}
:pending {}
:msgid 0
:waiting false
:queue []
:connect
(fn [self ?port ?host]
(when (not self.connection)
(local [port host] [(or ?port config.port) (or ?host config.host)])
(set self.connection (assert (socket.udp)))
(assert (self.connection:setpeername host port))
(self.connection:settimeout 0)
(core.add_thread #(while (self:connected?) (self:receive) (coroutine.yield)) self.connection)))
:connected? (fn [self] (not= self.connection nil))
:disconnect
(fn [self]
(when self.connection
(self.connection:close)
(set self.connection nil)
(set self.pending {})))
:next-msgid
(fn [self]
(set self.msgid (lo (+ self.msgid 1)))
self.msgid)
:send
(fn [self cmd ?data ?callback]
(self:enqueue
#(let [msgid (self:next-msgid)
msg (.. (string.char msgid cmd) (or ?data ""))]
(print "sending" msgid cmd (length msg))
(when ?callback
(tset self.pending msgid ?callback)
(set self.waiting true))
(self.connection:send msg))))
:receive
(fn [self]
(when self.connection
(let [data (self.connection:receive)]
(when data
(let [msgid (string.byte (data:sub 1 1))
cmd (string.byte (data:sub 2 2))
pendingfn (. self.pending msgid)]
2021-09-29 00:19:13 +00:00
(print "recieved" msgid cmd)
(when pendingfn
(tset self.pending msgid nil)
(pendingfn self cmd (data:sub 3)))
(set self.waiting false)))
(when (and (not self.waiting) (> (length self.queue) 0))
(let [f (. self.queue 1)]
(table.remove self.queue 1)
(f))))))
:enqueue (fn [self f] (table.insert self.queue f))
:jump (fn [self addr] (self:send self.cmd.jmp (int32-to-bytes addr)))
:coro-send
(fn [self cmd ?data]
(let [coro (coroutine.running)]
(self:send cmd ?data #(coroutine.resume coro $2 $3))
(coroutine.yield)))
:read
(fn [self addr len]
(if (> len 1450)
(let [first (self:read addr 1450)
rest (self:read (+ addr 1450) (- len 1450))]
(.. first rest))
(let [(cmd data) (self:coro-send self.cmd.read (.. (int32-to-bytes addr)
(int16-to-bytes len)))] data)))
:write
(fn [self addr data]
(if (> (length data) 1450) (do (self:write addr (data:sub 1 1400)) (self:write (+ addr 1400) (data:sub 1401)))
(self:send self.cmd.write (.. (int32-to-bytes addr)
(int16-to-bytes (length data))
data) #nil)))
:launch (fn [self prg] (self:jump (prg:lookup-addr prg.start-symbol)))
}