allow observer to enter N facts
[scpubgit/DKit.git] / lib / DX / ResultStream.pm
index 28555a9..559c1f1 100644 (file)
@@ -1,5 +1,6 @@
 package DX::ResultStream;
 
+use DX::Result;
 use Moo;
 
 has for_state => (is => 'ro', required => 1);
@@ -8,24 +9,48 @@ has _current_state => (is => 'rw');
 
 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;