move exec code to Client.pm, add get_homedir example to Takfile
[scpubgit/Tak.git] / lib / Tak / ObjectClient.pm
1 package Tak::ObjectClient;
2
3 use Tak::ObjectProxy;
4 use Moo;
5
6 with 'Tak::Role::ObjectMangling';
7
8 has remote => (is => 'ro', required => 1);
9
10 has object_service => (is => 'lazy');
11
12 sub _build_object_service {
13   my ($self) = @_;
14   my $remote = $self->remote;
15   $remote->ensure(object_service => 'Tak::ObjectService');
16   $remote->curry('object_service');
17 }
18
19 sub proxy_method_call {
20   my ($self, @call) = @_;
21   my $client = $self->object_service;
22   my $ready = $self->encode_objects(\@call);
23   my $context = wantarray;
24   my $res = $client->do(call_method => $context => $ready);
25   my $unpacked = $self->decode_objects($res);
26   if ($context) {
27     return @$unpacked;
28   } elsif (defined $context) {
29     return $unpacked->[0];
30   } else {
31     return;
32   }
33 }
34
35 sub proxy_death {
36   my ($self, $proxy) = @_;
37   $self->client->do(remove_object => $proxy->{tag});
38 }
39
40 sub inflate {
41   my ($self, $tag) = @_;
42   bless({ client => $self, tag => $tag }, 'Tak::ObjectProxy');
43 }
44
45 sub deflate {
46   my ($self, $obj) = @_;
47   unless (ref($obj) eq 'Tak::ObjectProxy') {
48     die "Can't deflate non-proxied object ${obj}";
49   }
50   return +{ __proxied_object__ => $obj->{tag} };
51 }
52
53 sub new_object {
54   my ($self, $class, @args) = @_;
55   $self->proxy_method_call($class, 'new', @args);
56 }
57
58 1;