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