diff options
-rw-r--r-- | lib/pure/asyncio.nim | 17 | ||||
-rw-r--r-- | lib/pure/irc.nim | 79 |
2 files changed, 61 insertions, 35 deletions
diff --git a/lib/pure/asyncio.nim b/lib/pure/asyncio.nim index 6b384b1a7..bcaa85827 100644 --- a/lib/pure/asyncio.nim +++ b/lib/pure/asyncio.nim @@ -119,6 +119,8 @@ type handleAccept*: proc (s: PAsyncSocket) {.closure.} + handleTask*: proc (s: PAsyncSocket) {.closure.} + lineBuffer: TaintedString ## Temporary storage for ``recvLine`` sslNeedAccept: bool proto: TProtocol @@ -145,6 +147,7 @@ proc newAsyncSocket(): PAsyncSocket = result.handleRead = (proc (s: PAsyncSocket) = nil) result.handleConnect = (proc (s: PAsyncSocket) = nil) result.handleAccept = (proc (s: PAsyncSocket) = nil) + result.handleTask = (proc (s: PAsyncSocket) = nil) result.lineBuffer = "".TaintedString @@ -196,6 +199,13 @@ when defined(ssl): # handshake will set socket's ``sslNoHandshake`` field. discard PAsyncSocket(h).socket.handshake() + +proc asyncSockTask(h: PObject) = + when defined(ssl): + h.asyncSockDoHandshake() + + PAsyncSocket(h).handleTask(PAsyncSocket(h)) + proc toDelegate(sock: PAsyncSocket): PDelegate = result = newDelegate() result.deleVal = sock @@ -204,6 +214,7 @@ proc toDelegate(sock: PAsyncSocket): PDelegate = result.mode = fmReadWrite result.handleRead = asyncSockHandleRead result.handleWrite = asyncSockHandleWrite + result.task = asyncSockTask # TODO: Errors? #result.handleError = (proc (h: PObject) = assert(false)) @@ -215,10 +226,7 @@ proc toDelegate(sock: PAsyncSocket): PDelegate = if sock.info notin {SockIdle, SockClosed}: sock.deleg.open = true else: - sock.deleg.open = false - - when defined(ssl): - result.task = asyncSockDoHandshake + sock.deleg.open = false proc connect*(sock: PAsyncSocket, name: string, port = TPort(0), af: TDomain = AF_INET) = @@ -257,6 +265,7 @@ proc acceptAddr*(server: PAsyncSocket, client: var PAsyncSocket, ## ## **Note**: ``client`` needs to be initialised. assert(client != nil) + client = newAsyncSocket() var c: TSocket new(c) when defined(ssl): diff --git a/lib/pure/irc.nim b/lib/pure/irc.nim index cc9157053..60a86f2f1 100644 --- a/lib/pure/irc.nim +++ b/lib/pure/irc.nim @@ -44,10 +44,8 @@ type PAsyncIRC* = ref TAsyncIRC TAsyncIRC* = object of TIRC - userArg: PObject - handleEvent: proc (irc: var TAsyncIRC, ev: TIRCEvent, - userArg: PObject) {.nimcall.} - lineBuffer: TaintedString + handleEvent: proc (irc: var TAsyncIRC, ev: TIRCEvent) {.closure.} + asyncSock: PAsyncSocket TIRCMType* = enum MUnknown, @@ -320,12 +318,16 @@ proc connect*(irc: PAsyncIRC) = assert(irc.address != "") assert(irc.port != TPort(0)) - irc.sock = socket() - irc.sock.setBlocking(false) - irc.sock.connectAsync(irc.address, irc.port) - irc.status = SockConnecting + irc.asyncSock = AsyncSocket() + irc.asyncSock.connect(irc.address, irc.port) -proc handleConnect(h: PObject) = +proc handleConnect(s: PAsyncSocket, irc: PAsyncIRC) = + # Greet the server :) + if irc.serverPass != "": irc[].send("PASS " & irc.serverPass, true) + irc[].send("NICK " & irc.nick, true) + irc[].send("USER $1 * 0 :$2" % [irc.user, irc.realname], true) + +discard """proc handleConnect(h: PObject) = var irc = PAsyncIRC(h) # Greet the server :) @@ -334,8 +336,22 @@ proc handleConnect(h: PObject) = irc[].send("USER $1 * 0 :$2" % [irc.user, irc.realname], true) irc.status = SockConnected +""" + +proc handleRead(s: PAsyncSocket, irc: PAsyncIRC) = + var line = "".TaintedString + var ret = s.recvLine(line) + if ret: + if line == "": + var ev: TIRCEvent + irc[].close() + ev.typ = EvDisconnected + irc.handleEvent(irc[], ev) + else: + var ev = irc[].processLine(line.string) + irc.handleEvent(irc[], ev) -proc handleRead(h: PObject) = +discard """proc handleRead(h: PObject) = var irc = PAsyncIRC(h) var line = "".TaintedString var ret = irc.sock.recvLineAsync(line) @@ -352,13 +368,18 @@ proc handleRead(h: PObject) = irc[].close() ev.typ = EvDisconnected irc.handleEvent(irc[], ev, irc.userArg) - of RecvFail: nil + of RecvFail: nil""" + +proc handleTask(s: PAsyncSocket, irc: PAsyncIRC) = + var ev: TIRCEvent + if irc[].processOther(ev): + irc.handleEvent(irc[], ev) -proc handleTask(h: PObject) = +discard """proc handleTask(h: PObject) = var irc = PAsyncIRC(h) var ev: TIRCEvent if PAsyncIRC(h)[].processOther(ev): - irc.handleEvent(irc[], ev, irc.userArg) + irc.handleEvent(irc[], ev, irc.userArg)""" proc asyncIRC*(address: string, port: TPort = 6667.TPort, nick = "NimrodBot", @@ -366,9 +387,8 @@ proc asyncIRC*(address: string, port: TPort = 6667.TPort, realname = "NimrodBot", serverPass = "", joinChans: seq[string] = @[], msgLimit: bool = true, - ircEvent: proc (irc: var TAsyncIRC, ev: TIRCEvent, - userArg: PObject) {.nimcall.}, - userArg: PObject = nil): PAsyncIRC = + ircEvent: proc (irc: var TAsyncIRC, ev: TIRCEvent) {.closure.} + ): PAsyncIRC = ## Use this function if you want to use asyncio's dispatcher. ## ## **Note:** Do **NOT** use this if you're writing a simple IRC bot which only @@ -389,28 +409,25 @@ proc asyncIRC*(address: string, port: TPort = 6667.TPort, result.msgLimit = msgLimit result.messageBuffer = @[] result.handleEvent = ircEvent - result.userArg = userArg - result.lineBuffer = "" proc register*(d: PDispatcher, irc: PAsyncIRC) = ## Registers ``irc`` with dispatcher ``d``. - var dele = newDelegate() - dele.deleVal = irc - dele.getSocket = (proc (h: PObject): tuple[info: TInfo, sock: TSocket] = - if PAsyncIRC(h).status == SockConnecting or - PAsyncIRC(h).status == SockConnected: - return (PAsyncIRC(h).status, PAsyncIRC(h).sock) - else: return (SockIdle, PAsyncIRC(h).sock)) - dele.handleConnect = handleConnect - dele.handleRead = handleRead - dele.task = handleTask - d.register(dele) + irc.asyncSock.handleConnect = + proc (s: PAsyncSocket) = + handleConnect(s, irc) + irc.asyncSock.handleRead = + proc (s: PAsyncSocket) = + handleRead(s, irc) + irc.asyncSock.handleTask = + proc (s: PAsyncSocket) = + handleTask(s, irc) + d.register(irc.asyncSock) when isMainModule: #var m = parseMessage("ERROR :Closing Link: dom96.co.cc (Ping timeout: 252 seconds)") #echo(repr(m)) - #discard """ + var client = irc("amber.tenthbit.net", nick="TestBot1234", joinChans = @["#flood"]) @@ -431,5 +448,5 @@ when isMainModule: #echo( repr(event) ) #echo("Lag: ", formatFloat(client.getLag())) - #""" + |