oxihuman_viewer/
render_queue.rs1#![allow(dead_code)]
7
8#[allow(dead_code)]
9#[derive(Debug, Clone)]
10pub struct DrawCall {
11 pub mesh_id: u32,
12 pub material_id: u32,
13 pub transform: [f32; 16],
14 pub layer: u32,
15}
16
17#[allow(dead_code)]
18#[derive(Debug, Clone)]
19pub struct RenderQueue {
20 calls: Vec<DrawCall>,
21}
22
23#[allow(dead_code)]
24pub fn new_render_queue() -> RenderQueue {
25 RenderQueue { calls: Vec::new() }
26}
27
28#[allow(dead_code)]
29pub fn rq_push(rq: &mut RenderQueue, call: DrawCall) {
30 rq.calls.push(call);
31}
32
33#[allow(dead_code)]
34pub fn rq_sort_by_layer(rq: &mut RenderQueue) {
35 rq.calls.sort_by_key(|c| c.layer);
36}
37
38#[allow(dead_code)]
39pub fn rq_clear(rq: &mut RenderQueue) {
40 rq.calls.clear();
41}
42
43#[allow(dead_code)]
44pub fn rq_len(rq: &RenderQueue) -> usize {
45 rq.calls.len()
46}
47
48#[allow(dead_code)]
49pub fn rq_is_empty(rq: &RenderQueue) -> bool {
50 rq.calls.is_empty()
51}
52
53#[allow(dead_code)]
54pub fn rq_get(rq: &RenderQueue, index: usize) -> Option<&DrawCall> {
55 rq.calls.get(index)
56}
57
58#[allow(dead_code)]
59pub fn rq_drain(rq: &mut RenderQueue) -> Vec<DrawCall> {
60 std::mem::take(&mut rq.calls)
61}
62
63#[allow(dead_code)]
64pub fn rq_to_json(rq: &RenderQueue) -> String {
65 let entries: Vec<String> = rq
66 .calls
67 .iter()
68 .map(|c| {
69 format!(
70 r#"{{"mesh_id":{},"material_id":{},"layer":{}}}"#,
71 c.mesh_id, c.material_id, c.layer
72 )
73 })
74 .collect();
75 format!("[{}]", entries.join(","))
76}
77
78fn make_identity_transform() -> [f32; 16] {
79 [
80 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0,
81 ]
82}
83
84#[cfg(test)]
85mod tests {
86 use super::*;
87
88 fn make_call(mesh_id: u32, layer: u32) -> DrawCall {
89 DrawCall {
90 mesh_id,
91 material_id: 0,
92 transform: make_identity_transform(),
93 layer,
94 }
95 }
96
97 #[test]
98 fn test_new_queue_empty() {
99 let rq = new_render_queue();
100 assert!(rq_is_empty(&rq));
101 assert_eq!(rq_len(&rq), 0);
102 }
103
104 #[test]
105 fn test_push_increases_len() {
106 let mut rq = new_render_queue();
107 rq_push(&mut rq, make_call(1, 0));
108 assert_eq!(rq_len(&rq), 1);
109 }
110
111 #[test]
112 fn test_sort_by_layer() {
113 let mut rq = new_render_queue();
114 rq_push(&mut rq, make_call(1, 5));
115 rq_push(&mut rq, make_call(2, 1));
116 rq_push(&mut rq, make_call(3, 3));
117 rq_sort_by_layer(&mut rq);
118 assert_eq!(rq_get(&rq, 0).expect("should succeed").layer, 1);
119 assert_eq!(rq_get(&rq, 2).expect("should succeed").layer, 5);
120 }
121
122 #[test]
123 fn test_clear() {
124 let mut rq = new_render_queue();
125 rq_push(&mut rq, make_call(1, 0));
126 rq_clear(&mut rq);
127 assert!(rq_is_empty(&rq));
128 }
129
130 #[test]
131 fn test_get_valid_index() {
132 let mut rq = new_render_queue();
133 rq_push(&mut rq, make_call(42, 0));
134 assert_eq!(rq_get(&rq, 0).expect("should succeed").mesh_id, 42);
135 }
136
137 #[test]
138 fn test_get_out_of_bounds() {
139 let rq = new_render_queue();
140 assert!(rq_get(&rq, 0).is_none());
141 }
142
143 #[test]
144 fn test_drain_empties_queue() {
145 let mut rq = new_render_queue();
146 rq_push(&mut rq, make_call(1, 0));
147 rq_push(&mut rq, make_call(2, 1));
148 let drained = rq_drain(&mut rq);
149 assert_eq!(drained.len(), 2);
150 assert!(rq_is_empty(&rq));
151 }
152
153 #[test]
154 fn test_to_json_non_empty() {
155 let mut rq = new_render_queue();
156 rq_push(&mut rq, make_call(7, 2));
157 let j = rq_to_json(&rq);
158 assert!(j.contains("mesh_id"));
159 }
160
161 #[test]
162 fn test_to_json_empty() {
163 let rq = new_render_queue();
164 assert_eq!(rq_to_json(&rq), "[]");
165 }
166}