#!/usr/bin/perl6
class Spawn {
has & .cb ;
has @.args ;
has $.name ;
has $.in = Channel.new ;
method receive( ) {
return $! in.receive ;
}
multi method send( Str $name, \msg) {
for @* scheduler {
if .name eq $name {
.send ( [ $! name, msg] ) ;
last;
}
}
}
multi method send( \msg) {
$! in.send ( msg) ;
}
method loop {
start {
&! cb( self, | @! args) ;
}
}
}
my @* scheduler = [ ] ;
sub main- loop( ) {
await Promise.allof (
[ @* scheduler>> .loop ]
) ;
}
sub spawn( & cb, @args, : $name) {
@* scheduler.push (
Spawn.new (
cb => & cb,
args => @args,
name => $name
)
) ;
}
& spawn( & ping, [ "pong" , 3 ] , name => "ping" ) ;
& spawn( & pong, [ ] , name => "pong" ) ;
& main- loop( ) ;
sub ping( \s, Str $name, Int $x) {
for ^ $x {
s.send ( $name, "pong" ) ;
if s.receive -> ( $ping, $msg) {
given $msg {
when / ping/ {
say "{$msg} received from {$ping}" ;
}
}
}
}
s.send ( $name, "finish" ) ;
say "ping finished!" ;
}
sub pong( \s) {
while ( True) {
if s.receive -> ( $ping, $msg) {
given $msg {
when / finish/ {
say "pong finished." ;
last;
}
when / pong/ {
say "{$msg} received from {$ping}" ;
s.send ( $ping, "ping" ) ;
}
}
}
}
}
IyEvdXNyL2Jpbi9wZXJsNgoKY2xhc3MgU3Bhd24gewoJaGFzICYuY2I7CgloYXMgQC5hcmdzOwoJaGFzICQubmFtZTsKCWhhcyAkLmluID0gQ2hhbm5lbC5uZXc7CgoJbWV0aG9kIHJlY2VpdmUoKSB7CgkJcmV0dXJuICQhaW4ucmVjZWl2ZTsKCX0KCgltdWx0aSBtZXRob2Qgc2VuZChTdHIgJG5hbWUsIFxtc2cpIHsKCQlmb3IgQCpzY2hlZHVsZXIgewoJCQlpZiAubmFtZSBlcSAkbmFtZSB7CgkJCQkuc2VuZChbJCFuYW1lLCBtc2ddKTsKCQkJCWxhc3Q7CgkJCX0KCQl9Cgl9CgoJbXVsdGkgbWV0aG9kIHNlbmQoXG1zZykgewoJCSQhaW4uc2VuZChtc2cpOwoJfQoKCW1ldGhvZCBsb29wIHsKCQlzdGFydCB7CgkJCSYhY2Ioc2VsZiwgfEAhYXJncyk7CgkJfQoJfQp9CgpteSBAKnNjaGVkdWxlciA9IFtdOwoKc3ViIG1haW4tbG9vcCgpIHsKCWF3YWl0IFByb21pc2UuYWxsb2YoCgkJWyBAKnNjaGVkdWxlcj4+Lmxvb3AgXQoJKTsKfQoKc3ViIHNwYXduKCZjYiwgQGFyZ3MsIDokbmFtZSkgewoJQCpzY2hlZHVsZXIucHVzaCgKCQlTcGF3bi5uZXcoCgkJCWNiID0+ICZjYiwKCQkJYXJncyA9PiBAYXJncywKCQkJbmFtZSA9PiAkbmFtZQoJCSkKCSk7Cn0KCiZzcGF3bigmcGluZywgWyJwb25nIiwgM10sIG5hbWUgPT4gInBpbmciKTsKJnNwYXduKCZwb25nLCBbXSwgbmFtZSA9PiAicG9uZyIpOwombWFpbi1sb29wKCk7CgpzdWIgcGluZyhccywgU3RyICRuYW1lLCBJbnQgJHgpIHsKCWZvciBeJHggewoJCXMuc2VuZCgkbmFtZSwgInBvbmciKTsKCQlpZiBzLnJlY2VpdmUgLT4gKCRwaW5nLCAkbXNnKSB7CgkJCWdpdmVuICRtc2cgewoJCQkJd2hlbiAvcGluZy8gewoJCQkJCXNheSAieyRtc2d9IHJlY2VpdmVkIGZyb20geyRwaW5nfSI7CgkJCQl9CgkJCX0KCQl9Cgl9CglzLnNlbmQoJG5hbWUsICJmaW5pc2giKTsKCXNheSAicGluZyBmaW5pc2hlZCEiOwp9CnN1YiBwb25nKFxzKSB7Cgl3aGlsZSAoVHJ1ZSkgewoJCWlmIHMucmVjZWl2ZSAtPiAoJHBpbmcsICRtc2cpIHsKCQkJZ2l2ZW4gJG1zZyB7CgkJCQl3aGVuIC9maW5pc2gvIHsKCQkJCQlzYXkgInBvbmcgZmluaXNoZWQuIjsKCQkJCQlsYXN0OwoJCQkJfQoJCQkJd2hlbiAvcG9uZy8gewoJCQkJCXNheSAieyRtc2d9IHJlY2VpdmVkIGZyb20geyRwaW5nfSI7CgkJCQkJcy5zZW5kKCRwaW5nLCAicGluZyIpOwoJCQkJfQoJCQl9CgkJfQoJfQp9