@effindomv2/fui-rs 0.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (115) hide show
  1. package/COMMERCIAL.md +7 -0
  2. package/Cargo.toml +34 -0
  3. package/LICENSE.md +9 -0
  4. package/README.md +88 -0
  5. package/package.json +54 -0
  6. package/scripts/build.sh +227 -0
  7. package/scripts/check-runtime-dependency.sh +41 -0
  8. package/scripts/framework-host-services.ts +40 -0
  9. package/scripts/generate-host-events.ts +17 -0
  10. package/scripts/generate-host-services.ts +28 -0
  11. package/scripts/hostgen/common.ts +73 -0
  12. package/scripts/hostgen/registry.ts +159 -0
  13. package/scripts/hostgen/rust-host-events.ts +171 -0
  14. package/scripts/hostgen/rust-host-services.ts +257 -0
  15. package/src/animation.rs +625 -0
  16. package/src/app.rs +324 -0
  17. package/src/assets.rs +572 -0
  18. package/src/bindings/mod.rs +1 -0
  19. package/src/bindings/ui.rs +705 -0
  20. package/src/bitmap.rs +317 -0
  21. package/src/bridge_callbacks.rs +242 -0
  22. package/src/context_menu_manager.rs +332 -0
  23. package/src/controls/anti_selection_area.rs +54 -0
  24. package/src/controls/button.rs +542 -0
  25. package/src/controls/checkbox.rs +372 -0
  26. package/src/controls/combobox.rs +1574 -0
  27. package/src/controls/context_menu.rs +1367 -0
  28. package/src/controls/control_template_set.rs +46 -0
  29. package/src/controls/control_tokens.rs +596 -0
  30. package/src/controls/dialog.rs +590 -0
  31. package/src/controls/dropdown.rs +1010 -0
  32. package/src/controls/form.rs +229 -0
  33. package/src/controls/internal/button_presenter.rs +142 -0
  34. package/src/controls/internal/checkbox_indicator_presenter.rs +210 -0
  35. package/src/controls/internal/dropdown_chevron_presenter.rs +134 -0
  36. package/src/controls/internal/dropdown_field_presenter.rs +269 -0
  37. package/src/controls/internal/dropdown_option_row_presenter.rs +184 -0
  38. package/src/controls/internal/mod.rs +13 -0
  39. package/src/controls/internal/pressable_indicator_presenter.rs +26 -0
  40. package/src/controls/internal/pressable_labeled_control.rs +492 -0
  41. package/src/controls/internal/radio_indicator_presenter.rs +208 -0
  42. package/src/controls/internal/selectable_popup_list.rs +597 -0
  43. package/src/controls/internal/slider_presenter.rs +282 -0
  44. package/src/controls/internal/switch_indicator_presenter.rs +235 -0
  45. package/src/controls/internal/text_input_core.rs +1074 -0
  46. package/src/controls/internal/text_input_presenter.rs +108 -0
  47. package/src/controls/mod.rs +235 -0
  48. package/src/controls/nav_link.rs +395 -0
  49. package/src/controls/popup.rs +191 -0
  50. package/src/controls/progress_bar.rs +287 -0
  51. package/src/controls/radio_button.rs +348 -0
  52. package/src/controls/radio_group.rs +283 -0
  53. package/src/controls/selection_area.rs +82 -0
  54. package/src/controls/shared.rs +68 -0
  55. package/src/controls/slider.rs +701 -0
  56. package/src/controls/switch.rs +293 -0
  57. package/src/controls/templating.rs +49 -0
  58. package/src/controls/tests.rs +3905 -0
  59. package/src/controls/text_area.rs +207 -0
  60. package/src/controls/text_input.rs +192 -0
  61. package/src/debug.rs +146 -0
  62. package/src/drag_drop.rs +424 -0
  63. package/src/drag_gesture.rs +258 -0
  64. package/src/drawing.rs +385 -0
  65. package/src/event.rs +1603 -0
  66. package/src/external_drop.rs +467 -0
  67. package/src/fetch.rs +500 -0
  68. package/src/ffi.rs +3542 -0
  69. package/src/file.rs +1677 -0
  70. package/src/focus_adorner.rs +307 -0
  71. package/src/focus_visibility.rs +121 -0
  72. package/src/frame_scheduler.rs +159 -0
  73. package/src/frame_signal.rs +64 -0
  74. package/src/generated/ffi.rs +798 -0
  75. package/src/generated/framework_host_services.rs +74 -0
  76. package/src/generated/mod.rs +2 -0
  77. package/src/host_services.rs +162 -0
  78. package/src/image_sampling.rs +78 -0
  79. package/src/keyboard_scroll.rs +137 -0
  80. package/src/keyboard_scroll_tracker.rs +385 -0
  81. package/src/lib.rs +547 -0
  82. package/src/logger.rs +56 -0
  83. package/src/mobile_text_selection_toolbar.rs +1034 -0
  84. package/src/navigation.rs +48 -0
  85. package/src/node/core.rs +2210 -0
  86. package/src/node/custom_drawable.rs +149 -0
  87. package/src/node/flex_box.rs +874 -0
  88. package/src/node/grid.rs +304 -0
  89. package/src/node/helpers.rs +442 -0
  90. package/src/node/image.rs +506 -0
  91. package/src/node/mod.rs +315 -0
  92. package/src/node/scroll_bar.rs +845 -0
  93. package/src/node/scroll_box.rs +514 -0
  94. package/src/node/scroll_state.rs +121 -0
  95. package/src/node/scroll_view.rs +557 -0
  96. package/src/node/svg_node.rs +474 -0
  97. package/src/node/text_node.rs +633 -0
  98. package/src/node/virtual_list.rs +678 -0
  99. package/src/panic_hook.rs +36 -0
  100. package/src/persisted.rs +274 -0
  101. package/src/platform.rs +556 -0
  102. package/src/popup_presenter.rs +344 -0
  103. package/src/selection_handle_adorner.rs +838 -0
  104. package/src/signal.rs +134 -0
  105. package/src/text.rs +1065 -0
  106. package/src/theme.rs +571 -0
  107. package/src/timers.rs +106 -0
  108. package/src/tool_tip.rs +167 -0
  109. package/src/tool_tip_manager.rs +691 -0
  110. package/src/transitions.rs +41 -0
  111. package/src/typography.rs +520 -0
  112. package/src/viewport.rs +108 -0
  113. package/src/worker.rs +308 -0
  114. package/src/worker_job.rs +82 -0
  115. package/src/worker_runtime.rs +172 -0
