1use std::rc::Rc;
5
6use nifty_runtime::{Shown, Templates};
7
8use crate::logic::{Compiled, Frame, Region, ViewTemplate};
9use crate::value::Slot;
10
11pub struct Sink<'a> {
12 region: &'a Region,
13 views: &'a [ViewTemplate],
14 parent: &'a Rc<Frame>,
15 shown: Vec<(Templates<Compiled>, Pending)>,
16}
17
18impl std::fmt::Debug for Sink<'_> {
19 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
20 f.debug_struct("Sink")
21 .field("shown", &self.shown.len())
22 .finish_non_exhaustive()
23 }
24}
25
26enum Pending {
29 Parent,
30 Own(Frame),
31}
32
33impl<'a> Sink<'a> {
34 pub(crate) fn new(
35 region: &'a Region,
36 views: &'a [ViewTemplate],
37 parent: &'a Rc<Frame>,
38 ) -> Self {
39 Self {
40 region,
41 views,
42 parent,
43 shown: Vec::new(),
44 }
45 }
46
47 pub(crate) fn finish(self) -> Vec<Shown<Compiled>> {
48 self.shown
49 .into_iter()
50 .map(|(templates, frame)| Shown {
51 templates,
52 frame: match frame {
53 Pending::Parent => Rc::clone(self.parent),
54 Pending::Own(frame) => Rc::new(frame),
55 },
56 })
57 .collect()
58 }
59
60 fn list(&self, list: u32) -> Templates<Compiled> {
63 let list =
64 self.region.lists.get(list as usize).unwrap_or_else(|| {
65 panic!("compiled code showed list {list}, which its region lacks")
66 });
67 Rc::clone(list)
68 }
69
70 fn show_own(&mut self, templates: Templates<Compiled>, mut frame: Frame) -> *mut Slot {
73 let locals = frame.as_mut_ptr();
74 self.shown.push((templates, Pending::Own(frame)));
75 locals
76 }
77}
78
79#[unsafe(no_mangle)]
84pub(crate) unsafe extern "C" fn nf_show_same(sink: *mut Sink<'_>, list: u32) {
85 let sink = unsafe { &mut *sink };
87 let templates = sink.list(list);
88 sink.shown.push((templates, Pending::Parent));
89}
90
91#[unsafe(no_mangle)]
98pub(crate) unsafe extern "C" fn nf_show_item(sink: *mut Sink<'_>, list: u32) -> *mut Slot {
99 let sink = unsafe { &mut *sink };
101 let templates = sink.list(list);
102 let frame = Frame::clone(sink.parent);
103 sink.show_own(templates, frame)
104}
105
106#[unsafe(no_mangle)]
116pub(crate) unsafe extern "C" fn nf_show_view(sink: *mut Sink<'_>, view: u32) -> *mut Slot {
117 let sink = unsafe { &mut *sink };
119 let view = sink
120 .views
121 .get(view as usize)
122 .unwrap_or_else(|| panic!("compiled code showed view {view}, which doesn't exist"));
123 let (templates, frame) = (Rc::clone(&view.body), Frame::empty(view.frame));
124 sink.show_own(templates, frame)
125}