X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2FObject%2FRemote%2FConnection.pm;h=ea1614dfa020a4c936746e189c03b0ba396e1d06;hb=a8ac86b54bc79f9ec659086cc095687fdc020b0d;hp=1d21114a5bd9c3ea7b7f0132aac47acbf8230fa5;hpb=6db5156c142f62874d0be74b537f98e28b6708f2;p=scpubgit%2FObject-Remote.git diff --git a/lib/Object/Remote/Connection.pm b/lib/Object/Remote/Connection.pm index 1d21114..ea1614d 100644 --- a/lib/Object/Remote/Connection.pm +++ b/lib/Object/Remote/Connection.pm @@ -3,6 +3,7 @@ package Object::Remote::Connection; use Object::Remote::Future; use Object::Remote::Null; use Object::Remote::Handle; +use Object::Remote::CodeContainer; use Object::Remote; use IO::Handle; use Module::Runtime qw(use_module); @@ -57,17 +58,25 @@ has _json => ( }, ); +sub _id_to_remote_object { + my ($self, $id) = @_; + return bless({}, 'Object::Remote::Null') if $id eq 'NULL'; + ( + $self->remote_objects_by_id->{$id} + or Object::Remote::Handle->new(connection => $self, id => $id) + )->proxy; +} + sub _build__json { weaken(my $self = shift); - my $remotes = $self->remote_objects_by_id; JSON::PP->new->filter_json_single_key_object( __remote_object__ => sub { - my $id = shift; - return bless({}, 'Object::Remote::Null') if $id eq 'NULL'; - ( - $remotes->{$id} - or Object::Remote::Handle->new(connection => $self, id => $id) - )->proxy; + $self->_id_to_remote_object(@_); + } + )->filter_json_single_key_object( + __remote_code__ => sub { + my $code_container = $self->_id_to_remote_object(@_); + sub { $code_container->call(@_) }; } ); } @@ -146,20 +155,30 @@ sub _serialize { }; } +sub _local_object_to_id { + my ($self, $object) = @_; + my $id = refaddr($object); + $self->local_objects_by_id->{$id} ||= do { + push our(@New_Ids), $id; + $object; + }; + return $id; +} + sub _deobjectify { my ($self, $data) = @_; if (blessed($data)) { - my $id = refaddr($data); - $self->local_objects_by_id->{$id} ||= do { - push our(@New_Ids), $id; - $data; - }; - return +{ __remote_object__ => $id }; + return +{ __remote_object__ => $self->_local_object_to_id($data) }; } elsif (my $ref = ref($data)) { if ($ref eq 'HASH') { return +{ map +($_ => $self->_deobjectify($data->{$_})), keys %$data }; } elsif ($ref eq 'ARRAY') { return [ map $self->_deobjectify($_), @$data ]; + } elsif ($ref eq 'CODE') { + my $id = $self->_local_object_to_id( + Object::Remote::CodeContainer->new(code => $data) + ); + return +{ __remote_code__ => $id }; } else { die "Can't collapse reftype $ref"; }