Skip to content

Instantly share code, notes, and snippets.

Created April 28, 2012 13:30
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save anonymous/2519083 to your computer and use it in GitHub Desktop.
Save anonymous/2519083 to your computer and use it in GitHub Desktop.
use v6;
role Signal {
has @.slots; # a nice list of callbacks (that are methods)
multi method connect(Any:D $sender, Any:D $rcpt, Method $method){
@.slots.push([$sender, self, $rcpt, $method]);
}
multi method connect(Any:D $rcpt, Method $method){
@.slots.push([self, $rcpt, $method]);
}
}
multi trait_mod:<is>(Method $m, :$signal!){
# warn "turn method into signal";
$m does Signal;
sub handle_call($invocant, |$rest){
for $m.slots -> [$sender, $signal, $rcpt, $method] {
# say $sender.WHAT, '::', $signal, ' - ', $rcpt.WHAT, '::', &$method;
$method($rcpt, |$rest);
}
}
$m.wrap(&handle_call);
}
multi trait_mod:<is>(Routine $r, :$signal!){
# warn "turn non-method into signal";
$r does Signal;
# say $r.slots.elems;
sub handle_call(|$args){
# say "Routine signal handler called";
# say $r.slots.elems;
for $r.slots -> [$signal, $rcpt, $method] {
# say $signal, ' - ', $rcpt.WHAT, '::', &$method;
$method($rcpt, |$args);
}
}
$r.wrap(&handle_call);
}
multi sub connect(Any:D $sender, Method $signal, Any:D $rcpt, Method $slot){
$signal.connect($sender, $rcpt, $slot);
}
multi sub connect(Signal $signal, Any:D $rcpt, Method $slot){
$signal.connect($rcpt, $slot);
}
class Button {
our method pressed is signal { warn "signal fired without slots" }
}
class App {
our method exit { say "App::exit called" }
}
my Button $btn_exit .= new;
my App $app .= new;
$btn_exit.pressed;
connect($btn_exit, &Button::pressed, $app, &App::exit);
$btn_exit.pressed;
sub bare_signal_exit is signal {}
connect(&bare_signal_exit, $app, &App::exit);
bare_signal_exit;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment