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)) { |
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 |
47 | sub results { |
48 | my ($self) = @_; |
49 | my @all; |
50 | while (my $next = $self->next) { |
51 | push @all, $next; |
52 | } |
53 | return @all; |
54 | } |
55 | |
94565614 |
56 | 1; |