summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--lib/pure/asyncio.nim17
-rw-r--r--lib/pure/irc.nim79
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()))
-  #"""
+