package dbus_object;

sub system_bus {
    my %params = @_;
    #- use nomainloop => 1 to disable Net::DBus::Reactor main loop
    require Net::DBus;
    Net::DBus->system(%params);
}

sub new {
    my ($type, $bus, $service, $path, $interface) = @_;
    my $o = {
	bus => $bus,
	service => $service,
	path => $path,
	interface => $interface,
    };
    attach_object($o);
    bless $o, $type;
}

sub attach_object {
    my ($o) = @_;
    my $service = $o->{bus}->get_service($o->{service});
    $o->{object} = $service->get_object($o->{path}, $o->{interface});
}

sub call_method {
    my ($o, $method, @args) = @_;
    $o->{object}->$method(@args);
}

sub safe_call_method {
    my ($o, $method, @args) = @_;
    my @ret;
    eval {
        @ret = $o->call_method($method, @args);
    };
    if ($@) {
        print STDERR "($method) exception: $@\n";
        $o->{bus}{connection}->dispatch;
        return;
    }
    @ret;
}

sub set_gtk3_watch {
    my ($o) = @_;
    set_gtk3_watch_helper($o->{bus});
}

sub set_gtk3_watch_helper {
    my ($bus) = @_;
    $bus->{connection}->set_watch_callbacks(sub {
        my ($con, $watch) = @_;
        my $flags = $watch->get_flags;
        require Net::DBus::Binding::Watch;
	require Gtk3::Helper;
        if ($flags & &Net::DBus::Binding::Watch::READABLE) {
            Gtk3::Helper->add_watch($watch->get_fileno, 'in', sub {
                $watch->handle(&Net::DBus::Binding::Watch::READABLE);
                $con->dispatch;
                1;
            });
        }
        #- do nothing for WRITABLE watch, we dispatch when needed
    }, undef, undef); #- do nothing when watch is disabled or toggled yet

    $bus->{connection}->dispatch;
}

1;
