my $action = $self->builder->(map $state->resolve_value($_), @vars)
->but(dependencies => \@deps);
my ($fact_type, $value) = $action->expected_effect;
- my $id = $vars[0]->id;
- my $var = $state->by_id->{$id}->with_action($action);
- my $fact_set = $state->facts->{$fact_type}->with_value($value);
- $state->but(
- by_id => { %{$state->by_id}, $id => $var },
- facts => { %{$state->facts}, $fact_type => $fact_set },
- )
+ my $final_value = $value->but(required_action => $action);
+ my $fact_set = $state->facts->{$fact_type}->with_value($final_value);
+ $state->but(facts => { %{$state->facts}, $fact_type => $fact_set })
->then($self->next);
}
--- /dev/null
+package DX::RefSet;
+
+use DX::FactRef;
+use DX::ArrayStream;
+use Moo;
+
+has target => (is => 'ro', required => 1);
+
+has names => (is => 'ro', required => 1);
+
+sub to_stream {
+ my ($self) = @_;
+ return DX::ArrayStream->from_array(
+ map DX::FactRef->new(fact_type => $self->target, fact_id => $_),
+ @{$self->names}
+ );
+}
+
+1;
package DX::Result;
+use Safe::Isa;
use Moo;
has _state => (is => 'ro', required => 1, init_arg => 'state');
sub actions {
my ($self) = @_;
+ my $state = $self->_state;
my $by_id = $self->_state->by_id;
- return map $_->action, grep $_->has_action, values %$by_id;
+ return map $_->required_action,
+ grep $_->has_required_action,
+ grep $_->$_does('DX::Role::Fact'),
+ map $state->resolve_value($_),
+ values %$by_id;
}
sub independent_actions {
--- /dev/null
+package DX::Role::Action;
+
+use Moo::Role;
+
+has dependencies => (is => 'ro', default => sub { [] });
+
+has was_run => (is => 'rw');
+
+requires 'expected_effect';
+requires '_do_run';
+
+sub but { my ($self, @but) = @_; ref($self)->new(%$self, @but); }
+
+sub run {
+ my ($self) = @_;
+ die "Can't run, was already run" if $self->was_run;
+ my @res = $self->_do_run;
+ $self->was_run(1);
+ return @res;
+}
+
+1;
--- /dev/null
+package DX::Role::Fact;
+
+use Moo::Role;
+
+has required_action => (is => 'ro', predicate => 1);
+
+sub but { ref($_[0])->new(%{$_[0]}, @_[1..$#_]) }
+
+1;
--- /dev/null
+package DX::Role::Ref;
+
+use Moo::Role;
+
+requires 'resolve';
+
+1;
my @queue = @ids;
while (my $id = shift @queue) {
$seen{$id}++;
- push @found, $id if $by_id->{$id}->has_action;
+ my $value = $self->resolve_value($by_id->{$id});
+ push @found, $id if $value->$_does('DX::Role::Fact')
+ and $value->has_required_action;
push @queue, grep !$seen{$_}, keys %{$deps->{$id}};
}
return @found;
return;
});
-has action => (is => 'ro', predicate => 1);
-
sub is_bound {
my ($self) = @_;
$self->has_bound_value || $self->has_bound_stream || $self->has_root_set;
$self->new(%$self, bound_value => $stream);
}
-sub with_action {
- my ($self, $action) = @_;
- $self->new(%$self, action => $action);
-}
-
sub with_root_set {
my ($self, $set) = @_;
$self->new(%$self, root_set => $set);
use Moo;
+ with 'DX::Role::Fact';
+
has path => (is => 'ro', required => 1);
has info => (is => 'ro', predicate => 1);
use Moo;
+ with 'DX::Role::Fact';
+
has is_directory => (is => 'ro', default => 0);
has is_file => (is => 'ro', default => 0);
has mode => (is => 'ro', required => 1);