1#[cfg(feature = "v1_1")]
7#[cfg_attr(docsrs, doc(cfg(feature = "v1_1")))]
8use crate::DataSourceRequest;
9use crate::ffi;
10use glib::{
11 object::ObjectType as _,
12 prelude::*,
13 signal::{SignalHandlerId, connect_raw},
14 translate::*,
15};
16use std::{boxed::Box as Box_, pin::Pin};
17
18glib::wrapper! {
19 #[doc(alias = "ShumateDataSource")]
50 pub struct DataSource(Object<ffi::ShumateDataSource, ffi::ShumateDataSourceClass>);
51
52 match fn {
53 type_ => || ffi::shumate_data_source_get_type(),
54 }
55}
56
57impl DataSource {
58 pub const NONE: Option<&'static DataSource> = None;
59}
60
61pub trait DataSourceExt: IsA<DataSource> + 'static {
67 #[cfg(feature = "v1_1")]
73 #[cfg_attr(docsrs, doc(cfg(feature = "v1_1")))]
74 #[doc(alias = "shumate_data_source_get_max_zoom_level")]
75 #[doc(alias = "get_max_zoom_level")]
76 #[doc(alias = "max-zoom-level")]
77 fn max_zoom_level(&self) -> u32 {
78 unsafe { ffi::shumate_data_source_get_max_zoom_level(self.as_ref().to_glib_none().0) }
79 }
80
81 #[cfg(feature = "v1_1")]
87 #[cfg_attr(docsrs, doc(cfg(feature = "v1_1")))]
88 #[doc(alias = "shumate_data_source_get_min_zoom_level")]
89 #[doc(alias = "get_min_zoom_level")]
90 #[doc(alias = "min-zoom-level")]
91 fn min_zoom_level(&self) -> u32 {
92 unsafe { ffi::shumate_data_source_get_min_zoom_level(self.as_ref().to_glib_none().0) }
93 }
94
95 #[doc(alias = "shumate_data_source_get_tile_data_async")]
112 #[doc(alias = "get_tile_data_async")]
113 fn tile_data_async<P: FnOnce(Result<Option<glib::Bytes>, glib::Error>) + 'static>(
114 &self,
115 x: i32,
116 y: i32,
117 zoom_level: i32,
118 cancellable: Option<&impl IsA<gio::Cancellable>>,
119 callback: P,
120 ) {
121 let main_context = glib::MainContext::ref_thread_default();
122 let is_main_context_owner = main_context.is_owner();
123 let has_acquired_main_context = (!is_main_context_owner)
124 .then(|| main_context.acquire().ok())
125 .flatten();
126 assert!(
127 is_main_context_owner || has_acquired_main_context.is_some(),
128 "Async operations only allowed if the thread is owning the MainContext"
129 );
130
131 let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
132 Box_::new(glib::thread_guard::ThreadGuard::new(callback));
133 unsafe extern "C" fn tile_data_async_trampoline<
134 P: FnOnce(Result<Option<glib::Bytes>, glib::Error>) + 'static,
135 >(
136 _source_object: *mut glib::gobject_ffi::GObject,
137 res: *mut gio::ffi::GAsyncResult,
138 user_data: glib::ffi::gpointer,
139 ) {
140 unsafe {
141 let mut error = std::ptr::null_mut();
142 let ret = ffi::shumate_data_source_get_tile_data_finish(
143 _source_object as *mut _,
144 res,
145 &mut error,
146 );
147 let result = if error.is_null() {
148 Ok(from_glib_full(ret))
149 } else {
150 Err(from_glib_full(error))
151 };
152 let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
153 Box_::from_raw(user_data as *mut _);
154 let callback: P = callback.into_inner();
155 callback(result);
156 }
157 }
158 let callback = tile_data_async_trampoline::<P>;
159 unsafe {
160 ffi::shumate_data_source_get_tile_data_async(
161 self.as_ref().to_glib_none().0,
162 x,
163 y,
164 zoom_level,
165 cancellable.map(|p| p.as_ref()).to_glib_none().0,
166 Some(callback),
167 Box_::into_raw(user_data) as *mut _,
168 );
169 }
170 }
171
172 fn tile_data_future(
173 &self,
174 x: i32,
175 y: i32,
176 zoom_level: i32,
177 ) -> Pin<
178 Box_<dyn std::future::Future<Output = Result<Option<glib::Bytes>, glib::Error>> + 'static>,
179 > {
180 Box_::pin(gio::GioFuture::new(self, move |obj, cancellable, send| {
181 obj.tile_data_async(x, y, zoom_level, Some(cancellable), move |res| {
182 send.resolve(res);
183 });
184 }))
185 }
186
187 #[cfg(feature = "v1_1")]
191 #[cfg_attr(docsrs, doc(cfg(feature = "v1_1")))]
192 #[doc(alias = "shumate_data_source_set_max_zoom_level")]
193 #[doc(alias = "max-zoom-level")]
194 fn set_max_zoom_level(&self, zoom_level: u32) {
195 unsafe {
196 ffi::shumate_data_source_set_max_zoom_level(self.as_ref().to_glib_none().0, zoom_level);
197 }
198 }
199
200 #[cfg(feature = "v1_1")]
204 #[cfg_attr(docsrs, doc(cfg(feature = "v1_1")))]
205 #[doc(alias = "shumate_data_source_set_min_zoom_level")]
206 #[doc(alias = "min-zoom-level")]
207 fn set_min_zoom_level(&self, zoom_level: u32) {
208 unsafe {
209 ffi::shumate_data_source_set_min_zoom_level(self.as_ref().to_glib_none().0, zoom_level);
210 }
211 }
212
213 #[cfg(feature = "v1_1")]
228 #[cfg_attr(docsrs, doc(cfg(feature = "v1_1")))]
229 #[doc(alias = "shumate_data_source_start_request")]
230 fn start_request(
231 &self,
232 x: i32,
233 y: i32,
234 zoom_level: i32,
235 cancellable: Option<&impl IsA<gio::Cancellable>>,
236 ) -> Option<DataSourceRequest> {
237 unsafe {
238 from_glib_full(ffi::shumate_data_source_start_request(
239 self.as_ref().to_glib_none().0,
240 x,
241 y,
242 zoom_level,
243 cancellable.map(|p| p.as_ref()).to_glib_none().0,
244 ))
245 }
246 }
247
248 #[cfg_attr(feature = "v1_1", deprecated = "Since 1.1")]
264 #[doc(alias = "received-data")]
265 fn connect_received_data<F: Fn(&Self, i32, i32, i32, &glib::Bytes) + 'static>(
266 &self,
267 f: F,
268 ) -> SignalHandlerId {
269 unsafe extern "C" fn received_data_trampoline<
270 P: IsA<DataSource>,
271 F: Fn(&P, i32, i32, i32, &glib::Bytes) + 'static,
272 >(
273 this: *mut ffi::ShumateDataSource,
274 x: std::ffi::c_int,
275 y: std::ffi::c_int,
276 zoom_level: std::ffi::c_int,
277 bytes: *mut glib::ffi::GBytes,
278 f: glib::ffi::gpointer,
279 ) {
280 unsafe {
281 let f: &F = &*(f as *const F);
282 f(
283 DataSource::from_glib_borrow(this).unsafe_cast_ref(),
284 x,
285 y,
286 zoom_level,
287 &from_glib_borrow(bytes),
288 )
289 }
290 }
291 unsafe {
292 let f: Box_<F> = Box_::new(f);
293 connect_raw(
294 self.as_ptr() as *mut _,
295 c"received-data".as_ptr(),
296 Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
297 received_data_trampoline::<Self, F> as *const (),
298 )),
299 Box_::into_raw(f),
300 )
301 }
302 }
303
304 #[cfg(feature = "v1_1")]
305 #[cfg_attr(docsrs, doc(cfg(feature = "v1_1")))]
306 #[doc(alias = "max-zoom-level")]
307 fn connect_max_zoom_level_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
308 unsafe extern "C" fn notify_max_zoom_level_trampoline<
309 P: IsA<DataSource>,
310 F: Fn(&P) + 'static,
311 >(
312 this: *mut ffi::ShumateDataSource,
313 _param_spec: glib::ffi::gpointer,
314 f: glib::ffi::gpointer,
315 ) {
316 unsafe {
317 let f: &F = &*(f as *const F);
318 f(DataSource::from_glib_borrow(this).unsafe_cast_ref())
319 }
320 }
321 unsafe {
322 let f: Box_<F> = Box_::new(f);
323 connect_raw(
324 self.as_ptr() as *mut _,
325 c"notify::max-zoom-level".as_ptr(),
326 Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
327 notify_max_zoom_level_trampoline::<Self, F> as *const (),
328 )),
329 Box_::into_raw(f),
330 )
331 }
332 }
333
334 #[cfg(feature = "v1_1")]
335 #[cfg_attr(docsrs, doc(cfg(feature = "v1_1")))]
336 #[doc(alias = "min-zoom-level")]
337 fn connect_min_zoom_level_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
338 unsafe extern "C" fn notify_min_zoom_level_trampoline<
339 P: IsA<DataSource>,
340 F: Fn(&P) + 'static,
341 >(
342 this: *mut ffi::ShumateDataSource,
343 _param_spec: glib::ffi::gpointer,
344 f: glib::ffi::gpointer,
345 ) {
346 unsafe {
347 let f: &F = &*(f as *const F);
348 f(DataSource::from_glib_borrow(this).unsafe_cast_ref())
349 }
350 }
351 unsafe {
352 let f: Box_<F> = Box_::new(f);
353 connect_raw(
354 self.as_ptr() as *mut _,
355 c"notify::min-zoom-level".as_ptr(),
356 Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
357 notify_min_zoom_level_trampoline::<Self, F> as *const (),
358 )),
359 Box_::into_raw(f),
360 )
361 }
362 }
363}
364
365impl<O: IsA<DataSource>> DataSourceExt for O {}