observers
[scpubgit/DKit.git] / lib / DX / ResultStream.pm
CommitLineData
94565614 1package DX::ResultStream;
2
3use Moo;
4
5has for_state => (is => 'ro', required => 1);
6
7has _current_state => (is => 'rw');
8
9has is_exhausted => (is => 'rwp');
10
5ef4d923 11has observation_policy => (is => 'ro', default => sub { sub { 0 } });
12
94565614 13sub next {
14 my ($self) = @_;
15 return if $self->is_exhausted;
5ef4d923 16 my $state = do {
94565614 17 if (my $cur = $self->_current_state) {
5622b4df 18 $cur->push_backtrack;
94565614 19 } else {
20 $self->for_state
21 }
22 };
5ef4d923 23 STATE: while ($state = $self->_current_state($state->run)) {
24 last if $state->isa('DX::State');
25 if ($state->isa('DX::ObservationRequired')) {
26 if ($self->observation_policy->($state->observer)) {
27 my ($type, $value) = $state->observer->run;
28 $state = $state->resume;
29 $state->facts->{$type}->set_value($value);
30 } else {
31 die "Observation refused";
32 }
33 } else {
34 die "WTF: ".$state;
35 }
36 }
5622b4df 37 unless ($state) {
38 $self->_set_is_exhausted(1);
39 return;
40 }
94565614 41 return +{
42 map +($_ => $state->scope_var($_)->bound_value), keys %{$state->scope}
43 };
44}
45
26300a7d 46sub results {
47 my ($self) = @_;
48 my @all;
49 while (my $next = $self->next) {
50 push @all, $next;
51 }
52 return @all;
53}
54
94565614 551;