has _store => (is => 'ro', required => 1, init_arg => 'store');
-has _class => (is => 'ro', predicate => '_has_class');
+has _class => (is => 'ro', predicate => '_has_class', init_arg => 'class');
has _set_over => (is => 'ro', required => 1, init_arg => 'set_over');
while (my ($raw) = $stream->next) {
my $obj = do {
if (my ($obj) = $self->_key_cache_get_raw($raw)) {
- $obj # can't $self->_merge($obj, $raw) since $obj might have changed
+ # can't just $self->_merge($obj, $raw) since $obj might have changed
+ $self->_refresh($obj, $raw)
} else {
$self->_add_to_key_cache($self->_inflate($raw))
}
};
push @cache, $obj;
}
+ $self->_notify_observers(all_members => \@cache);
\@cache
}
: ()
}
+## observers
+
+has _observer_callbacks => (
+ is => 'ro', isa => 'ArrayRef', default => sub { [] }
+);
+
+method _notify_observers ($event, $payload) {
+ foreach my $cb (@{$self->_observer_callbacks}) {
+ $self->$cb($event, $payload);
+ }
+}
+
## thunking between the store representation and the set representation
#
# _inflate is raw data -> final repr
$obj
}
+method _refresh ($obj, $raw) {
+ # if $obj has been changed but not flushed we'd destroy data doing
+ # a blind merge - but if $obj has change tracking of some sort then
+ # we -could- do something safely, so this method exists to be mangled
+ # by subclasses
+ $obj
+}
+
method _deflate_spec ($spec) {
$spec
}
method add ($new) {
$self->_add_to_store($new);
$self->_add_to_caches($new);
+ $self->_notify_observers(add => $new);
$new
}
method remove ($old) {
$self->_remove_from_store($old);
$self->_remove_from_caches($old);
+ $self->_notify_observers(remove => $old);
$old
}