I am trying to write an observer pattern using a timer class which invoke its subscribers at a given interval. All while trying to understand the concept of promises in Perl6.
class Timer does Observable
{
has Promise $!p;
has Int $!interval;
has Bool $!active = False;
submethod BUILD(Int :$!interval) {}
method start {
$!p = Promise.start( {
$!active = True;
loop {
sleep($!interval);
@!action_listeners>>.actionPerformed(ActionEvent.new);
if !$!active {$!p.keep}
}
});
}
method stop {
$!active = False;
}
}
The Observer role simply just have an array with subscribers. Granted I should have made a method for updating all subscribers within the role.
role Observable {
has ActionListener @!action_listeners;
method addActionListener(ActionListener $al){
@!action_listeners.push($al);
}
method removeActionListener{
@!action_listeners.pop;
}
}
The ActionListener role simply has a actionPerformed method. The class ActionEvent might not be nessesary, it is simply an empty class at the moment.
role ActionListener
{
method actionPerformed(ActionEvent $e) { ... }
}
Running from a script:
my Subscriber $s = Subscriber.new;
my Timer $t = Timer.new(interval => 1);
$t.start;
$t.addActionListener($s);
$t.addActionListener(Subscriber.new);
.... #doing stuff that lasts for a while
$t.stop;
The subscriber class implements the ActionListener role (has a method called actionPerformed).
Though this work fine: The actionPerformed method of the subscribers get invoked until I call the stop method of the timer. While having no proper way to remove a given subscriber. Also I was wondering if there is a better way to keep/break a promise, from outside given the code loops infinitively.
I am basically wondering if I might be missing out on built in features in Perl6? Am I reinventing the wheel?