package/src/worker.rs ADDED
@@ -0,0 +1,308 @@
1
+ use std::cell::RefCell;
2
+ use std::collections::HashMap;
3
+ use std::rc::Rc;
4
+
5
+ use crate::ffi;
6
+
7
+ type ProgressCallback = Rc<dyn Fn(WorkerProgressEventArgs)>;
8
+ type CompleteCallback = Rc<dyn Fn(WorkerCompletedEventArgs)>;
9
+ type ErrorCallback = Rc<dyn Fn(WorkerErrorEventArgs)>;
10
+ const MAX_WORKER_START_INPUT_BYTES: usize = 1024 * 1024;
11
+
12
+ thread_local! {
13
+ static NEXT_WORKER_ID: RefCell<u32> = const { RefCell::new(1) };
14
+ static ACTIVE_WORKERS: RefCell<HashMap<u32, Rc<RefCell<WorkerInner>>>> = RefCell::new(HashMap::new());
15
+ }
16
+
17
+ fn with_utf8(value: &str, callback: impl FnOnce(usize, u32)) {
18
+ let bytes = value.as_bytes();
19
+ callback(
20
+ if bytes.is_empty() {
21
+ 0
22
+ } else {
23
+ bytes.as_ptr() as usize
24
+ },
25
+ bytes.len() as u32,
26
+ );
27
+ }
28
+
29
+ #[derive(Clone, Debug, PartialEq, Eq)]
30
+ pub struct WorkerProgressEventArgs {
31
+ pub message: String,
32
+ }
33
+
34
+ #[derive(Clone, Debug, PartialEq, Eq)]
35
+ pub struct WorkerCompletedEventArgs {
36
+ pub result: String,
37
+ }
38
+
39
+ #[derive(Clone, Debug, PartialEq, Eq)]
40
+ pub struct WorkerErrorEventArgs {
41
+ pub message: String,
42
+ }
43
+
44
+ struct WorkerInner {
45
+ worker_id: u32,
46
+ wasm_path: String,
47
+ entry_name: String,
48
+ on_progress: Option<ProgressCallback>,
49
+ on_complete: Option<CompleteCallback>,
50
+ on_error: Option<ErrorCallback>,
51
+ started: bool,
52
+ finished: bool,
53
+ cancel_requested: bool,
54
+ }
55
+
56
+ pub struct Worker {
57
+ inner: Rc<RefCell<WorkerInner>>,
58
+ }
59
+
60
+ impl Worker {
61
+ pub fn new(wasm_path: impl Into<String>, entry_name: impl Into<String>) -> Self {
62
+ let worker_id = NEXT_WORKER_ID.with(|next| {
63
+ let mut slot = next.borrow_mut();
64
+ let id = *slot;
65
+ *slot += 1;
66
+ id
67
+ });
68
+ let worker = Self {
69
+ inner: Rc::new(RefCell::new(WorkerInner {
70
+ worker_id,
71
+ wasm_path: wasm_path.into(),
72
+ entry_name: entry_name.into(),
73
+ on_progress: None,
74
+ on_complete: None,
75
+ on_error: None,
76
+ started: false,
77
+ finished: false,
78
+ cancel_requested: false,
79
+ })),
80
+ };
81
+ ACTIVE_WORKERS.with(|workers| {
82
+ workers.borrow_mut().insert(worker_id, worker.inner.clone());
83
+ });
84
+ worker
85
+ }
86
+
87
+ pub fn on_progress(self, handler: impl Fn(WorkerProgressEventArgs) + 'static) -> Self {
88
+ self.inner.borrow_mut().on_progress = Some(Rc::new(handler));
89
+ self
90
+ }
91
+
92
+ pub fn on_complete(self, handler: impl Fn(WorkerCompletedEventArgs) + 'static) -> Self {
93
+ self.inner.borrow_mut().on_complete = Some(Rc::new(handler));
94
+ self
95
+ }
96
+
97
+ pub fn on_error(self, handler: impl Fn(WorkerErrorEventArgs) + 'static) -> Self {
98
+ self.inner.borrow_mut().on_error = Some(Rc::new(handler));
99
+ self
100
+ }
101
+
102
+ pub fn start(self, input: impl Into<String>) -> Self {
103
+ let input = input.into();
104
+ let already_started = {
105
+ let inner = self.inner.borrow();
106
+ inner.started || inner.finished
107
+ };
108
+ if already_started {
109
+ return self;
110
+ }
111
+ if input.as_bytes().len() > MAX_WORKER_START_INPUT_BYTES {
112
+ let (worker_id, callback) = {
113
+ let mut inner = self.inner.borrow_mut();
114
+ inner.started = true;
115
+ inner.finished = true;
116
+ (inner.worker_id, inner.on_error.clone())
117
+ };
118
+ finish_worker(worker_id);
119
+ if let Some(callback) = callback {
120
+ callback(WorkerErrorEventArgs {
121
+ message: format!(
122
+ "Worker.start input exceeds the maximum UTF-8 payload size of {} bytes.",
123
+ MAX_WORKER_START_INPUT_BYTES
124
+ ),
125
+ });
126
+ }
127
+ return self;
128
+ }
129
+ let start_info = {
130
+ let mut inner = self.inner.borrow_mut();
131
+ inner.started = true;
132
+ (
133
+ inner.worker_id,
134
+ inner.wasm_path.clone(),
135
+ inner.entry_name.clone(),
136
+ )
137
+ };
138
+ with_utf8(&start_info.1, |wasm_path_ptr, wasm_path_len| {
139
+ with_utf8(&start_info.2, |entry_ptr, entry_len| {
140
+ with_utf8(&input, |input_ptr, input_len| unsafe {
141
+ ffi::fui_worker_start_string(
142
+ start_info.0,
143
+ wasm_path_ptr,
144
+ wasm_path_len,
145
+ entry_ptr,
146
+ entry_len,
147
+ input_ptr,
148
+ input_len,
149
+ );
150
+ })
151
+ })
152
+ });
153
+ self
154
+ }
155
+
156
+ pub fn cancel(&self) {
157
+ let worker_id = {
158
+ let mut inner = self.inner.borrow_mut();
159
+ if !inner.started || inner.finished || inner.cancel_requested {
160
+ return;
161
+ }
162
+ inner.cancel_requested = true;
163
+ inner.worker_id
164
+ };
165
+ unsafe { ffi::fui_worker_cancel(worker_id) };
166
+ }
167
+ }
168
+
169
+ impl Drop for Worker {
170
+ fn drop(&mut self) {
171
+ self.cancel();
172
+ finish_worker(self.inner.borrow().worker_id);
173
+ }
174
+ }
175
+
176
+ fn finish_worker(worker_id: u32) -> Option<Rc<RefCell<WorkerInner>>> {
177
+ ACTIVE_WORKERS.with(|workers| workers.borrow_mut().remove(&worker_id))
178
+ }
179
+
180
+ fn with_active_worker(worker_id: u32, callback: impl FnOnce(&mut WorkerInner)) {
181
+ let Some(worker) = ACTIVE_WORKERS.with(|workers| workers.borrow().get(&worker_id).cloned())
182
+ else {
183
+ return;
184
+ };
185
+ let mut inner = worker.borrow_mut();
186
+ callback(&mut inner);
187
+ }
188
+
189
+ #[no_mangle]
190
+ pub extern "C" fn __fui_on_worker_progress(worker_id: u32, text_ptr: *const u8, text_len: u32) {
191
+ let message = if text_ptr.is_null() || text_len == 0 {
192
+ String::new()
193
+ } else {
194
+ String::from_utf8_lossy(unsafe { std::slice::from_raw_parts(text_ptr, text_len as usize) })
195
+ .into_owned()
196
+ };
197
+ with_active_worker(worker_id, |inner| {
198
+ if inner.finished || inner.cancel_requested {
199
+ return;
200
+ }
201
+ if let Some(callback) = inner.on_progress.clone() {
202
+ callback(WorkerProgressEventArgs { message });
203
+ }
204
+ });
205
+ }
206
+
207
+ #[no_mangle]
208
+ pub extern "C" fn __fui_on_worker_complete(worker_id: u32, text_ptr: *const u8, text_len: u32) {
209
+ let result = if text_ptr.is_null() || text_len == 0 {
210
+ String::new()
211
+ } else {
212
+ String::from_utf8_lossy(unsafe { std::slice::from_raw_parts(text_ptr, text_len as usize) })
213
+ .into_owned()
214
+ };
215
+ let Some(worker) = finish_worker(worker_id) else {
216
+ return;
217
+ };
218
+ let callback = {
219
+ let mut inner = worker.borrow_mut();
220
+ if inner.finished {
221
+ return;
222
+ }
223
+ inner.finished = true;
224
+ inner.on_complete.clone()
225
+ };
226
+ if let Some(callback) = callback {
227
+ callback(WorkerCompletedEventArgs { result });
228
+ }
229
+ }
230
+
231
+ #[no_mangle]
232
+ pub extern "C" fn __fui_on_worker_error(worker_id: u32, text_ptr: *const u8, text_len: u32) {
233
+ let message = if text_ptr.is_null() || text_len == 0 {
234
+ String::new()
235
+ } else {
236
+ String::from_utf8_lossy(unsafe { std::slice::from_raw_parts(text_ptr, text_len as usize) })
237
+ .into_owned()
238
+ };
239
+ let Some(worker) = finish_worker(worker_id) else {
240
+ return;
241
+ };
242
+ let callback = {
243
+ let mut inner = worker.borrow_mut();
244
+ if inner.finished {
245
+ return;
246
+ }
247
+ inner.finished = true;
248
+ inner.on_error.clone()
249
+ };
250
+ if let Some(callback) = callback {
251
+ callback(WorkerErrorEventArgs { message });
252
+ }
253
+ }
254
+
255
+ #[cfg(test)]
256
+ mod tests {
257
+ use super::Worker;
258
+ use crate::ffi::{self, Call};
259
+ use std::cell::RefCell;
260
+ use std::rc::Rc;
261
+
262
+ #[test]
263
+ fn worker_start_emits_host_call() {
264
+ ffi::test::reset();
265
+ let _worker = Worker::new("./workers/test.wasm", "demo").start("hello");
266
+ let calls = ffi::test::take_calls();
267
+ assert!(calls.iter().any(|call| matches!(call, Call::WorkerStartString { wasm_path, entry, input, .. } if wasm_path == "./workers/test.wasm" && entry == "demo" && input == "hello")));
268
+ }
269
+
270
+ #[test]
271
+ fn oversized_worker_start_input_reports_error_without_host_call() {
272
+ ffi::test::reset();
273
+ let error = Rc::new(RefCell::new(String::new()));
274
+ let error_clone = error.clone();
275
+ let input = "x".repeat(super::MAX_WORKER_START_INPUT_BYTES + 1);
276
+ let _worker = Worker::new("./workers/test.wasm", "demo")
277
+ .on_error(move |event| {
278
+ error_clone.replace(event.message);
279
+ })
280
+ .start(input);
281
+ let calls = ffi::test::take_calls();
282
+ assert!(!calls
283
+ .iter()
284
+ .any(|call| matches!(call, Call::WorkerStartString { .. })));
285
+ assert!(error.borrow().contains("maximum UTF-8 payload size"));
286
+ }
287
+
288
+ #[test]
289
+ fn worker_callbacks_receive_payloads() {
290
+ ffi::test::reset();
291
+ let progress = Rc::new(RefCell::new(String::new()));
292
+ let result = Rc::new(RefCell::new(String::new()));
293
+ let progress_clone = progress.clone();
294
+ let result_clone = result.clone();
295
+ let _worker = Worker::new("./workers/test.wasm", "demo")
296
+ .on_progress(move |event| {
297
+ progress_clone.replace(event.message);
298
+ })
299
+ .on_complete(move |event| {
300
+ result_clone.replace(event.result);
301
+ })
302
+ .start("hello");
303
+ super::__fui_on_worker_progress(1, b"25%".as_ptr(), 3);
304
+ super::__fui_on_worker_complete(1, b"done".as_ptr(), 4);
305
+ assert_eq!(&*progress.borrow(), "25%");
306
+ assert_eq!(&*result.borrow(), "done");
307
+ }
308
+ }
@@ -0,0 +1,82 @@
1
+ use crate::worker_runtime::WorkerRuntime;
2
+
3
+ #[derive(Default)]
4
+ pub struct WorkerJobState {
5
+ started: bool,
6
+ finished: bool,
7
+ }
8
+
9
+ impl WorkerJobState {
10
+ pub const fn new() -> Self {
11
+ Self {
12
+ started: false,
13
+ finished: false,
14
+ }
15
+ }
16
+ }
17
+
18
+ pub trait WorkerJob {
19
+ fn state(&mut self) -> &mut WorkerJobState;
20
+
21
+ fn on_start(&mut self, _input: String) {}
22
+
23
+ fn run(&mut self);
24
+
25
+ fn resume(&mut self, input: String) -> bool {
26
+ let should_start = {
27
+ let state = self.state();
28
+ if state.started {
29
+ false
30
+ } else {
31
+ state.started = true;
32
+ true
33
+ }
34
+ };
35
+ if should_start {
36
+ self.on_start(input);
37
+ }
38
+ if self.state().finished {
39
+ return false;
40
+ }
41
+ self.run();
42
+ !self.state().finished
43
+ }
44
+
45
+ fn report_progress(&mut self, progress: impl AsRef<str>) {
46
+ if self.state().finished {
47
+ return;
48
+ }
49
+ WorkerRuntime::report_progress(progress);
50
+ }
51
+
52
+ fn complete(&mut self, result: impl AsRef<str>) {
53
+ if self.state().finished {
54
+ return;
55
+ }
56
+ self.state().finished = true;
57
+ WorkerRuntime::complete(result);
58
+ }
59
+
60
+ fn fail(&mut self, message: impl AsRef<str>) {
61
+ if self.state().finished {
62
+ return;
63
+ }
64
+ self.state().finished = true;
65
+ WorkerRuntime::fail(message);
66
+ }
67
+
68
+ fn is_cancelled(&self) -> bool {
69
+ WorkerRuntime::is_cancelled()
70
+ }
71
+
72
+ fn r#yield(&mut self, delay_ms: i32) -> bool {
73
+ if self.state().finished {
74
+ return false;
75
+ }
76
+ WorkerRuntime::r#yield(delay_ms)
77
+ }
78
+
79
+ fn yield_now(&mut self, delay_ms: i32) -> bool {
80
+ self.r#yield(delay_ms)
81
+ }
82
+ }
@@ -0,0 +1,172 @@
1
+ use std::cell::{Cell, RefCell};
2
+ thread_local! {
3
+ static WORKER_TERMINAL_SENT: Cell<bool> = const { Cell::new(false) };
4
+ static WORKER_CALLBACK_BUFFER: RefCell<Box<[u8]>> =
5
+ RefCell::new(vec![0u8; 1024 * 1024].into_boxed_slice());
6
+ }
7
+
8
+ #[cfg(target_arch = "wasm32")]
9
+ #[link(wasm_import_module = "fui_worker_host")]
10
+ unsafe extern "C" {
11
+ #[link_name = "fui_worker_report_progress"]
12
+ fn host_worker_report_progress(ptr: usize, len: u32);
13
+ #[link_name = "fui_worker_complete_string"]
14
+ fn host_worker_complete_string(ptr: usize, len: u32);
15
+ #[link_name = "fui_worker_fail"]
16
+ fn host_worker_fail(ptr: usize, len: u32);
17
+ #[link_name = "fui_worker_is_cancelled"]
18
+ fn host_worker_is_cancelled() -> bool;
19
+ #[link_name = "fui_worker_request_yield"]
20
+ fn host_worker_request_yield();
21
+ #[link_name = "fui_worker_request_yield_delay"]
22
+ fn host_worker_request_yield_delay(delay_ms: i32);
23
+ #[link_name = "fui_file_read_chunk"]
24
+ fn host_file_read_chunk(offset_low: i32, offset_high: i32, max_bytes: i32) -> i32;
25
+ #[link_name = "fui_file_worker_write_chunk"]
26
+ fn host_file_worker_write_chunk(ptr: usize, len: i32);
27
+ }
28
+
29
+ #[cfg(target_arch = "wasm32")]
30
+ fn with_utf8(value: &str, callback: impl FnOnce(usize, u32)) {
31
+ let bytes = value.as_bytes();
32
+ callback(
33
+ if bytes.is_empty() {
34
+ 0
35
+ } else {
36
+ bytes.as_ptr() as usize
37
+ },
38
+ bytes.len() as u32,
39
+ );
40
+ }
41
+
42
+ pub struct WorkerRuntime;
43
+
44
+ impl WorkerRuntime {
45
+ pub fn entry_input(input_ptr: usize, input_len: u32) -> String {
46
+ if input_ptr == 0 || input_len == 0 {
47
+ return String::new();
48
+ }
49
+ let bytes =
50
+ unsafe { std::slice::from_raw_parts(input_ptr as *const u8, input_len as usize) };
51
+ String::from_utf8_lossy(bytes).into_owned()
52
+ }
53
+
54
+ pub fn report_progress(progress: impl AsRef<str>) {
55
+ if WORKER_TERMINAL_SENT.with(Cell::get) {
56
+ return;
57
+ }
58
+ #[cfg(target_arch = "wasm32")]
59
+ send_text(progress.as_ref(), |ptr, len| unsafe {
60
+ host_worker_report_progress(ptr, len);
61
+ });
62
+ #[cfg(not(target_arch = "wasm32"))]
63
+ let _ = progress.as_ref();
64
+ }
65
+
66
+ pub fn complete(result: impl AsRef<str>) {
67
+ if WORKER_TERMINAL_SENT.with(Cell::get) {
68
+ return;
69
+ }
70
+ WORKER_TERMINAL_SENT.with(|sent| sent.set(true));
71
+ #[cfg(target_arch = "wasm32")]
72
+ send_text(result.as_ref(), |ptr, len| unsafe {
73
+ host_worker_complete_string(ptr, len);
74
+ });
75
+ #[cfg(not(target_arch = "wasm32"))]
76
+ let _ = result.as_ref();
77
+ }
78
+
79
+ pub fn fail(message: impl AsRef<str>) {
80
+ if WORKER_TERMINAL_SENT.with(Cell::get) {
81
+ return;
82
+ }
83
+ WORKER_TERMINAL_SENT.with(|sent| sent.set(true));
84
+ #[cfg(target_arch = "wasm32")]
85
+ send_text(message.as_ref(), |ptr, len| unsafe {
86
+ host_worker_fail(ptr, len);
87
+ });
88
+ #[cfg(not(target_arch = "wasm32"))]
89
+ let _ = message.as_ref();
90
+ }
91
+
92
+ pub fn is_cancelled() -> bool {
93
+ #[cfg(target_arch = "wasm32")]
94
+ {
95
+ unsafe { host_worker_is_cancelled() }
96
+ }
97
+ #[cfg(not(target_arch = "wasm32"))]
98
+ {
99
+ false
100
+ }
101
+ }
102
+
103
+ pub fn r#yield(delay_ms: i32) -> bool {
104
+ if WORKER_TERMINAL_SENT.with(Cell::get) {
105
+ return false;
106
+ }
107
+ #[cfg(target_arch = "wasm32")]
108
+ unsafe {
109
+ if delay_ms > 0 {
110
+ host_worker_request_yield_delay(delay_ms);
111
+ } else {
112
+ host_worker_request_yield();
113
+ }
114
+ }
115
+ #[cfg(not(target_arch = "wasm32"))]
116
+ let _ = delay_ms;
117
+ true
118
+ }
119
+
120
+ pub fn yield_now(delay_ms: i32) -> bool {
121
+ Self::r#yield(delay_ms)
122
+ }
123
+ }
124
+
125
+ pub fn file_read_chunk(offset_low: i32, offset_high: i32, max_bytes: i32) -> i32 {
126
+ #[cfg(target_arch = "wasm32")]
127
+ {
128
+ unsafe { host_file_read_chunk(offset_low, offset_high, max_bytes) }
129
+ }
130
+ #[cfg(not(target_arch = "wasm32"))]
131
+ {
132
+ let _ = (offset_low, offset_high, max_bytes);
133
+ 0
134
+ }
135
+ }
136
+
137
+ pub fn file_worker_write_chunk(ptr: usize, len: i32) {
138
+ #[cfg(target_arch = "wasm32")]
139
+ unsafe {
140
+ host_file_worker_write_chunk(ptr, len);
141
+ }
142
+ #[cfg(not(target_arch = "wasm32"))]
143
+ {
144
+ let _ = (ptr, len);
145
+ }
146
+ }
147
+
148
+ pub fn worker_text_buffer_ptr() -> usize {
149
+ WORKER_CALLBACK_BUFFER.with(|buffer| buffer.borrow().as_ptr() as usize)
150
+ }
151
+
152
+ pub fn worker_text_buffer_size() -> u32 {
153
+ WORKER_CALLBACK_BUFFER.with(|buffer| buffer.borrow().len() as u32)
154
+ }
155
+
156
+ pub fn handle_fetch_complete(
157
+ request_id: u32,
158
+ ok: bool,
159
+ status: i32,
160
+ payload_ptr: *const u8,
161
+ payload_len: u32,
162
+ ) {
163
+ crate::fetch::__fui_on_fetch_complete(request_id, ok, status, payload_ptr, payload_len);
164
+ }
165
+
166
+ pub fn handle_fetch_error(request_id: u32, payload_ptr: *const u8, payload_len: u32) {
167
+ crate::fetch::__fui_on_fetch_error(request_id, payload_ptr, payload_len);
168
+ }
169
+
170
+ pub fn reset_worker_runtime() {
171
+ WORKER_TERMINAL_SENT.with(|sent| sent.set(false));
172
+ }