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