1use crate::dynamic_item_tree::ErasedItemTreeBox;
6
7use super::*;
8use core::ptr::NonNull;
9use i_slint_core::model::{Model, ModelNotify, ModelRc, SharedVectorModel};
10use i_slint_core::slice::Slice;
11use i_slint_core::window::WindowAdapter;
12use smol_str::SmolStr;
13use std::ffi::c_void;
14use std::path::PathBuf;
15use std::rc::Rc;
16use vtable::VRef;
17
18#[unsafe(no_mangle)]
20pub extern "C" fn slint_interpreter_value_new() -> Box<Value> {
21 Box::new(Value::default())
22}
23
24#[unsafe(no_mangle)]
26pub extern "C" fn slint_interpreter_value_clone(other: &Value) -> Box<Value> {
27 Box::new(other.clone())
28}
29
30#[unsafe(no_mangle)]
32pub extern "C" fn slint_interpreter_value_destructor(val: Box<Value>) {
33 drop(val);
34}
35
36#[unsafe(no_mangle)]
37pub extern "C" fn slint_interpreter_value_eq(a: &Value, b: &Value) -> bool {
38 a == b
39}
40
41#[unsafe(no_mangle)]
43pub extern "C" fn slint_interpreter_value_new_string(str: &SharedString) -> Box<Value> {
44 Box::new(Value::String(str.clone()))
45}
46
47#[unsafe(no_mangle)]
49pub extern "C" fn slint_interpreter_value_new_double(double: f64) -> Box<Value> {
50 Box::new(Value::Number(double))
51}
52
53#[unsafe(no_mangle)]
55pub extern "C" fn slint_interpreter_value_new_bool(b: bool) -> Box<Value> {
56 Box::new(Value::Bool(b))
57}
58
59#[unsafe(no_mangle)]
61pub extern "C" fn slint_interpreter_value_new_array_model(
62 a: &SharedVector<Box<Value>>,
63) -> Box<Value> {
64 let vec = a.iter().map(|vb| vb.as_ref().clone()).collect::<SharedVector<_>>();
65 Box::new(Value::Model(ModelRc::new(SharedVectorModel::from(vec))))
66}
67
68#[unsafe(no_mangle)]
70pub extern "C" fn slint_interpreter_value_new_brush(brush: &Brush) -> Box<Value> {
71 Box::new(Value::Brush(brush.clone()))
72}
73
74#[unsafe(no_mangle)]
76pub extern "C" fn slint_interpreter_value_new_struct(struc: &StructOpaque) -> Box<Value> {
77 Box::new(Value::Struct(struc.as_struct().clone()))
78}
79
80#[unsafe(no_mangle)]
82pub extern "C" fn slint_interpreter_value_new_image(img: &Image) -> Box<Value> {
83 Box::new(Value::Image(img.clone()))
84}
85
86#[unsafe(no_mangle)]
88pub unsafe extern "C" fn slint_interpreter_value_new_model(
89 model: NonNull<u8>,
90 vtable: &ModelAdaptorVTable,
91) -> Box<Value> {
92 Box::new(Value::Model(ModelRc::new(ModelAdaptorWrapper(unsafe {
93 vtable::VBox::from_raw(NonNull::from(vtable), model)
94 }))))
95}
96
97#[unsafe(no_mangle)]
101pub extern "C" fn slint_interpreter_value_to_model(
102 val: &Value,
103 vtable: &ModelAdaptorVTable,
104) -> *const u8 {
105 if let Value::Model(m) = val
106 && let Some(m) = m.as_any().downcast_ref::<ModelAdaptorWrapper>()
107 && core::ptr::eq(m.0.get_vtable() as *const _, vtable as *const _)
108 {
109 return m.0.as_ptr();
110 }
111 core::ptr::null()
112}
113
114#[unsafe(no_mangle)]
115pub extern "C" fn slint_interpreter_value_type(val: &Value) -> ValueType {
116 val.value_type()
117}
118
119#[unsafe(no_mangle)]
120pub extern "C" fn slint_interpreter_value_to_string(val: &Value) -> Option<&SharedString> {
121 match val {
122 Value::String(v) => Some(v),
123 _ => None,
124 }
125}
126
127#[unsafe(no_mangle)]
128pub extern "C" fn slint_interpreter_value_to_number(val: &Value) -> Option<&f64> {
129 match val {
130 Value::Number(v) => Some(v),
131 _ => None,
132 }
133}
134
135#[unsafe(no_mangle)]
136pub extern "C" fn slint_interpreter_value_to_bool(val: &Value) -> Option<&bool> {
137 match val {
138 Value::Bool(v) => Some(v),
139 _ => None,
140 }
141}
142
143#[unsafe(no_mangle)]
147#[allow(clippy::borrowed_box)]
148pub extern "C" fn slint_interpreter_value_to_array(
149 val: &Box<Value>,
150 out: &mut SharedVector<Box<Value>>,
151) -> bool {
152 match val.as_ref() {
153 Value::Model(m) => {
154 let vec = m.iter().map(Box::new).collect::<SharedVector<_>>();
155 *out = vec;
156 true
157 }
158 _ => false,
159 }
160}
161
162#[unsafe(no_mangle)]
163pub extern "C" fn slint_interpreter_value_to_brush(val: &Value) -> Option<&Brush> {
164 match val {
165 Value::Brush(b) => Some(b),
166 _ => None,
167 }
168}
169
170#[unsafe(no_mangle)]
171pub extern "C" fn slint_interpreter_value_to_struct(val: &Value) -> *const StructOpaque {
172 match val {
173 Value::Struct(s) => s as *const Struct as *const StructOpaque,
174 _ => std::ptr::null(),
175 }
176}
177
178#[unsafe(no_mangle)]
179pub extern "C" fn slint_interpreter_value_to_image(val: &Value) -> Option<&Image> {
180 match val {
181 Value::Image(img) => Some(img),
182 _ => None,
183 }
184}
185
186#[unsafe(no_mangle)]
188pub extern "C" fn slint_interpreter_value_new_data_transfer(
189 data: &i_slint_core::data_transfer::DataTransfer,
190) -> Box<Value> {
191 Box::new(Value::DataTransfer(data.clone()))
192}
193
194#[unsafe(no_mangle)]
195pub extern "C" fn slint_interpreter_value_to_data_transfer(
196 val: &Value,
197) -> Option<&i_slint_core::data_transfer::DataTransfer> {
198 match val {
199 Value::DataTransfer(data) => Some(data),
200 _ => None,
201 }
202}
203
204#[unsafe(no_mangle)]
206pub extern "C" fn slint_interpreter_value_new_keys(keys: &i_slint_core::input::Keys) -> Box<Value> {
207 Box::new(Value::Keys(keys.clone()))
208}
209
210#[unsafe(no_mangle)]
211pub extern "C" fn slint_interpreter_value_to_keys(
212 val: &Value,
213) -> Option<&i_slint_core::input::Keys> {
214 match val {
215 Value::Keys(keys) => Some(keys),
216 _ => None,
217 }
218}
219
220#[unsafe(no_mangle)]
222pub extern "C" fn slint_interpreter_value_new_styled_text(
223 text: &i_slint_core::styled_text::StyledText,
224) -> Box<Value> {
225 Box::new(Value::StyledText(text.clone()))
226}
227
228#[unsafe(no_mangle)]
229pub extern "C" fn slint_interpreter_value_to_styled_text(
230 val: &Value,
231) -> Option<&i_slint_core::styled_text::StyledText> {
232 match val {
233 Value::StyledText(text) => Some(text),
234 _ => None,
235 }
236}
237
238#[unsafe(no_mangle)]
239pub extern "C" fn slint_interpreter_value_enum_to_string(
240 val: &Value,
241 result: &mut SharedString,
242) -> bool {
243 match val {
244 Value::EnumerationValue(_, value) => {
245 *result = SharedString::from(value);
246 true
247 }
248 _ => false,
249 }
250}
251
252#[unsafe(no_mangle)]
253pub extern "C" fn slint_interpreter_value_new_enum(
254 name: Slice<u8>,
255 value: Slice<u8>,
256) -> Box<Value> {
257 Box::new(Value::EnumerationValue(
258 std::str::from_utf8(&name).unwrap().to_string(),
259 std::str::from_utf8(&value).unwrap().to_string(),
260 ))
261}
262
263#[repr(C)]
264#[cfg(target_pointer_width = "64")]
265pub struct StructOpaque([usize; 6]);
266#[repr(C)]
267#[cfg(target_pointer_width = "32")]
268pub struct StructOpaque([u64; 4]);
269const _: [(); std::mem::size_of::<StructOpaque>()] = [(); std::mem::size_of::<Struct>()];
270const _: [(); std::mem::align_of::<StructOpaque>()] = [(); std::mem::align_of::<Struct>()];
271
272impl StructOpaque {
273 fn as_struct(&self) -> &Struct {
274 unsafe { std::mem::transmute::<&StructOpaque, &Struct>(self) }
276 }
277 fn as_struct_mut(&mut self) -> &mut Struct {
278 unsafe { std::mem::transmute::<&mut StructOpaque, &mut Struct>(self) }
280 }
281}
282
283#[unsafe(no_mangle)]
285pub unsafe extern "C" fn slint_interpreter_struct_new(val: *mut StructOpaque) {
286 unsafe { std::ptr::write(val as *mut Struct, Struct::default()) }
287}
288
289#[unsafe(no_mangle)]
291pub unsafe extern "C" fn slint_interpreter_struct_clone(
292 other: &StructOpaque,
293 val: *mut StructOpaque,
294) {
295 unsafe { std::ptr::write(val as *mut Struct, other.as_struct().clone()) }
296}
297
298#[unsafe(no_mangle)]
300pub unsafe extern "C" fn slint_interpreter_struct_destructor(val: *mut StructOpaque) {
301 drop(unsafe { std::ptr::read(val as *mut Struct) })
302}
303
304#[unsafe(no_mangle)]
305pub extern "C" fn slint_interpreter_struct_get_field(
306 stru: &StructOpaque,
307 name: Slice<u8>,
308) -> *mut Value {
309 if let Some(value) = stru.as_struct().get_field(std::str::from_utf8(&name).unwrap()) {
310 Box::into_raw(Box::new(value.clone()))
311 } else {
312 std::ptr::null_mut()
313 }
314}
315
316#[unsafe(no_mangle)]
317pub extern "C" fn slint_interpreter_struct_set_field(
318 stru: &mut StructOpaque,
319 name: Slice<u8>,
320 value: &Value,
321) {
322 stru.as_struct_mut().set_field(std::str::from_utf8(&name).unwrap().into(), value.clone())
323}
324
325type StructIterator<'a> = std::collections::hash_map::Iter<'a, SmolStr, Value>;
326#[repr(C)]
327pub struct StructIteratorOpaque<'a>([usize; 5], std::marker::PhantomData<StructIterator<'a>>);
328const _: [(); std::mem::size_of::<StructIteratorOpaque>()] =
329 [(); std::mem::size_of::<StructIterator>()];
330const _: [(); std::mem::align_of::<StructIteratorOpaque>()] =
331 [(); std::mem::align_of::<StructIterator>()];
332
333#[unsafe(no_mangle)]
334pub unsafe extern "C" fn slint_interpreter_struct_iterator_destructor(
335 val: *mut StructIteratorOpaque,
336) {
337 #[allow(clippy::drop_non_drop)] drop(unsafe { std::ptr::read(val as *mut StructIterator) })
339}
340
341#[unsafe(no_mangle)]
343pub unsafe extern "C" fn slint_interpreter_struct_iterator_next<'a>(
344 iter: &'a mut StructIteratorOpaque,
345 k: &mut Slice<'a, u8>,
346) -> *mut Value {
347 if let Some((str, val)) =
348 unsafe { (*(iter as *mut StructIteratorOpaque as *mut StructIterator)).next() }
349 {
350 *k = Slice::from_slice(str.as_bytes());
351 Box::into_raw(Box::new(val.clone()))
352 } else {
353 *k = Slice::default();
354 std::ptr::null_mut()
355 }
356}
357
358#[unsafe(no_mangle)]
359pub extern "C" fn slint_interpreter_struct_make_iter(
360 stru: &StructOpaque,
361) -> StructIteratorOpaque<'_> {
362 let ret_it: StructIterator = stru.as_struct().0.iter();
363 unsafe {
364 let mut r = std::mem::MaybeUninit::<StructIteratorOpaque>::uninit();
365 std::ptr::write(r.as_mut_ptr() as *mut StructIterator, ret_it);
366 r.assume_init()
367 }
368}
369
370#[unsafe(no_mangle)]
372pub extern "C" fn slint_interpreter_component_instance_get_property(
373 inst: &ErasedItemTreeBox,
374 name: Slice<u8>,
375) -> *mut Value {
376 generativity::make_guard!(guard);
377 let comp = inst.unerase(guard);
378 match comp
379 .description()
380 .get_property(comp.borrow(), &normalize_identifier(std::str::from_utf8(&name).unwrap()))
381 {
382 Ok(val) => Box::into_raw(Box::new(val)),
383 Err(_) => std::ptr::null_mut(),
384 }
385}
386
387#[unsafe(no_mangle)]
388pub extern "C" fn slint_interpreter_component_instance_set_property(
389 inst: &ErasedItemTreeBox,
390 name: Slice<u8>,
391 val: &Value,
392) -> bool {
393 generativity::make_guard!(guard);
394 let comp = inst.unerase(guard);
395 comp.description()
396 .set_property(
397 comp.borrow(),
398 &normalize_identifier(std::str::from_utf8(&name).unwrap()),
399 val.clone(),
400 )
401 .is_ok()
402}
403
404#[unsafe(no_mangle)]
406pub extern "C" fn slint_interpreter_component_instance_invoke(
407 inst: &ErasedItemTreeBox,
408 name: Slice<u8>,
409 args: Slice<Box<Value>>,
410) -> *mut Value {
411 let args = args.iter().map(|vb| vb.as_ref().clone()).collect::<Vec<_>>();
412 generativity::make_guard!(guard);
413 let comp = inst.unerase(guard);
414 match comp.description().invoke(
415 comp.borrow(),
416 &normalize_identifier(std::str::from_utf8(&name).unwrap()),
417 args.as_slice(),
418 ) {
419 Ok(val) => Box::into_raw(Box::new(val)),
420 Err(_) => std::ptr::null_mut(),
421 }
422}
423
424pub struct CallbackUserData {
429 user_data: *mut c_void,
430 drop_user_data: Option<extern "C" fn(*mut c_void)>,
431 callback: extern "C" fn(user_data: *mut c_void, arg: Slice<Box<Value>>) -> Box<Value>,
432}
433
434impl Drop for CallbackUserData {
435 fn drop(&mut self) {
436 if let Some(x) = self.drop_user_data {
437 x(self.user_data)
438 }
439 }
440}
441
442impl CallbackUserData {
443 pub unsafe fn new(
444 user_data: *mut c_void,
445 drop_user_data: Option<extern "C" fn(*mut c_void)>,
446 callback: extern "C" fn(user_data: *mut c_void, arg: Slice<Box<Value>>) -> Box<Value>,
447 ) -> Self {
448 Self { user_data, drop_user_data, callback }
449 }
450
451 pub fn call(&self, args: &[Value]) -> Value {
452 let args = args.iter().map(|v| v.clone().into()).collect::<Vec<_>>();
453 (self.callback)(self.user_data, Slice::from_slice(args.as_ref())).as_ref().clone()
454 }
455}
456
457#[unsafe(no_mangle)]
460pub unsafe extern "C" fn slint_interpreter_component_instance_set_callback(
461 inst: &ErasedItemTreeBox,
462 name: Slice<u8>,
463 callback: extern "C" fn(user_data: *mut c_void, arg: Slice<Box<Value>>) -> Box<Value>,
464 user_data: *mut c_void,
465 drop_user_data: Option<extern "C" fn(*mut c_void)>,
466) -> bool {
467 let ud = unsafe { CallbackUserData::new(user_data, drop_user_data, callback) };
468
469 generativity::make_guard!(guard);
470 let comp = inst.unerase(guard);
471 comp.description()
472 .set_callback_handler(
473 comp.borrow(),
474 &normalize_identifier(std::str::from_utf8(&name).unwrap()),
475 Box::new(move |args| ud.call(args)),
476 )
477 .is_ok()
478}
479
480#[unsafe(no_mangle)]
482pub unsafe extern "C" fn slint_interpreter_component_instance_get_global_property(
483 inst: &ErasedItemTreeBox,
484 global: Slice<u8>,
485 property_name: Slice<u8>,
486) -> *mut Value {
487 generativity::make_guard!(guard);
488 let comp = inst.unerase(guard);
489 match comp
490 .description()
491 .get_global(comp.borrow(), &normalize_identifier(std::str::from_utf8(&global).unwrap()))
492 .and_then(|g| {
493 g.as_ref()
494 .get_property(&normalize_identifier(std::str::from_utf8(&property_name).unwrap()))
495 }) {
496 Ok(val) => Box::into_raw(Box::new(val)),
497 Err(_) => std::ptr::null_mut(),
498 }
499}
500
501#[unsafe(no_mangle)]
502pub extern "C" fn slint_interpreter_component_instance_set_global_property(
503 inst: &ErasedItemTreeBox,
504 global: Slice<u8>,
505 property_name: Slice<u8>,
506 val: &Value,
507) -> bool {
508 generativity::make_guard!(guard);
509 let comp = inst.unerase(guard);
510 comp.description()
511 .get_global(comp.borrow(), &normalize_identifier(std::str::from_utf8(&global).unwrap()))
512 .and_then(|g| {
513 g.as_ref()
514 .set_property(
515 &normalize_identifier(std::str::from_utf8(&property_name).unwrap()),
516 val.clone(),
517 )
518 .map_err(|_| ())
519 })
520 .is_ok()
521}
522
523#[unsafe(no_mangle)]
525pub unsafe extern "C" fn slint_interpreter_component_instance_set_global_callback(
526 inst: &ErasedItemTreeBox,
527 global: Slice<u8>,
528 name: Slice<u8>,
529 callback: extern "C" fn(user_data: *mut c_void, arg: Slice<Box<Value>>) -> Box<Value>,
530 user_data: *mut c_void,
531 drop_user_data: Option<extern "C" fn(*mut c_void)>,
532) -> bool {
533 let ud = unsafe { CallbackUserData::new(user_data, drop_user_data, callback) };
534
535 generativity::make_guard!(guard);
536 let comp = inst.unerase(guard);
537 comp.description()
538 .get_global(comp.borrow(), &normalize_identifier(std::str::from_utf8(&global).unwrap()))
539 .and_then(|g| {
540 g.as_ref().set_callback_handler(
541 &normalize_identifier(std::str::from_utf8(&name).unwrap()),
542 Box::new(move |args| ud.call(args)),
543 )
544 })
545 .is_ok()
546}
547
548#[unsafe(no_mangle)]
550pub unsafe extern "C" fn slint_interpreter_component_instance_invoke_global(
551 inst: &ErasedItemTreeBox,
552 global: Slice<u8>,
553 callable_name: Slice<u8>,
554 args: Slice<Box<Value>>,
555) -> *mut Value {
556 let args = args.iter().map(|vb| vb.as_ref().clone()).collect::<Vec<_>>();
557 generativity::make_guard!(guard);
558 let comp = inst.unerase(guard);
559 let callable_name = std::str::from_utf8(&callable_name).unwrap();
560 match comp
561 .description()
562 .get_global(comp.borrow(), &normalize_identifier(std::str::from_utf8(&global).unwrap()))
563 .and_then(|g| {
564 if matches!(
565 comp.description()
566 .original
567 .root_element
568 .borrow()
569 .lookup_property(callable_name)
570 .property_type,
571 i_slint_compiler::langtype::Type::Function { .. }
572 ) {
573 g.as_ref()
574 .eval_function(&normalize_identifier(callable_name), args.as_slice().to_vec())
575 } else {
576 g.as_ref().invoke_callback(&normalize_identifier(callable_name), args.as_slice())
577 }
578 }) {
579 Ok(val) => Box::into_raw(Box::new(val)),
580 Err(_) => std::ptr::null_mut(),
581 }
582}
583
584#[unsafe(no_mangle)]
586pub extern "C" fn slint_interpreter_component_instance_show(
587 inst: &ErasedItemTreeBox,
588 is_visible: bool,
589) {
590 generativity::make_guard!(guard);
591 let comp = inst.unerase(guard);
592 match is_visible {
593 true => comp.borrow_instance().window_adapter().window().show().unwrap(),
594 false => comp.borrow_instance().window_adapter().window().hide().unwrap(),
595 }
596}
597
598#[unsafe(no_mangle)]
603pub unsafe extern "C" fn slint_interpreter_component_instance_window(
604 inst: &ErasedItemTreeBox,
605 out: *mut *const i_slint_core::window::ffi::WindowAdapterRcOpaque,
606) {
607 assert_eq!(
608 core::mem::size_of::<Rc<dyn WindowAdapter>>(),
609 core::mem::size_of::<i_slint_core::window::ffi::WindowAdapterRcOpaque>()
610 );
611 unsafe {
612 core::ptr::write(
613 out as *mut *const Rc<dyn WindowAdapter>,
614 inst.window_adapter_ref().unwrap() as *const _,
615 )
616 }
617}
618
619#[unsafe(no_mangle)]
624pub unsafe extern "C" fn slint_interpreter_component_instance_create(
625 def: &ComponentDefinitionOpaque,
626 out: *mut ComponentInstance,
627) {
628 unsafe { std::ptr::write(out, def.as_component_definition().create().unwrap()) }
629}
630
631#[unsafe(no_mangle)]
632pub unsafe extern "C" fn slint_interpreter_component_instance_component_definition(
633 inst: &ErasedItemTreeBox,
634 component_definition_ptr: *mut ComponentDefinitionOpaque,
635) {
636 generativity::make_guard!(guard);
637 let definition = ComponentDefinition { inner: inst.unerase(guard).description().into() };
638 unsafe { std::ptr::write(component_definition_ptr as *mut ComponentDefinition, definition) };
639}
640
641#[vtable::vtable]
642#[repr(C)]
643pub struct ModelAdaptorVTable {
644 pub row_count: extern "C" fn(VRef<ModelAdaptorVTable>) -> usize,
645 pub row_data: unsafe extern "C" fn(VRef<ModelAdaptorVTable>, row: usize) -> *mut Value,
646 pub set_row_data: extern "C" fn(VRef<ModelAdaptorVTable>, row: usize, value: Box<Value>),
647 pub push_row: extern "C" fn(VRef<ModelAdaptorVTable>, value: Box<Value>),
648 pub remove_row: extern "C" fn(VRef<ModelAdaptorVTable>, row: isize),
649 pub insert_row: extern "C" fn(VRef<ModelAdaptorVTable>, row: isize, value: Box<Value>),
650 pub get_notify: extern "C" fn(VRef<'_, ModelAdaptorVTable>) -> &ModelNotifyOpaque,
651 pub drop: extern "C" fn(VRefMut<ModelAdaptorVTable>),
652}
653
654struct ModelAdaptorWrapper(vtable::VBox<ModelAdaptorVTable>);
655impl Model for ModelAdaptorWrapper {
656 type Data = Value;
657
658 fn row_count(&self) -> usize {
659 self.0.row_count()
660 }
661
662 fn row_data(&self, row: usize) -> Option<Value> {
663 let val_ptr = unsafe { self.0.row_data(row) };
664 if val_ptr.is_null() { None } else { Some(*unsafe { Box::from_raw(val_ptr) }) }
665 }
666
667 fn model_tracker(&self) -> &dyn i_slint_core::model::ModelTracker {
668 self.0.get_notify().as_model_notify()
669 }
670
671 fn set_row_data(&self, row: usize, data: Value) {
672 let val = Box::new(data);
673 self.0.set_row_data(row, val);
674 }
675
676 fn push_row(&self, data: Value) {
677 let val = Box::new(data);
678 self.0.push_row(val);
679 }
680
681 fn remove_row(&self, row: isize) {
682 self.0.remove_row(row);
683 }
684
685 fn insert_row(&self, row: isize, data: Value) {
686 let val = Box::new(data);
687 self.0.insert_row(row, val);
688 }
689
690 fn as_any(&self) -> &dyn core::any::Any {
691 self
692 }
693}
694
695#[repr(C)]
696#[cfg(target_pointer_width = "64")]
697pub struct ModelNotifyOpaque([usize; 8]);
698#[repr(C)]
699#[cfg(target_pointer_width = "32")]
700pub struct ModelNotifyOpaque([usize; 12]);
701const _: usize = std::mem::size_of::<ModelNotifyOpaque>() - std::mem::size_of::<ModelNotify>();
703const _: usize = std::mem::align_of::<ModelNotifyOpaque>() - std::mem::align_of::<ModelNotify>();
704
705impl ModelNotifyOpaque {
706 fn as_model_notify(&self) -> &ModelNotify {
707 unsafe { std::mem::transmute::<&ModelNotifyOpaque, &ModelNotify>(self) }
709 }
710}
711
712#[unsafe(no_mangle)]
714pub unsafe extern "C" fn slint_interpreter_model_notify_new(val: *mut ModelNotifyOpaque) {
715 unsafe { std::ptr::write(val as *mut ModelNotify, ModelNotify::default()) };
716}
717
718#[unsafe(no_mangle)]
720pub unsafe extern "C" fn slint_interpreter_model_notify_destructor(val: *mut ModelNotifyOpaque) {
721 drop(unsafe { std::ptr::read(val as *mut ModelNotify) })
722}
723
724#[unsafe(no_mangle)]
725pub unsafe extern "C" fn slint_interpreter_model_notify_row_changed(
726 notify: &ModelNotifyOpaque,
727 row: usize,
728) {
729 notify.as_model_notify().row_changed(row);
730}
731
732#[unsafe(no_mangle)]
733pub unsafe extern "C" fn slint_interpreter_model_notify_row_added(
734 notify: &ModelNotifyOpaque,
735 row: usize,
736 count: usize,
737) {
738 notify.as_model_notify().row_added(row, count);
739}
740
741#[unsafe(no_mangle)]
742pub unsafe extern "C" fn slint_interpreter_model_notify_reset(notify: &ModelNotifyOpaque) {
743 notify.as_model_notify().reset();
744}
745
746#[unsafe(no_mangle)]
747pub unsafe extern "C" fn slint_interpreter_model_notify_row_removed(
748 notify: &ModelNotifyOpaque,
749 row: usize,
750 count: usize,
751) {
752 notify.as_model_notify().row_removed(row, count);
753}
754
755#[derive(Clone)]
758#[repr(u8)]
759pub enum DiagnosticLevel {
760 Error,
762 Warning,
764 Note,
766}
767
768#[derive(Clone)]
772#[repr(C)]
773pub struct Diagnostic {
774 message: SharedString,
776 source_file: SharedString,
778 line: usize,
780 column: usize,
782 level: DiagnosticLevel,
784}
785
786#[repr(transparent)]
787pub struct ComponentCompilerOpaque(#[allow(deprecated)] NonNull<ComponentCompiler>);
788
789#[allow(deprecated)]
790impl ComponentCompilerOpaque {
791 fn as_component_compiler(&self) -> &ComponentCompiler {
792 unsafe { self.0.as_ref() }
794 }
795 fn as_component_compiler_mut(&mut self) -> &mut ComponentCompiler {
796 unsafe { self.0.as_mut() }
798 }
799}
800
801#[unsafe(no_mangle)]
802#[allow(deprecated)]
803pub unsafe extern "C" fn slint_interpreter_component_compiler_new(
804 compiler: *mut ComponentCompilerOpaque,
805) {
806 unsafe {
807 *compiler = ComponentCompilerOpaque(NonNull::new_unchecked(Box::into_raw(Box::new(
808 ComponentCompiler::default(),
809 ))));
810 }
811}
812
813#[unsafe(no_mangle)]
814pub unsafe extern "C" fn slint_interpreter_component_compiler_destructor(
815 compiler: *mut ComponentCompilerOpaque,
816) {
817 drop(unsafe { Box::from_raw((*compiler).0.as_ptr()) })
818}
819
820#[unsafe(no_mangle)]
821pub unsafe extern "C" fn slint_interpreter_component_compiler_set_include_paths(
822 compiler: &mut ComponentCompilerOpaque,
823 paths: &SharedVector<SharedString>,
824) {
825 compiler
826 .as_component_compiler_mut()
827 .set_include_paths(paths.iter().map(|path| path.as_str().into()).collect())
828}
829
830#[unsafe(no_mangle)]
831pub unsafe extern "C" fn slint_interpreter_component_compiler_set_style(
832 compiler: &mut ComponentCompilerOpaque,
833 style: Slice<u8>,
834) {
835 compiler.as_component_compiler_mut().set_style(std::str::from_utf8(&style).unwrap().to_string())
836}
837
838#[unsafe(no_mangle)]
839pub unsafe extern "C" fn slint_interpreter_component_compiler_set_translation_domain(
840 compiler: &mut ComponentCompilerOpaque,
841 translation_domain: Slice<u8>,
842) {
843 compiler
844 .as_component_compiler_mut()
845 .set_translation_domain(std::str::from_utf8(&translation_domain).unwrap().to_string())
846}
847
848#[unsafe(no_mangle)]
849pub unsafe extern "C" fn slint_interpreter_component_compiler_get_style(
850 compiler: &ComponentCompilerOpaque,
851 style_out: &mut SharedString,
852) {
853 *style_out =
854 compiler.as_component_compiler().style().map_or(SharedString::default(), |s| s.into());
855}
856
857#[unsafe(no_mangle)]
858pub unsafe extern "C" fn slint_interpreter_component_compiler_get_include_paths(
859 compiler: &ComponentCompilerOpaque,
860 paths: &mut SharedVector<SharedString>,
861) {
862 paths.extend(
863 compiler
864 .as_component_compiler()
865 .include_paths()
866 .iter()
867 .map(|path| path.to_str().map_or_else(Default::default, |str| str.into())),
868 );
869}
870
871#[unsafe(no_mangle)]
872pub unsafe extern "C" fn slint_interpreter_component_compiler_get_diagnostics(
873 compiler: &ComponentCompilerOpaque,
874 out_diags: &mut SharedVector<Diagnostic>,
875) {
876 #[allow(deprecated)]
877 out_diags.extend(compiler.as_component_compiler().diagnostics().iter().map(|diagnostic| {
878 let (line, column) = diagnostic.line_column();
879 Diagnostic {
880 message: diagnostic.message().into(),
881 source_file: diagnostic
882 .source_file()
883 .and_then(|path| path.to_str())
884 .map_or_else(Default::default, |str| str.into()),
885 line,
886 column,
887 level: match diagnostic.level() {
888 i_slint_compiler::diagnostics::DiagnosticLevel::Error => DiagnosticLevel::Error,
889 i_slint_compiler::diagnostics::DiagnosticLevel::Warning => DiagnosticLevel::Warning,
890 i_slint_compiler::diagnostics::DiagnosticLevel::Note => DiagnosticLevel::Note,
891 _ => DiagnosticLevel::Warning,
892 },
893 }
894 }));
895}
896
897#[unsafe(no_mangle)]
898pub unsafe extern "C" fn slint_interpreter_component_compiler_build_from_source(
899 compiler: &mut ComponentCompilerOpaque,
900 source_code: Slice<u8>,
901 path: Slice<u8>,
902 component_definition_ptr: *mut ComponentDefinitionOpaque,
903) -> bool {
904 match spin_on::spin_on(compiler.as_component_compiler_mut().build_from_source(
905 std::str::from_utf8(&source_code).unwrap().to_string(),
906 std::str::from_utf8(&path).unwrap().to_string().into(),
907 )) {
908 Some(definition) => {
909 unsafe {
910 std::ptr::write(component_definition_ptr as *mut ComponentDefinition, definition)
911 };
912 true
913 }
914 None => false,
915 }
916}
917
918#[unsafe(no_mangle)]
919pub unsafe extern "C" fn slint_interpreter_component_compiler_build_from_path(
920 compiler: &mut ComponentCompilerOpaque,
921 path: Slice<u8>,
922 component_definition_ptr: *mut ComponentDefinitionOpaque,
923) -> bool {
924 use std::str::FromStr;
925 match spin_on::spin_on(
926 compiler
927 .as_component_compiler_mut()
928 .build_from_path(PathBuf::from_str(std::str::from_utf8(&path).unwrap()).unwrap()),
929 ) {
930 Some(definition) => {
931 unsafe {
932 std::ptr::write(component_definition_ptr as *mut ComponentDefinition, definition)
933 };
934 true
935 }
936 None => false,
937 }
938}
939
940#[derive(Clone)]
944#[repr(C)]
945pub struct PropertyDescriptor {
946 property_name: SharedString,
948 property_type: ValueType,
950}
951
952#[repr(C)]
953pub struct ComponentDefinitionOpaque([usize; 1]);
956const _: [(); std::mem::size_of::<ComponentDefinitionOpaque>()] =
958 [(); std::mem::size_of::<ComponentDefinition>()];
959const _: [(); std::mem::align_of::<ComponentDefinitionOpaque>()] =
960 [(); std::mem::align_of::<ComponentDefinition>()];
961
962impl ComponentDefinitionOpaque {
963 fn as_component_definition(&self) -> &ComponentDefinition {
964 unsafe { std::mem::transmute::<&ComponentDefinitionOpaque, &ComponentDefinition>(self) }
966 }
967}
968
969#[unsafe(no_mangle)]
971pub unsafe extern "C" fn slint_interpreter_component_definition_clone(
972 other: &ComponentDefinitionOpaque,
973 def: *mut ComponentDefinitionOpaque,
974) {
975 unsafe {
976 std::ptr::write(def as *mut ComponentDefinition, other.as_component_definition().clone())
977 }
978}
979
980#[unsafe(no_mangle)]
982pub unsafe extern "C" fn slint_interpreter_component_definition_destructor(
983 val: *mut ComponentDefinitionOpaque,
984) {
985 drop(unsafe { std::ptr::read(val as *mut ComponentDefinition) })
986}
987
988#[unsafe(no_mangle)]
990pub unsafe extern "C" fn slint_interpreter_component_definition_properties(
991 def: &ComponentDefinitionOpaque,
992 props: &mut SharedVector<PropertyDescriptor>,
993) {
994 props.extend(def.as_component_definition().properties().map(
995 |(property_name, property_type)| PropertyDescriptor {
996 property_name: property_name.into(),
997 property_type,
998 },
999 ))
1000}
1001
1002#[unsafe(no_mangle)]
1004pub unsafe extern "C" fn slint_interpreter_component_definition_callbacks(
1005 def: &ComponentDefinitionOpaque,
1006 callbacks: &mut SharedVector<SharedString>,
1007) {
1008 callbacks.extend(def.as_component_definition().callbacks().map(|name| name.into()))
1009}
1010
1011#[unsafe(no_mangle)]
1013pub unsafe extern "C" fn slint_interpreter_component_definition_functions(
1014 def: &ComponentDefinitionOpaque,
1015 functions: &mut SharedVector<SharedString>,
1016) {
1017 functions.extend(def.as_component_definition().functions().map(|name| name.into()))
1018}
1019
1020#[unsafe(no_mangle)]
1022pub unsafe extern "C" fn slint_interpreter_component_definition_name(
1023 def: &ComponentDefinitionOpaque,
1024 name: &mut SharedString,
1025) {
1026 *name = def.as_component_definition().name().into()
1027}
1028
1029#[unsafe(no_mangle)]
1031pub unsafe extern "C" fn slint_interpreter_component_definition_globals(
1032 def: &ComponentDefinitionOpaque,
1033 names: &mut SharedVector<SharedString>,
1034) {
1035 names.extend(def.as_component_definition().globals().map(|name| name.into()))
1036}
1037
1038#[unsafe(no_mangle)]
1041pub unsafe extern "C" fn slint_interpreter_component_definition_global_properties(
1042 def: &ComponentDefinitionOpaque,
1043 global_name: Slice<u8>,
1044 properties: &mut SharedVector<PropertyDescriptor>,
1045) -> bool {
1046 if let Some(property_it) =
1047 def.as_component_definition().global_properties(std::str::from_utf8(&global_name).unwrap())
1048 {
1049 properties.extend(property_it.map(|(property_name, property_type)| PropertyDescriptor {
1050 property_name: property_name.into(),
1051 property_type,
1052 }));
1053 true
1054 } else {
1055 false
1056 }
1057}
1058
1059#[unsafe(no_mangle)]
1062pub unsafe extern "C" fn slint_interpreter_component_definition_global_callbacks(
1063 def: &ComponentDefinitionOpaque,
1064 global_name: Slice<u8>,
1065 names: &mut SharedVector<SharedString>,
1066) -> bool {
1067 if let Some(name_it) =
1068 def.as_component_definition().global_callbacks(std::str::from_utf8(&global_name).unwrap())
1069 {
1070 names.extend(name_it.map(|name| name.into()));
1071 true
1072 } else {
1073 false
1074 }
1075}
1076
1077#[unsafe(no_mangle)]
1080pub unsafe extern "C" fn slint_interpreter_component_definition_global_functions(
1081 def: &ComponentDefinitionOpaque,
1082 global_name: Slice<u8>,
1083 names: &mut SharedVector<SharedString>,
1084) -> bool {
1085 if let Some(name_it) =
1086 def.as_component_definition().global_functions(std::str::from_utf8(&global_name).unwrap())
1087 {
1088 names.extend(name_it.map(|name| name.into()));
1089 true
1090 } else {
1091 false
1092 }
1093}