Commit | Line | Data |
94565614 |
1 | package DX::ResultStream; |
2 | |
deec7cc4 |
3 | use DX::Result; |
94565614 |
4 | use Moo; |
5 | |
6 | has for_state => (is => 'ro', required => 1); |
7 | |
8 | has _current_state => (is => 'rw'); |
9 | |
10 | has is_exhausted => (is => 'rwp'); |
11 | |
5ef4d923 |
12 | has observation_policy => (is => 'ro', default => sub { sub { 0 } }); |
13 | |
94565614 |
14 | sub 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)) { |
28 | my ($type, $value) = $state->observer->run; |
29 | $state = $state->resume; |
30 | $state->facts->{$type}->set_value($value); |
31 | } else { |
32 | die "Observation refused"; |
33 | } |
34 | } else { |
35 | die "WTF: ".$state; |
36 | } |
37 | } |
5622b4df |
38 | unless ($state) { |
39 | $self->_set_is_exhausted(1); |
40 | return; |
41 | } |
deec7cc4 |
42 | return DX::Result->new(state => $state->copy_vars); |
94565614 |
43 | } |
44 | |
26300a7d |
45 | sub results { |
46 | my ($self) = @_; |
47 | my @all; |
48 | while (my $next = $self->next) { |
49 | push @all, $next; |
50 | } |
51 | return @all; |
52 | } |
53 | |
94565614 |
54 | 1; |