Skip to main content

libshumate/subclass/
location.rs

1// Take a look at the license at the top of the repository in the LICENSE file.
2
3// rustdoc-stripper-ignore-next
4//! Traits intended for implementing the [`Location`](crate::Location) interface.
5
6use crate::{Location, prelude::*};
7use glib::subclass::prelude::*;
8use glib::translate::*;
9
10pub trait LocationImpl: ObjectImpl {
11    fn latitude(&self) -> f64 {
12        self.parent_latitude()
13    }
14
15    fn longitude(&self) -> f64 {
16        self.parent_longitude()
17    }
18
19    fn set_location(&self, latitude: f64, longitude: f64) {
20        self.parent_set_location(latitude, longitude)
21    }
22}
23
24pub trait LocationImplExt: ObjectSubclass {
25    fn parent_latitude(&self) -> f64 {
26        unsafe {
27            let type_data = Self::type_data();
28            let parent_iface = type_data.as_ref().parent_interface::<Location>()
29                as *const ffi::ShumateLocationInterface;
30
31            let func = (*parent_iface)
32                .get_latitude
33                .expect("no parent \"get_latitude\" implementation");
34
35            func(self.obj().unsafe_cast_ref::<Location>().to_glib_none().0)
36        }
37    }
38
39    fn parent_longitude(&self) -> f64 {
40        unsafe {
41            let type_data = Self::type_data();
42            let parent_iface = type_data.as_ref().parent_interface::<Location>()
43                as *const ffi::ShumateLocationInterface;
44
45            let func = (*parent_iface)
46                .get_longitude
47                .expect("no parent \"get_longitude\" implementation");
48
49            func(self.obj().unsafe_cast_ref::<Location>().to_glib_none().0)
50        }
51    }
52
53    fn parent_set_location(&self, latitude: f64, longitude: f64) {
54        unsafe {
55            let type_data = Self::type_data();
56            let parent_iface = type_data.as_ref().parent_interface::<Location>()
57                as *const ffi::ShumateLocationInterface;
58
59            let func = (*parent_iface)
60                .set_location
61                .expect("no parent \"set_location\" implementation");
62
63            func(
64                self.obj().unsafe_cast_ref::<Location>().to_glib_none().0,
65                latitude,
66                longitude,
67            )
68        }
69    }
70}
71
72impl<T: LocationImpl> LocationImplExt for T {}
73
74unsafe impl<T: LocationImpl> IsImplementable<T> for Location {
75    fn interface_init(iface: &mut glib::Interface<Self>) {
76        let iface = iface.as_mut();
77
78        iface.get_latitude = Some(location_get_latitude::<T>);
79        iface.get_longitude = Some(location_get_longitude::<T>);
80        iface.set_location = Some(location_set_location::<T>);
81    }
82}
83
84unsafe extern "C" fn location_get_latitude<T: LocationImpl>(
85    location: *mut ffi::ShumateLocation,
86) -> f64 {
87    unsafe {
88        let instance = &*(location as *mut T::Instance);
89        let imp = instance.imp();
90
91        imp.latitude()
92    }
93}
94
95unsafe extern "C" fn location_get_longitude<T: LocationImpl>(
96    location: *mut ffi::ShumateLocation,
97) -> f64 {
98    unsafe {
99        let instance = &*(location as *mut T::Instance);
100        let imp = instance.imp();
101
102        imp.longitude()
103    }
104}
105
106unsafe extern "C" fn location_set_location<T: LocationImpl>(
107    location: *mut ffi::ShumateLocation,
108    latitude: f64,
109    longitude: f64,
110) {
111    unsafe {
112        let instance = &*(location as *mut T::Instance);
113        let imp = instance.imp();
114
115        imp.set_location(latitude, longitude)
116    }
117}