File Coverage

blib/lib/AnyEvent/Onkyo.pm
Criterion Covered Total %
statement 93 115 80.8
branch 7 16 43.7
condition n/a
subroutine 23 29 79.3
pod 4 4 100.0
total 127 164 77.4


line stmt bran cond sub pod time code
1 2     2   153562 use strict;
  2         6  
  2         60  
2 2     2   10 use warnings;
  2         4  
  2         108  
3             package AnyEvent::Onkyo;
4             {
5             $AnyEvent::Onkyo::VERSION = '1.130220';
6             }
7 2     2   10 use base 'Device::Onkyo';
  2         12  
  2         1580  
8 2     2   126746 use AnyEvent::Handle;
  2         61128  
  2         70  
9 2     2   2060 use AnyEvent::SerialPort;
  2         2734  
  2         56  
10 2     2   10 use Carp qw/croak carp/;
  2         4  
  2         98  
11 2     2   1796 use Sub::Name;
  2         2336  
  2         110  
12 2     2   12 use Scalar::Util qw/weaken/;
  2         4  
  2         106  
13              
14             use constant {
15 2         2832 DEBUG => $ENV{ANYEVENT_ONKYO_DEBUG},
16 2     2   10 };
  2         4  
17              
18              
19             # ABSTRACT: AnyEvent module for controlling Onkyo/Integra AV equipment
20              
21              
22             sub new {
23 1     1 1 2721 my ($pkg, %p) = @_;
24 1 50       34 croak $pkg.'->new: callback parameter is required' unless ($p{callback});
25 1         80 my $self = $pkg->SUPER::new(device => 'discover', %p);
26 1         22 $self;
27             }
28              
29              
30             sub command {
31 1     1 1 9830 my $self = shift;
32 1         66 my $cv = AnyEvent->condvar;
33 1         9 my $weak_cv = $cv;
34 1         10 weaken $weak_cv;
35             $self->SUPER::command(@_, subname 'command_cb' => sub {
36 1 50   1   31 $weak_cv->send() if ($weak_cv);
37 1         52 });
38 1         97 return $cv;
39             }
40              
41             sub _open {
42 1     1   122 my $self = shift;
43 1         22 $self->SUPER::_open($self->_open_condvar);
44 1         9 return 1;
45             }
46              
47             sub _open_tcp_port {
48 1     1   1171 my ($self, $cv) = @_;
49 1         3 my $dev = $self->{device};
50 1         2 print STDERR "Opening $dev as tcp socket\n" if DEBUG;
51 1         5 my ($host, $port) = split /:/, $dev, 2;
52 1 50       6 $port = $self->{port} unless (defined $port);
53             $self->{handle} =
54             AnyEvent::Handle->new(connect => [$host, $port],
55             on_connect => subname('tcp_connect_cb' => sub {
56 1     1   628 my ($hdl, $h, $p) = @_;
57 1         3 warn ref $self, " connected to $h:$p\n" if DEBUG;
58 1         6 $cv->send();
59             }),
60             on_connect_error =>
61             subname('tcp_connect_error_cb' => sub {
62 0     0   0 my ($hdl, $msg) = @_;
63 0         0 my $err =
64             (ref $self).": Can't connect to $dev: $msg";
65 0         0 warn "Connect error: $err\n" if DEBUG;
66 0         0 $self->cleanup($err);
67 0         0 $cv->croak;
68 1         62 }));
69 1         23991 return $cv;
70             }
71              
72             sub _open_serial_port {
73 0     0   0 my ($self, $cv) = @_;
74 0         0 $self->{handle} =
75             AnyEvent::SerialPort->new(serial_port =>
76             [ $self->device,
77             [ baudrate => $self->baud ] ]);
78 0         0 $cv->send();
79 0         0 return $cv;
80             }
81              
82             sub _handle_setup {
83 1     1   2 my $self = shift;
84 1         4 my $handle = $self->{handle};
85 1         2 my $weak_self = $self;
86 1         5 weaken $weak_self;
87              
88             $handle->on_error(subname('on_error' => sub {
89 0     0   0 my ($hdl, $fatal, $msg) = @_;
90 0         0 print STDERR $hdl.": error $msg\n" if DEBUG;
91 0         0 $hdl->destroy;
92 0 0       0 if ($fatal) {
93 0         0 $weak_self->cleanup($msg);
94             }
95 1         37 }));
96              
97             $handle->on_eof(subname('on_eof' => sub {
98 0     0   0 my ($hdl) = @_;
99 0         0 print STDERR $hdl.": eof\n" if DEBUG;
100 0         0 $weak_self->cleanup('connection closed');
101 1         29 }));
102              
103             $handle->on_read(subname 'on_read_cb' => sub {
104 1     1   9048 my ($hdl) = @_;
105             $hdl->push_read(ref $self => $self,
106             subname 'push_read_cb' => sub {
107 1         8 $weak_self->{callback}->(@_);
108 1         8 $weak_self->_write_now();
109 1         21 return 1;
110 1         24 });
111 1         35 });
112              
113 1 50       111 $self->{handle}->on_timeout($self->{on_timeout}) if ($self->{on_timeout});
114 1 50       24 $self->{handle}->timeout($self->{timeout}) if ($self->{timeout});
115 1         3 1;
116             }
117              
118             sub DESTROY {
119 0     0   0 $_[0]->cleanup;
120             }
121              
122              
123             sub cleanup {
124 0     0 1 0 my ($self, $error) = @_;
125 0         0 print STDERR $self."->cleanup\n" if DEBUG;
126 0 0       0 $self->{handle}->destroy if ($self->{handle});
127 0         0 delete $self->{handle};
128             }
129              
130             sub _open_condvar {
131 1     1   2 my $self = shift;
132 1         1 print STDERR $self."->open_condvar\n" if DEBUG;
133 1         41 my $cv = AnyEvent->condvar;
134 1         7744 my $weak_self = $self;
135 1         8 weaken $weak_self;
136              
137             $cv->cb(subname 'open_cb' => sub {
138 1     1   13 print STDERR "start cb ", $weak_self->{handle}, " @_\n" if DEBUG;
139 1         7 $weak_self->_handle_setup();
140 1         18 $weak_self->_write_now();
141 1         38 });
142 1         122 $weak_self->{_waiting} = ['fake for async open'];
143 1         26 return $cv;
144             }
145              
146             sub _real_write {
147 1     1   16 my ($self, $str, $desc, $cb) = @_;
148 1         2 print STDERR "Sending: ", $desc, "\n" if DEBUG;
149 1         7 $self->{handle}->push_write($str);
150             }
151              
152             sub _time_now {
153 1     1   190 AnyEvent->now;
154             }
155              
156              
157             sub anyevent_read_type {
158 1     1 1 52 my ($handle, $cb, $self) = @_;
159              
160 1         3 my $weak_self = $self;
161 1         6 weaken $weak_self;
162              
163             subname 'anyevent_read_type_reader' => sub {
164 1     1   34 my ($handle) = @_;
165 1         3 my $rbuf = \$handle->{rbuf};
166 1         2 while (1) { # read all message from the buffer
167 2         4 print STDERR "Before: ", (unpack 'H*', $$rbuf||''), "\n" if DEBUG;
168 2         11 my $res = $weak_self->read_one($rbuf);
169 2 100       53 return unless ($res);
170 1         2 print STDERR "After: ", (unpack 'H*', $$rbuf), "\n" if DEBUG;
171 1         4 $res = $cb->($res);
172             }
173             }
174 1         23 }
175              
176             1;
177              
178             __END__