aboutsummaryrefslogtreecommitdiff
path: root/lib/Lirc/Client.rakumod
blob: 672a3d0312e05cbd6fb0ee8b461b8519f2a938b9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
use v6.d;
use NativeCall;
 
class Lirc::Client {
    our class X::Init is Exception {
        has Int $.rc;
        method message { "Failed to init LIRC client: $!rc" }
    }
 
    our class X::Send is Exception {
        method message { "Failed to send command to LIRC client" }
    }
    
    my sub lirc_get_local_socket(Str $socket is encoded('utf8'), int32 $verbose --> int32is native('lirc_client'{*}
    my sub lirc_send_one(int32 $fdStr $remote is encoded('utf8'), Str $keysym is encoded('utf8'--> int32is native('lirc_client'{*}
    my sub lirc_deinit(--> int32is native('lirc_client'{*}
 
    has Str $!socket;
    has Bool $!verbose;
    has int $!fd;
 
    submethod BUILD(Str :$!socket=StrBool :$!verbose=False{
        $!fd = -1;
    }
 
    method !ensure-connected() {
        if ($!fd < 0{
            $!fd = lirc_get_local_socket($!socket, $!verbose ?? 1 !! 0);
            X::Init.new(rc => -$!fd).throw() if $!fd < 0;
        }
    }
 
    method !send-sync(Str :$remote!Str :$keysym!{
        self!ensure-connected();
        my $rc = lirc_send_one($!fd, $remote, $keysym);
        if $rc != 0 {
            lirc_deinit(); $!fd = -1;
            X::Send.new().throw()
        }
    }
 
    # copied from OO::Actors 
    has Lock::Async $!orderer .= new;
    method send(Str :$remote!Str :$keysym!{
        $!orderer.lock.then({
            LEAVE $!orderer.unlock;
            self!send-sync(:$remote:$keysym);
        })
    }
}