1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102
|
# (c) Sound Object Logic 2000-2001
use strict;
use Tangram::Coll;
package Tangram::AbstractSet;
use base qw( Tangram::Coll );
use Carp;
sub get_exporter
{
my ($self, $context) = @_;
my $field = $self->{name};
return $self->{deep_update} ?
sub {
my ($obj, $context) = @_;
# has collection been loaded? if not, then it hasn't been modified
return if tied $obj->{$field};
my $storage = $context->{storage};
foreach my $item ($obj->{$field}->members) {
$storage->_save($item, $context->{SAVING});
}
$storage->defer(sub { $self->defered_save(shift, $obj, $field, $self) } );
return ();
}
: sub {
my ($obj, $context) = @_;
# has collection been loaded? if not, then it hasn't been modified
return if tied $obj->{$field};
my $storage = $context->{storage};
foreach my $item ($obj->{$field}->members) {
$storage->insert($item)
unless $storage->id($item);
}
$storage->defer(sub { $self->defered_save(shift, $obj, $field, $self) } );
return ();
}
}
sub update
{
my ($self, $storage, $obj, $member, $insert, $remove) = @_;
return unless defined $obj->{$member};
my $coll_id = $storage->id($obj);
my $old_states = $storage->{scratch}{ref($self)}{$coll_id};
my $old_state = $old_states->{$member};
my %new_state = ();
foreach my $item ($obj->{$member}->members)
{
my $item_id = $storage->id($item) || croak "member $item has no id";
unless (exists $old_state->{$item_id})
{
$insert->($storage->{export_id}->($item_id));
}
$new_state{$item_id} = 1;
}
foreach my $del (keys %$old_state)
{
next if $new_state{$del};
$remove->($storage->{export_id}->($del));
}
$old_states->{$member} = \%new_state;
$storage->tx_on_rollback( sub { $old_states->{$member} = $old_state } );
}
sub remember_state
{
my ($self, $def, $storage, $obj, $member, $set) = @_;
my %new_state;
@new_state{ map { $storage->id($_) } $set->members } = 1 x $set->size;
$storage->{scratch}{ref($self)}{$storage->id($obj)}{$member} = \%new_state;
}
sub content
{
shift;
shift->members;
}
1;
|