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 --> int32) is native('lirc_client') {*} my sub lirc_send_one(int32 $fd, Str $remote is encoded('utf8'), Str $keysym is encoded('utf8') --> int32) is native('lirc_client') {*} has int $!fd; submethod BUILD(Str :$socket=Str, Bool :$verbose=False) { $!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!) { my $rc = lirc_send_one($!fd, $remote, $keysym); X::Send.new().throw() if $rc != 0; } # 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); }) } }