Skip to main content

tracker/
notifier.rs

1use crate::{ffi, Notifier, NotifierEvent};
2use glib::{closure_local, prelude::*, Value};
3use std::mem;
4
5pub trait NotifierExtManual {
6    #[doc(alias = "tracker_sparql_notifier_connect_events")]
7    fn connect_events<F: Fn(&Self, Option<&str>, Option<&str>, Vec<NotifierEvent>) + 'static>(
8        &self,
9        f: F,
10    ) -> glib::SignalHandlerId;
11}
12
13impl NotifierExtManual for Notifier {
14    /// Connect to the signal emitted when events are received.
15    fn connect_events<F: Fn(&Self, Option<&str>, Option<&str>, Vec<NotifierEvent>) + 'static>(
16        &self,
17        f: F,
18    ) -> glib::SignalHandlerId {
19        self.connect_closure(
20            "events",
21            true,
22            closure_local!(move |obj: Self,
23                                 service: Option<&str>,
24                                 graph: Option<&str>,
25                                 events: Value| {
26                let events: Vec<NotifierEvent> = {
27                    let events: *const glib::ffi::GPtrArray = unsafe {
28                        mem::transmute::<glib::ffi::gpointer, *const glib::ffi::GPtrArray>(
29                            glib::gobject_ffi::g_value_get_boxed(events.as_ptr()),
30                        )
31                    };
32
33                    let len = unsafe { (*events).len as u32 };
34                    let mut vec = Vec::new();
35
36                    for i in 0..len {
37                        unsafe {
38                            let pdata = (*events).pdata as u64;
39
40                            let offset = i as u64
41                                * mem::size_of::<*const ffi::TrackerNotifierEvent>() as u64;
42
43                            let mut event_pointer =
44                                *((pdata + offset) as *const *mut ffi::TrackerNotifierEvent);
45
46                            let event: &mut NotifierEvent =
47                                NotifierEvent::from_glib_ptr_borrow_mut(&mut event_pointer);
48
49                            vec.push(event.clone());
50                        }
51                    }
52                    vec
53                };
54
55                f(&obj, service, graph, events);
56            }),
57        )
58    }
59}