read_wire_ports/
read_wire_ports.rs1use brdb::{AsBrdbValue, Brdb, IntoReader, WireChunkSoA, schema::BrdbStruct};
2use std::{
3 collections::{HashMap, HashSet},
4 fmt::Write,
5 path::PathBuf,
6};
7struct ComponentMeta {
8 wire_inputs: HashSet<u16>,
9 wire_outputs: HashSet<u16>,
10}
11
12struct BrickMeta {
13 type_index: u32,
14 components: Vec<(u16, BrdbStruct)>,
15}
16
17fn main() -> Result<(), Box<dyn std::error::Error>> {
19 let path = PathBuf::from("./world.brdb");
20
21 let db = Brdb::open(path)?.into_reader();
22
23 let data = db.global_data()?;
24 let component_schema = db.components_schema()?;
25
26 let chunks = db.brick_chunk_index(1)?;
27
28 let mut brick_type_set = HashSet::new();
30
31 let mut component_map = HashMap::new();
33
34 let mut brick_map = HashMap::new();
36
37 for chunk in &chunks {
38 let soa = db.brick_chunk_soa(1, chunk.index)?;
39
40 let pb_index = soa.procedural_brick_starting_index;
42 for (i, t) in soa.brick_type_indices.into_iter().enumerate() {
43 if t >= pb_index {
44 continue;
45 }
46 if brick_type_set.contains(&t) {
47 continue;
48 }
49 brick_type_set.insert(t);
50
51 brick_map.insert(
53 (chunk.index, i),
54 BrickMeta {
55 type_index: t,
56 components: Vec::new(),
57 },
58 );
59 }
60
61 if chunk.num_components > 0 {
62 let (soa, components) = db.component_chunk_soa(1, chunk.index)?;
63 let indices = soa.component_brick_indices;
64
65 let type_indices = soa
67 .component_type_counters
68 .iter()
69 .flat_map(|v| {
70 let index = v.type_index as u16;
71 (0..v.num_instances).map(move |_| index)
72 })
73 .collect::<Vec<_>>();
74
75 for (i, c) in components.iter().enumerate() {
77 let brick_index = indices[i as usize].as_brdb_u32()?;
78 let type_index = type_indices[i as usize];
79 if let Some(brick) = brick_map.get_mut(&(chunk.index, brick_index as usize)) {
80 brick.components.push((type_index, c.clone()));
81 } else {
82 continue;
83 }
84
85 if !component_map.contains_key(&type_index) {
87 component_map.insert(
88 type_index,
89 ComponentMeta {
90 wire_inputs: HashSet::new(),
91 wire_outputs: HashSet::new(),
92 },
93 );
94 }
95 }
96 }
97 }
98
99 for chunk in &chunks {
101 if chunk.num_wires > 0 {
102 let soa = db.wire_chunk_soa(1, chunk.index)?.to_value();
103 let soa: WireChunkSoA = (&soa).try_into()?;
104 for port in soa.local_wire_sources {
105 if let Some(meta) = component_map.get_mut(&port.component_type_index) {
106 meta.wire_outputs.insert(port.port_index);
107 }
108 }
109 for port in soa.local_wire_targets {
110 if let Some(meta) = component_map.get_mut(&port.component_type_index) {
111 meta.wire_inputs.insert(port.port_index);
112 }
113 }
114 for port in soa.remote_wire_sources {
115 if let Some(meta) = component_map.get_mut(&port.component_type_index) {
116 meta.wire_outputs.insert(port.port_index);
117 }
118 }
119 for port in soa.remote_wire_targets {
120 if let Some(meta) = component_map.get_mut(&port.component_type_index) {
121 meta.wire_inputs.insert(port.port_index);
122 }
123 }
124 }
125 }
126
127 for meta in brick_map.values() {
129 let brick_type_str = data.basic_brick_asset_names[meta.type_index as usize].clone();
130 for c in &meta.components {
131 let component_type_str = data.component_type_names[c.0 as usize].clone();
132 let c_entry = component_map.get(&c.0).unwrap();
133 let wire_inputs = c_entry
134 .wire_inputs
135 .iter()
136 .map(|i| {
137 format!(
138 " {}",
139 data.component_wire_port_names[*i as usize].to_owned()
140 )
141 })
142 .collect::<Vec<_>>()
143 .join("\n");
144 let wire_outputs = c_entry
145 .wire_outputs
146 .iter()
147 .map(|i| {
148 format!(
149 " {}",
150 data.component_wire_port_names[*i as usize].to_owned()
151 )
152 })
153 .collect::<Vec<_>>()
154 .join("\n");
155
156 let mut component_struct = String::new();
157 for (name, properties) in &component_schema.structs {
158 if name != &c.1.name {
159 continue;
160 }
161
162 let name = component_schema
163 .intern
164 .lookup(*name)
165 .unwrap_or("UnknownStruct".to_owned());
166 writeln!(component_struct, "struct {name} {{")?;
167 for (prop_name, prop_type) in properties {
168 let prop_name = component_schema
169 .intern
170 .lookup(*prop_name)
171 .unwrap_or("UnknownProperty".to_owned());
172 writeln!(
173 component_struct,
174 " {prop_name}: {},",
175 prop_type.as_string(&component_schema)
176 )?;
177 }
178 writeln!(component_struct, "}}")?;
179 }
180
181 println!(
182 "Brick: {}\nComponent: {}\n{}Inputs:\n{}\nOutputs:\n{}\n\n",
183 brick_type_str, component_type_str, component_struct, wire_inputs, wire_outputs
184 );
185 }
186 }
187
188 Ok(())
189}