package DX::ResultStream;
+use DX::Result;
use Moo;
has for_state => (is => 'ro', required => 1);
has is_exhausted => (is => 'rwp');
+has observation_policy => (is => 'ro', default => sub { sub { 0 } });
+
sub next {
my ($self) = @_;
return if $self->is_exhausted;
- my $start_state = do {
+ my $state = do {
if (my $cur = $self->_current_state) {
$cur->push_backtrack;
} else {
$self->for_state
}
};
- my $state = $self->_current_state($start_state->run);
+ STATE: while ($state = $self->_current_state($state->run)) {
+ last if $state->isa('DX::State');
+ if ($state->isa('DX::ObservationRequired')) {
+ if ($self->observation_policy->($state->observer)) {
+ my @ob = $state->observer->run;
+ $state = $state->resume;
+ while (my ($type, $value) = splice(@ob, 0, 2)) {
+ $state->facts->{$type}->set_value($value);
+ }
+ } else {
+ die "Observation refused";
+ }
+ } else {
+ die "WTF: ".$state;
+ }
+ }
unless ($state) {
$self->_set_is_exhausted(1);
return;
}
- return +{
- map +($_ => $state->scope_var($_)->bound_value), keys %{$state->scope}
- };
+ return DX::Result->new(state => $state->copy_vars);
+}
+
+sub results {
+ my ($self) = @_;
+ my @all;
+ while (my $next = $self->next) {
+ push @all, $next;
+ }
+ return @all;
}
1;