Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Implement Supply.on_demand.
Provides an easy way to create on-demand supplies.
  • Loading branch information
jnthn committed Jun 5, 2014
1 parent 609fb8f commit c0ef75e
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 0 deletions.
1 change: 1 addition & 0 deletions src/core/Supply.pm
Expand Up @@ -150,6 +150,7 @@ my role Supply {
}, *;
}

method on_demand(Supply:U: |c) { SupplyOperations.on_demand(|c) }
method for(Supply:U: |c) { SupplyOperations.for(|c) }
method interval(Supply:U: |c) { SupplyOperations.interval(|c) }
method flat(Supply:D: ) { SupplyOperations.flat(self) }
Expand Down
34 changes: 34 additions & 0 deletions src/core/SupplyOperations.pm
Expand Up @@ -35,6 +35,40 @@ my class SupplyOperations is repr('Uninstantiable') {
}
}

method on_demand(&producer, :&closing, :$scheduler = CurrentThreadScheduler) {
my class OnDemandSupply does Supply {
has &!producer;
has &!closing;
has $!scheduler;

submethod BUILD(:&!producer!, :&!closing!, :$!scheduler!) {}

method live { False }
method tap(|c) {
my $closed = False;
my $close_action;
my $sub = self.Supply::tap(|c, closing => {
$closed = True;
&!closing && &!closing();
});
$!scheduler.cue(
{
my $s = Supply.new;
$s.tap(
-> \val { $sub.more().(val) },
done => { if !$closed && $sub.done -> $t { $t() } },
quit => -> $ex { if !$closed && $sub.quit -> $t { $t($ex) } }
);
&!producer($s)
},
:catch(-> $ex { if !$closed && $sub.quit -> $t { $t($ex) } })
);
$sub
}
}
OnDemandSupply.new(:&producer, :&closing, :$scheduler)
}

method for(*@values, :$scheduler = $*SCHEDULER) {
my class ForSupply does Supply {
has @!values;
Expand Down

0 comments on commit c0ef75e

Please sign in to comment.