Skip to content

Commit

Permalink
Custom newline handling until Supply is fixed
Browse files Browse the repository at this point in the history
Also, return a Promise from run if desired instead of blocking.
  • Loading branch information
Timbus committed Dec 3, 2015
1 parent 9dc10d3 commit 651a0d2
Showing 1 changed file with 89 additions and 30 deletions.
119 changes: 89 additions & 30 deletions lib/Net/IRC/Bot.pm
Expand Up @@ -3,6 +3,68 @@ use Net::IRC::Handlers::Default;
use Net::IRC::Parser;
use Net::IRC::Event;


sub mylines(Supply:D $self, :$chomp = True ) {
use nqp;
on -> $res {
$self => do {
my str $str;
my int $chars;
my int $left;
my int $pos;
my int $nextpos;
my int $found;
my int $cr;
my int $crlf;

{
emit => -> \val {
$str = $str ~ nqp::unbox_s(val);
$chars = nqp::chars($str);
$pos = 0;

while ($left = $chars - $pos) > 0 {
$nextpos = nqp::findcclass(
nqp::const::CCLASS_NEWLINE, $str, $pos, $left
);

# no trailing line delimiter, so go buffer
last unless nqp::iscclass(
nqp::const::CCLASS_NEWLINE, $str, $nextpos
);

if $chomp {
$res.emit( ($found = $nextpos - $pos)
?? nqp::box_s(
nqp::substr($str, $pos, $found), Str)
!! ''
);
$pos = $nextpos + 1;
}
else {
$found = $nextpos - $pos + 1;
$res.emit( nqp::box_s(
nqp::substr($str, $pos, $found), Str)
);
$pos = $pos + $found;
}
}
$str = $pos < $chars
?? nqp::substr($str,$pos)
!! '';
},
done => {
if $str {
$chars = nqp::chars($str);
$res.emit( nqp::box_s($str, Str) );
}
$res.done;
}
}
}
}
}

class Net::IRC::Bot {
has $.conn is rw;

Expand Down Expand Up @@ -48,19 +110,15 @@ class Net::IRC::Bot {
}

method !connect(){
#Establish connection to server
self!reset-state;
self!disconnect();
self!reset-state();

say "Connecting to $.server on port $.port";
my role irc-connection[$debug] {
method sendln(Str $string, :$scrubbed = $string){
say "»»» $scrubbed" if $debug;
self.print($string~"\c13\c10");
}
method get(|){
my $line = callsame();
say "<-- $line" if $debug;
$line;
}
}
return IO::Socket::Async.connect($.server, $.port).then: -> $promise {
$.conn = $promise.result but irc-connection[$.debug];
Expand All @@ -85,45 +143,46 @@ class Net::IRC::Bot {
}
}

method connect-async() {
self!disconnect();

self!connect().then: sub ($promise) {
fail('Failed to connect..') if $promise.status != Kept;
method run(Bool :$async = False) {
# Connect, then attach the dispatcher to the line feed.
my $connected-promise = self!connect().then: -> $promise {
# Poke the promise to shake any failures out of it.
my $res = $promise.result;

my $input-channel = $.conn.chars-supply.lines;
my $runloop-promise = Promise.new;
$.conn.chars-supply.&mylines.act:
-> $line { self!dispatch($line) },
done => { $runloop-promise.keep(1) };

$input-channel.act: sub ($line) {
my $event = Net::IRC::Parser::RawEvent.parse($line)
or $*ERR.say("Could not parse the following IRC event: $line.perl()");
$runloop-promise;
};

self!dispatch($event) if $event;
};
if (!$async) {
# Wait to connect.
my $runloop = await $connected-promise;
await $runloop;
}

$input-channel;
};
return $connected-promise;
}

method run() {
# Wait to connect.
my $mainloop = await self.connect-async();
method !dispatch($line) {
say "<-- $line" if $.debug;

# Wait for lines to stop coming.
$mainloop.wait;
}
my $raw = Net::IRC::Parser::RawEvent.parse($line)
or $*ERR.say("Could not parse the following IRC event: $line.perl()") and return;

method !dispatch($raw) {
#Make an event object and fill it as much as we can.
#XXX: Should I just use a single cached Event to save memory?
my $who = {
'nick' => ~($raw<user><nick> // ''),
'nick' => ~($raw<user><nick> // ''),
'ident' => ~($raw<user><ident> // ''),
'host' => ~($raw<user><host> // $raw<server> // ''),
'host' => ~($raw<user><host> // $raw<server> // ''),
};
$who does role { method Str { self<nick> // self<host> } }

my $event = Net::IRC::Event.new(
:raw($raw),
:$raw,
:command(~$raw<command>),
:conn($.conn),
:state(%.state),
Expand Down

0 comments on commit 651a0d2

Please sign in to comment.