browser_window/core/application/
c.rs1use std::{
7 os::raw::{c_char, c_int, c_void},
8 path::PathBuf,
9 ptr,
10 time::Duration,
11};
12
13use super::{ApplicationExt, ApplicationSettings};
14use crate::{error::*, prelude::*};
15
16#[derive(Clone, Copy)]
17pub struct ApplicationImpl {
18 pub(crate) inner: *mut cbw_Application,
19}
20
21impl ApplicationExt for ApplicationImpl {
22 fn assert_correct_thread(&self) { unsafe { cbw_Application_assertCorrectThread(self.inner) } }
23
24 fn dispatch(&self, work: fn(ApplicationImpl, *mut ()), _data: *mut ()) -> bool {
25 let data = Box::new(DispatchData {
26 func: work,
27 data: _data,
28 });
29
30 let data_ptr = Box::into_raw(data);
31
32 unsafe {
33 cbw_Application_dispatch(self.inner, Some(invocation_handler), data_ptr as _) != 0
34 }
35 }
36
37 fn dispatch_delayed(
38 &self, work: fn(ApplicationImpl, *mut ()), _data: *mut (), delay: Duration,
39 ) -> bool {
40 let data = Box::new(DispatchData {
41 func: work,
42 data: _data,
43 });
44
45 let data_ptr = Box::into_raw(data);
46
47 unsafe {
48 cbw_Application_dispatchDelayed(
49 self.inner,
50 Some(invocation_handler),
51 data_ptr as _,
52 delay.as_millis() as _,
53 ) != 0
54 }
55 }
56
57 fn exit(&self, exit_code: i32) { unsafe { cbw_Application_exit(self.inner, exit_code as _) } }
58
59 fn exit_threadsafe(self: &Self, exit_code: i32) {
60 unsafe { cbw_Application_exitAsync(self.inner, exit_code) }
61 }
62
63 fn initialize(
64 argc: c_int, argv: *mut *mut c_char, settings: &ApplicationSettings,
65 ) -> Result<Self> {
66 let exec_path: &str = match settings.engine_seperate_executable_path.as_ref() {
67 None => "",
68 Some(path) => path.to_str().unwrap(),
69 };
70
71 let c_settings = cbw_ApplicationSettings {
72 engine_seperate_executable_path: exec_path.into(),
73 resource_dir: settings
74 .resource_dir
75 .as_ref()
76 .unwrap_or(&PathBuf::new())
77 .as_os_str()
78 .to_string_lossy()
79 .as_ref()
80 .into(),
81 remote_debugging_port: settings.remote_debugging_port.unwrap_or(0),
82 };
83
84 let mut c_handle: *mut cbw_Application = ptr::null_mut();
85 let c_err = unsafe { cbw_Application_initialize(&mut c_handle, argc, argv, &c_settings) };
86 if c_err.code != 0 {
87 return Err(c_err.into());
88 }
89
90 Ok(Self { inner: c_handle })
91 }
92
93 fn mark_as_done(&self) { unsafe { cbw_Application_markAsDone(self.inner) }; }
94
95 fn run(&self, on_ready: fn(ApplicationImpl, *mut ()), _data: *mut ()) -> i32 {
96 let data = Box::new(DispatchData {
97 func: on_ready,
98 data: _data,
99 });
100
101 let data_ptr = Box::into_raw(data);
102
103 unsafe { cbw_Application_run(self.inner, Some(invocation_handler), data_ptr as _) }
105 }
106}
107
108struct DispatchData {
109 func: unsafe fn(ApplicationImpl, *mut ()),
110 data: *mut (),
111}
112
113unsafe extern "C" fn invocation_handler(_handle: *mut cbw_Application, _data: *mut c_void) {
114 let data_ptr = _data as *mut DispatchData;
115 let data = Box::from_raw(data_ptr);
116 let handle = ApplicationImpl { inner: _handle };
117
118 (data.func)(handle, data.data);
119}