File Coverage

blib/lib/AnyEvent/LeapMotion.pm
Criterion Covered Total %
statement 27 59 45.7
branch 0 12 0.0
condition 0 3 0.0
subroutine 9 14 64.2
pod 2 4 50.0
total 38 92 41.3


line stmt bran cond sub pod time code
1             package AnyEvent::LeapMotion;
2 1     1   676 use 5.008005;
  1         2  
  1         33  
3 1     1   5 use strict;
  1         1  
  1         27  
4 1     1   6 use warnings;
  1         9  
  1         27  
5 1     1   1138 use AnyEvent::Handle;
  1         26079  
  1         36  
6 1     1   1098 use AnyEvent::Socket ();
  1         14620  
  1         35  
7 1     1   12 use JSON ();
  1         2  
  1         14  
8 1     1   907 use Protocol::WebSocket;
  1         37335  
  1         30  
9 1     1   9 use Protocol::WebSocket::Frame;
  1         2  
  1         18  
10 1     1   4 use Protocol::WebSocket::Handshake::Client;
  1         2  
  1         524  
11              
12             our $VERSION = "0.01";
13              
14             sub new {
15 0     0 1   my ($class, %args) = @_;
16 0           return bless {
17             host => '127.0.0.1',
18             port => 6437,
19             enable_gesture => 0,
20             %args,
21             frame => Protocol::WebSocket::Frame->new(),
22             }, $class;
23             }
24              
25             sub run {
26 0     0 1   my ($self, $code) = @_;
27             AnyEvent::Socket::tcp_connect $self->{host}, $self->{port}, sub {
28 0 0   0     my ($fh, $host, $port) = @_ or die "connection failed: $!";
29             $self->{handle} = AnyEvent::Handle->new(
30             fh => $fh,
31             on_eof => sub {
32 0           $_[0]->destroy;
33             },
34             on_error => sub {
35 0           $self->call(on_error => $_[1]);
36 0           $_[0]->destroy;
37             },
38 0           );
39 0           my $hs = Protocol::WebSocket::Handshake::Client->new(
40             url => "ws://$self->{host}:$self->{port}",
41             );
42 0           $self->{handle}->push_write($hs->to_string);
43             $self->{handle}->on_read(sub {
44             $self->{handle}->push_read(sub {
45 0           $hs->parse(delete $_[0]->{rbuf});
46 0 0         unless ($hs->is_done) {
47 0           $self->call(on_error => 'Handshake failed');
48             }
49 0           });
50 0 0         if ($self->{enable_gesture}) {
51 0           $self->send({enableGestures => \1}); # true
52             }
53             $self->{handle}->on_read(sub {
54             $_[0]->push_read(sub {
55 0           $self->{frame}->append(delete $_[0]->{rbuf});
56 0 0         if (my $message = $self->{frame}->next_bytes) {
57 0           my $data = JSON::decode_json($message);
58 0 0 0       if (exists $data->{id} && exists $data->{timestamp}) {
59 0           $self->call(on_frame => $data);
60             }
61             }
62 0           });
63 0           });
64 0           });
65 0           };
66             }
67              
68             sub send {
69 0     0 0   my ($self, $data) = @_;
70 0           my $message = JSON::encode_json($data);
71 0           my $frame = Protocol::WebSocket::Frame->new($message);
72 0           $self->{handle}->push_write($frame->to_bytes);
73             }
74              
75             sub call {
76 0     0 0   my ($self, $name, @args) = @_;
77 0 0         if ($self->{$name}) {
78 0           $self->{$name}->(@args);
79             }
80             }
81              
82             1;
83             __END__