has target_path => (is => 'ro', required => 1);
+has bound_to_path => (is => 'ro', required => 1);
+
has rebind_path => (is => 'ro', required => 1);
has new_value => (is => 'ro', required => 1);
action_applications => [ @{$hyp->action_applications}, $self ],
),
);
+ my $new_bound_to = do {
+ my $targ = $outer_hyp->scope;
+ $targ = $targ->get_member_at($_) for @{$self->bound_to_path};
+ $targ;
+ };
+ my $new_ab = DX::ActionBuilder::BoundValue->new(
+ target_path => $self->target_path,
+ rebind_path => $self->rebind_path,
+ bound_to_path => $self->bound_to_path,
+ inner_action_builder => $new_bound_to->action_builder
+ );
+ my $value_with_ab = $new_ab->apply_to_value($self->new_value, $new_bound_to);
my ($scope, @events) = $outer_hyp->scope->apply_updates(
DX::Update::SetValue->new(
target_path => $self->target_path,
- new_value => $self->new_value,
+ new_value => $value_with_ab,
)
);
my $new_bound = do {
return undef unless $inner_action;
DX::Action::SetBoundValue->new(
target_path => $self->target_path,
+ bound_to_path => $self->bound_to_path,
rebind_path => $self->rebind_path,
- new_value => $value->but_set_action_builder($self)
- ->but_set_identity_path($self->bound_to_path),
+ new_value => $value,
inner_action => $inner_action,
)
}
+sub apply_to_value {
+ my ($self, $value, $inner_value) = @_;
+ my $new_value = $value->but_set_action_builder($self)
+ ->but_set_identity_path($inner_value->identity_path);
+ return $new_value unless $new_value->isa('DX::Value::Dict');
+ my %m = %{$new_value->members};
+ return $new_value->but(
+ members => {
+ map {
+ my $this_inner = $inner_value->get_member_at($_);
+ ($_ => $self->but(
+ target_path => [ @{$self->target_path}, $_ ],
+ bound_to_path => [ @{$self->bound_to_path}, $_ ],
+ inner_action_builder => $this_inner->action_builder,
+ )->apply_to_value($m{$_}, $this_inner))
+ } keys %m
+ },
+ );
+}
+
1;
my ($self, $value) = @_;
DX::Action::SetValue->new(
target_path => $self->target_path,
- new_value => $value->but_set_action_builder($self)
- ->but_set_identity_path($self->target_path)
+ new_value => $self->apply_to_value($value),
);
}
sub action_for_add_member {
my ($self, $at, $value) = @_;
- my @add_path = (@{$self->target_path}, ref($at) ? $at->string_value : $at);
+ my $ab = $self->specialize_for_member($at);
DX::Action::AddValue->new(
- target_path => \@add_path,
- new_value => $value->but_set_action_builder(
- $self->but(target_path => \@add_path)
- )->but_set_identity_path(\@add_path)
+ target_path => $ab->target_path,
+ new_value => $ab->apply_to_value($value),
);
}
sub action_for_remove_member { die 'WHUT' }
+sub apply_to_value {
+ my ($self, $value) = @_;
+ my $new_value = $value->but_set_action_builder($self)
+ ->but_set_identity_path($self->target_path);
+ return $new_value unless $new_value->isa('DX::Value::Dict');
+ my %m = %{$new_value->members};
+ return $new_value->but(
+ members => {
+ map +($_ => $self->specialize_for_member($_)->apply_to_value($m{$_})),
+ keys %m,
+ },
+ );
+}
+
+sub specialize_for_member {
+ my ($self, $at) = @_;
+ $self->but(
+ target_path => [
+ @{$self->target_path},
+ (ref($at) ? $at->string_value : $at)
+ ],
+ );
+}
+
1;
);
return DX::Action::BindValue->new(
target_path => $self->target_path,
- new_value => $value->but_set_action_builder($ab),
+ new_value => $ab->apply_to_value($value, $value),
)
}
- my $ab = DX::ActionBuilder::Normal->new(
+ DX::ActionBuilder::Normal->new(
target_path => $self->target_path,
- );
- DX::Action::SetValue->new(
- target_path => $self->target_path,
- new_value => $value->but_set_action_builder($ab)
- ->but_set_identity_path($self->target_path),
- );
+ )->action_for_set_value($value);
}
1;