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 get_notify: extern "C" fn(VRef<'_, ModelAdaptorVTable>) -> &ModelNotifyOpaque,
648 pub drop: extern "C" fn(VRefMut<ModelAdaptorVTable>),
649}
650
651struct ModelAdaptorWrapper(vtable::VBox<ModelAdaptorVTable>);
652impl Model for ModelAdaptorWrapper {
653 type Data = Value;
654
655 fn row_count(&self) -> usize {
656 self.0.row_count()
657 }
658
659 fn row_data(&self, row: usize) -> Option<Value> {
660 let val_ptr = unsafe { self.0.row_data(row) };
661 if val_ptr.is_null() { None } else { Some(*unsafe { Box::from_raw(val_ptr) }) }
662 }
663
664 fn model_tracker(&self) -> &dyn i_slint_core::model::ModelTracker {
665 self.0.get_notify().as_model_notify()
666 }
667
668 fn set_row_data(&self, row: usize, data: Value) {
669 let val = Box::new(data);
670 self.0.set_row_data(row, val);
671 }
672
673 fn as_any(&self) -> &dyn core::any::Any {
674 self
675 }
676}
677
678#[repr(C)]
679#[cfg(target_pointer_width = "64")]
680pub struct ModelNotifyOpaque([usize; 8]);
681#[repr(C)]
682#[cfg(target_pointer_width = "32")]
683pub struct ModelNotifyOpaque([usize; 12]);
684const _: usize = std::mem::size_of::<ModelNotifyOpaque>() - std::mem::size_of::<ModelNotify>();
686const _: usize = std::mem::align_of::<ModelNotifyOpaque>() - std::mem::align_of::<ModelNotify>();
687
688impl ModelNotifyOpaque {
689 fn as_model_notify(&self) -> &ModelNotify {
690 unsafe { std::mem::transmute::<&ModelNotifyOpaque, &ModelNotify>(self) }
692 }
693}
694
695#[unsafe(no_mangle)]
697pub unsafe extern "C" fn slint_interpreter_model_notify_new(val: *mut ModelNotifyOpaque) {
698 unsafe { std::ptr::write(val as *mut ModelNotify, ModelNotify::default()) };
699}
700
701#[unsafe(no_mangle)]
703pub unsafe extern "C" fn slint_interpreter_model_notify_destructor(val: *mut ModelNotifyOpaque) {
704 drop(unsafe { std::ptr::read(val as *mut ModelNotify) })
705}
706
707#[unsafe(no_mangle)]
708pub unsafe extern "C" fn slint_interpreter_model_notify_row_changed(
709 notify: &ModelNotifyOpaque,
710 row: usize,
711) {
712 notify.as_model_notify().row_changed(row);
713}
714
715#[unsafe(no_mangle)]
716pub unsafe extern "C" fn slint_interpreter_model_notify_row_added(
717 notify: &ModelNotifyOpaque,
718 row: usize,
719 count: usize,
720) {
721 notify.as_model_notify().row_added(row, count);
722}
723
724#[unsafe(no_mangle)]
725pub unsafe extern "C" fn slint_interpreter_model_notify_reset(notify: &ModelNotifyOpaque) {
726 notify.as_model_notify().reset();
727}
728
729#[unsafe(no_mangle)]
730pub unsafe extern "C" fn slint_interpreter_model_notify_row_removed(
731 notify: &ModelNotifyOpaque,
732 row: usize,
733 count: usize,
734) {
735 notify.as_model_notify().row_removed(row, count);
736}
737
738#[derive(Clone)]
741#[repr(u8)]
742pub enum DiagnosticLevel {
743 Error,
745 Warning,
747 Note,
749}
750
751#[derive(Clone)]
755#[repr(C)]
756pub struct Diagnostic {
757 message: SharedString,
759 source_file: SharedString,
761 line: usize,
763 column: usize,
765 level: DiagnosticLevel,
767}
768
769#[repr(transparent)]
770pub struct ComponentCompilerOpaque(#[allow(deprecated)] NonNull<ComponentCompiler>);
771
772#[allow(deprecated)]
773impl ComponentCompilerOpaque {
774 fn as_component_compiler(&self) -> &ComponentCompiler {
775 unsafe { self.0.as_ref() }
777 }
778 fn as_component_compiler_mut(&mut self) -> &mut ComponentCompiler {
779 unsafe { self.0.as_mut() }
781 }
782}
783
784#[unsafe(no_mangle)]
785#[allow(deprecated)]
786pub unsafe extern "C" fn slint_interpreter_component_compiler_new(
787 compiler: *mut ComponentCompilerOpaque,
788) {
789 unsafe {
790 *compiler = ComponentCompilerOpaque(NonNull::new_unchecked(Box::into_raw(Box::new(
791 ComponentCompiler::default(),
792 ))));
793 }
794}
795
796#[unsafe(no_mangle)]
797pub unsafe extern "C" fn slint_interpreter_component_compiler_destructor(
798 compiler: *mut ComponentCompilerOpaque,
799) {
800 drop(unsafe { Box::from_raw((*compiler).0.as_ptr()) })
801}
802
803#[unsafe(no_mangle)]
804pub unsafe extern "C" fn slint_interpreter_component_compiler_set_include_paths(
805 compiler: &mut ComponentCompilerOpaque,
806 paths: &SharedVector<SharedString>,
807) {
808 compiler
809 .as_component_compiler_mut()
810 .set_include_paths(paths.iter().map(|path| path.as_str().into()).collect())
811}
812
813#[unsafe(no_mangle)]
814pub unsafe extern "C" fn slint_interpreter_component_compiler_set_style(
815 compiler: &mut ComponentCompilerOpaque,
816 style: Slice<u8>,
817) {
818 compiler.as_component_compiler_mut().set_style(std::str::from_utf8(&style).unwrap().to_string())
819}
820
821#[unsafe(no_mangle)]
822pub unsafe extern "C" fn slint_interpreter_component_compiler_set_translation_domain(
823 compiler: &mut ComponentCompilerOpaque,
824 translation_domain: Slice<u8>,
825) {
826 compiler
827 .as_component_compiler_mut()
828 .set_translation_domain(std::str::from_utf8(&translation_domain).unwrap().to_string())
829}
830
831#[unsafe(no_mangle)]
832pub unsafe extern "C" fn slint_interpreter_component_compiler_get_style(
833 compiler: &ComponentCompilerOpaque,
834 style_out: &mut SharedString,
835) {
836 *style_out =
837 compiler.as_component_compiler().style().map_or(SharedString::default(), |s| s.into());
838}
839
840#[unsafe(no_mangle)]
841pub unsafe extern "C" fn slint_interpreter_component_compiler_get_include_paths(
842 compiler: &ComponentCompilerOpaque,
843 paths: &mut SharedVector<SharedString>,
844) {
845 paths.extend(
846 compiler
847 .as_component_compiler()
848 .include_paths()
849 .iter()
850 .map(|path| path.to_str().map_or_else(Default::default, |str| str.into())),
851 );
852}
853
854#[unsafe(no_mangle)]
855pub unsafe extern "C" fn slint_interpreter_component_compiler_get_diagnostics(
856 compiler: &ComponentCompilerOpaque,
857 out_diags: &mut SharedVector<Diagnostic>,
858) {
859 #[allow(deprecated)]
860 out_diags.extend(compiler.as_component_compiler().diagnostics().iter().map(|diagnostic| {
861 let (line, column) = diagnostic.line_column();
862 Diagnostic {
863 message: diagnostic.message().into(),
864 source_file: diagnostic
865 .source_file()
866 .and_then(|path| path.to_str())
867 .map_or_else(Default::default, |str| str.into()),
868 line,
869 column,
870 level: match diagnostic.level() {
871 i_slint_compiler::diagnostics::DiagnosticLevel::Error => DiagnosticLevel::Error,
872 i_slint_compiler::diagnostics::DiagnosticLevel::Warning => DiagnosticLevel::Warning,
873 i_slint_compiler::diagnostics::DiagnosticLevel::Note => DiagnosticLevel::Note,
874 _ => DiagnosticLevel::Warning,
875 },
876 }
877 }));
878}
879
880#[unsafe(no_mangle)]
881pub unsafe extern "C" fn slint_interpreter_component_compiler_build_from_source(
882 compiler: &mut ComponentCompilerOpaque,
883 source_code: Slice<u8>,
884 path: Slice<u8>,
885 component_definition_ptr: *mut ComponentDefinitionOpaque,
886) -> bool {
887 match spin_on::spin_on(compiler.as_component_compiler_mut().build_from_source(
888 std::str::from_utf8(&source_code).unwrap().to_string(),
889 std::str::from_utf8(&path).unwrap().to_string().into(),
890 )) {
891 Some(definition) => {
892 unsafe {
893 std::ptr::write(component_definition_ptr as *mut ComponentDefinition, definition)
894 };
895 true
896 }
897 None => false,
898 }
899}
900
901#[unsafe(no_mangle)]
902pub unsafe extern "C" fn slint_interpreter_component_compiler_build_from_path(
903 compiler: &mut ComponentCompilerOpaque,
904 path: Slice<u8>,
905 component_definition_ptr: *mut ComponentDefinitionOpaque,
906) -> bool {
907 use std::str::FromStr;
908 match spin_on::spin_on(
909 compiler
910 .as_component_compiler_mut()
911 .build_from_path(PathBuf::from_str(std::str::from_utf8(&path).unwrap()).unwrap()),
912 ) {
913 Some(definition) => {
914 unsafe {
915 std::ptr::write(component_definition_ptr as *mut ComponentDefinition, definition)
916 };
917 true
918 }
919 None => false,
920 }
921}
922
923#[derive(Clone)]
927#[repr(C)]
928pub struct PropertyDescriptor {
929 property_name: SharedString,
931 property_type: ValueType,
933}
934
935#[repr(C)]
936pub struct ComponentDefinitionOpaque([usize; 1]);
939const _: [(); std::mem::size_of::<ComponentDefinitionOpaque>()] =
941 [(); std::mem::size_of::<ComponentDefinition>()];
942const _: [(); std::mem::align_of::<ComponentDefinitionOpaque>()] =
943 [(); std::mem::align_of::<ComponentDefinition>()];
944
945impl ComponentDefinitionOpaque {
946 fn as_component_definition(&self) -> &ComponentDefinition {
947 unsafe { std::mem::transmute::<&ComponentDefinitionOpaque, &ComponentDefinition>(self) }
949 }
950}
951
952#[unsafe(no_mangle)]
954pub unsafe extern "C" fn slint_interpreter_component_definition_clone(
955 other: &ComponentDefinitionOpaque,
956 def: *mut ComponentDefinitionOpaque,
957) {
958 unsafe {
959 std::ptr::write(def as *mut ComponentDefinition, other.as_component_definition().clone())
960 }
961}
962
963#[unsafe(no_mangle)]
965pub unsafe extern "C" fn slint_interpreter_component_definition_destructor(
966 val: *mut ComponentDefinitionOpaque,
967) {
968 drop(unsafe { std::ptr::read(val as *mut ComponentDefinition) })
969}
970
971#[unsafe(no_mangle)]
973pub unsafe extern "C" fn slint_interpreter_component_definition_properties(
974 def: &ComponentDefinitionOpaque,
975 props: &mut SharedVector<PropertyDescriptor>,
976) {
977 props.extend(def.as_component_definition().properties().map(
978 |(property_name, property_type)| PropertyDescriptor {
979 property_name: property_name.into(),
980 property_type,
981 },
982 ))
983}
984
985#[unsafe(no_mangle)]
987pub unsafe extern "C" fn slint_interpreter_component_definition_callbacks(
988 def: &ComponentDefinitionOpaque,
989 callbacks: &mut SharedVector<SharedString>,
990) {
991 callbacks.extend(def.as_component_definition().callbacks().map(|name| name.into()))
992}
993
994#[unsafe(no_mangle)]
996pub unsafe extern "C" fn slint_interpreter_component_definition_functions(
997 def: &ComponentDefinitionOpaque,
998 functions: &mut SharedVector<SharedString>,
999) {
1000 functions.extend(def.as_component_definition().functions().map(|name| name.into()))
1001}
1002
1003#[unsafe(no_mangle)]
1005pub unsafe extern "C" fn slint_interpreter_component_definition_name(
1006 def: &ComponentDefinitionOpaque,
1007 name: &mut SharedString,
1008) {
1009 *name = def.as_component_definition().name().into()
1010}
1011
1012#[unsafe(no_mangle)]
1014pub unsafe extern "C" fn slint_interpreter_component_definition_globals(
1015 def: &ComponentDefinitionOpaque,
1016 names: &mut SharedVector<SharedString>,
1017) {
1018 names.extend(def.as_component_definition().globals().map(|name| name.into()))
1019}
1020
1021#[unsafe(no_mangle)]
1024pub unsafe extern "C" fn slint_interpreter_component_definition_global_properties(
1025 def: &ComponentDefinitionOpaque,
1026 global_name: Slice<u8>,
1027 properties: &mut SharedVector<PropertyDescriptor>,
1028) -> bool {
1029 if let Some(property_it) =
1030 def.as_component_definition().global_properties(std::str::from_utf8(&global_name).unwrap())
1031 {
1032 properties.extend(property_it.map(|(property_name, property_type)| PropertyDescriptor {
1033 property_name: property_name.into(),
1034 property_type,
1035 }));
1036 true
1037 } else {
1038 false
1039 }
1040}
1041
1042#[unsafe(no_mangle)]
1045pub unsafe extern "C" fn slint_interpreter_component_definition_global_callbacks(
1046 def: &ComponentDefinitionOpaque,
1047 global_name: Slice<u8>,
1048 names: &mut SharedVector<SharedString>,
1049) -> bool {
1050 if let Some(name_it) =
1051 def.as_component_definition().global_callbacks(std::str::from_utf8(&global_name).unwrap())
1052 {
1053 names.extend(name_it.map(|name| name.into()));
1054 true
1055 } else {
1056 false
1057 }
1058}
1059
1060#[unsafe(no_mangle)]
1063pub unsafe extern "C" fn slint_interpreter_component_definition_global_functions(
1064 def: &ComponentDefinitionOpaque,
1065 global_name: Slice<u8>,
1066 names: &mut SharedVector<SharedString>,
1067) -> bool {
1068 if let Some(name_it) =
1069 def.as_component_definition().global_functions(std::str::from_utf8(&global_name).unwrap())
1070 {
1071 names.extend(name_it.map(|name| name.into()));
1072 true
1073 } else {
1074 false
1075 }
1076}