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