cotis_modules_debug/layout_module_debugger/
isolated_replay.rs1use std::iter::Peekable;
8
9use cotis::element_configuring::{ConfigureElements, ConfiguredParentElement, OpenElement};
10use cotis::layout::LayoutFrameManager;
11use cotis::layout::{LayoutManager, LayoutManagerCompatible};
12
13use crate::serialize_targets::leaf_serialization::LeafConfigListCompatible;
14use crate::serialize_targets::{
15 LeafedInterfaceDeclaration, LeafedInterfaceInstructions, SerializableInterfaceInstructions,
16};
17
18pub struct LayoutModuleReplay<Module, ConfigType, List: Copy> {
25 internal: Module,
26 declaration: LeafedInterfaceDeclaration<ConfigType, List>,
27}
28
29impl<Module, ConfigType, List: Copy> LayoutModuleReplay<Module, ConfigType, List> {
30 pub fn new(
32 internal: Module,
33 declaration: LeafedInterfaceDeclaration<ConfigType, List>,
34 ) -> Self {
35 Self {
36 internal,
37 declaration,
38 }
39 }
40
41 pub fn replay<'frame, RenderCommandType, Renderer>(
55 &mut self,
56 renderer: &mut Renderer,
57 ) -> Vec<RenderCommandType>
58 where
59 ConfigType: 'frame + Clone,
60 RenderCommandType: 'frame,
61 Module: LayoutManager<'frame, ConfigType, RenderCommandType>
62 + LayoutManagerCompatible<Renderer>,
63 for<'layout> List: LeafConfigListCompatible<Module::ElementConfigurer<'layout>, ConfigType>,
64 {
65 self.internal.init(renderer);
66 self.internal.prepare(renderer);
67 let mut frame = self.internal.begin_frame();
68 let mut root = frame.begin();
69 let mut iter = self.declaration.iter_over();
70
71 replay_instructions(&mut iter, &mut root);
72
73 root.close_element();
74 frame.end().collect()
75 }
76}
77
78pub(crate) fn replay_instructions<'a, ConfigType, Configurer, List>(
80 inst_iter: &mut impl Iterator<
81 Item = LeafedInterfaceInstructions<&'a SerializableInterfaceInstructions<ConfigType>, List>,
82 >,
83 layout: &mut ConfiguredParentElement<'_, Configurer, ConfigType>,
84) where
85 ConfigType: Clone + 'a,
86 Configurer: ConfigureElements<ConfigType>,
87 List: Copy + LeafConfigListCompatible<Configurer, ConfigType>,
88{
89 replay_instructions_recursive_parent(&mut inst_iter.peekable(), layout);
90}
91
92fn replay_instructions_recursive_parent<'a, ConfigType, Configurer, List>(
93 inst_iter: &mut Peekable<
94 impl Iterator<
95 Item = LeafedInterfaceInstructions<
96 &'a SerializableInterfaceInstructions<ConfigType>,
97 List,
98 >,
99 >,
100 >,
101 layout: &mut ConfiguredParentElement<'_, Configurer, ConfigType>,
102) where
103 ConfigType: Clone + 'a,
104 Configurer: ConfigureElements<ConfigType>,
105 List: Copy + LeafConfigListCompatible<Configurer, ConfigType>,
106{
107 while let Some(leafed) = inst_iter.next() {
108 match leafed.instruction {
109 SerializableInterfaceInstructions::Open => {
110 let element = layout.new_element();
111 replay_instructions_recursive_open(inst_iter, element);
112 }
113 SerializableInterfaceInstructions::Close => {
114 break;
115 }
116 SerializableInterfaceInstructions::Configure(_) => {
117 panic!("Bad replay: cannot configure ConfiguredParentElement");
118 }
119 SerializableInterfaceInstructions::LeafConfig(_) => {
120 panic!("Bad replay: cannot configure ConfiguredParentElement with leaf config");
121 }
122 _ => {}
123 }
124 }
125}
126
127fn replay_instructions_recursive_open<'a, ConfigType, Configurer, List>(
128 inst_iter: &mut Peekable<
129 impl Iterator<
130 Item = LeafedInterfaceInstructions<
131 &'a SerializableInterfaceInstructions<ConfigType>,
132 List,
133 >,
134 >,
135 >,
136 layout: OpenElement<'_, Configurer, ConfigType>,
137) where
138 ConfigType: Clone + 'a,
139 Configurer: ConfigureElements<ConfigType>,
140 List: Copy + LeafConfigListCompatible<Configurer, ConfigType>,
141{
142 let mut layout_opt = Some(layout);
143 let mut parent_opt: Option<ConfiguredParentElement<'_, Configurer, ConfigType>> = None;
144
145 while let Some(leafed) = inst_iter.next() {
146 match leafed.instruction {
147 SerializableInterfaceInstructions::Configure(c) => {
148 if let Some(ref mut open) = layout_opt {
149 open.set_config(c.clone());
150 }
151 }
152 SerializableInterfaceInstructions::LeafConfig(data) => {
153 if let Some(open) = layout_opt.take() {
154 List::configure_open(data, open);
155 }
156 }
157 SerializableInterfaceInstructions::Open => {
158 if parent_opt.is_none()
159 && let Some(open) = layout_opt.take()
160 {
161 parent_opt = Some(open.make_parent());
162 }
163 if let Some(ref mut parent) = parent_opt {
164 let child_element = parent.new_element();
165 replay_instructions_recursive_open(inst_iter, child_element);
166 }
167 }
168 SerializableInterfaceInstructions::Close => {
169 if let Some(parent) = parent_opt.take() {
170 parent.close_element();
171 } else if let Some(open) = layout_opt.take() {
172 open.close_element();
173 }
174 break;
175 }
176 _ => {}
177 }
178 }
179}