dump_fixture/
dump_fixture.rs1use brdb::{BrFsReader, Brdb, BrReader, Brz, IntoReader, WireChunkSoA};
9use std::path::PathBuf;
10
11fn run<T: BrFsReader>(db: &BrReader<T>) -> Result<(), Box<dyn std::error::Error>> {
12 let data = db.global_data()?;
13 println!("Basic Brick assets: {:?}", data.basic_brick_asset_names);
14 println!("Procedural Brick assets: {:?}", data.procedural_brick_asset_names);
15 println!(
19 "Wire port count: {} (registered catalog)",
20 data.component_wire_port_names.len()
21 );
22 println!(
23 "Component type count: {} (registered catalog)",
24 data.component_type_names.len()
25 );
26 println!("Entity types: {:?}", data.entity_type_names);
27 println!("Entity classes: {:?}", data.entity_data_class_names);
28
29 for gid in 1..32 {
32 let chunks = match db.brick_chunk_index(gid) {
33 Ok(c) => c,
34 Err(_) => break,
35 };
36 println!("=== grid {gid} ===");
37 println!("Brick chunks: {chunks:?}");
38 for chunk in &chunks {
39 let soa = db.brick_chunk_soa(gid, chunk.index)?;
40 println!("Brick soa: {soa:?}");
41 let asset_names: Vec<String> = soa
42 .brick_type_indices
43 .iter()
44 .map(|&t| {
45 if (t as usize) < soa.procedural_brick_starting_index as usize {
46 data.basic_brick_asset_names
47 .get_index(t as usize)
48 .cloned()
49 .unwrap_or_default()
50 } else {
51 "<procedural>".to_string()
52 }
53 })
54 .collect();
55 println!("Brick asset names (by index in chunk): {asset_names:?}");
56
57 if chunk.num_components > 0 {
58 let (soa, components) = db.component_chunk_soa(gid, chunk.index)?;
59 let type_names: Vec<String> = soa
60 .component_type_counters
61 .iter()
62 .flat_map(|c| {
63 let name = data
64 .component_type_names
65 .get_index(c.type_index as usize)
66 .cloned()
67 .unwrap_or_default();
68 (0..c.num_instances).map(move |_| name.clone())
69 })
70 .collect();
71 println!(
72 "Component chunk soa: component_brick_indices={:?} microchip_brick_indices={:?} microchip_brick_grid_references={:?}",
73 soa.component_brick_indices,
74 soa.microchip_brick_indices,
75 soa.microchip_brick_grid_references
76 );
77 println!("Component type names (parallel to ComponentBrickIndices): {type_names:?}");
78 for c in components {
79 println!("Component: {c}");
80 }
81 }
82 if chunk.num_wires > 0 {
83 let raw = db.wire_chunk_soa(gid, chunk.index)?;
84 println!("Wire chunk soa (raw struct): {raw}");
85 let value = raw.to_value();
86 let soa: WireChunkSoA = (&value).try_into()?;
87 let port_name = |i: u16| {
88 data.component_wire_port_names
89 .get_index(i as usize)
90 .cloned()
91 .unwrap_or_default()
92 };
93 let type_name = |i: u16| {
94 data.component_type_names
95 .get_index(i as usize)
96 .cloned()
97 .unwrap_or_default()
98 };
99 for s in &soa.local_wire_sources {
100 println!(
101 " local source: brick_in_chunk={} type={} port={}",
102 s.brick_index_in_chunk,
103 type_name(s.component_type_index),
104 port_name(s.port_index)
105 );
106 }
107 for t in &soa.local_wire_targets {
108 println!(
109 " local target: brick_in_chunk={} type={} port={}",
110 t.brick_index_in_chunk,
111 type_name(t.component_type_index),
112 port_name(t.port_index)
113 );
114 }
115 for s in &soa.remote_wire_sources {
116 println!(
117 " remote source: grid_persistent_index={} chunk={} brick_in_chunk={} type={} port={}",
118 s.grid_persistent_index,
119 s.chunk_index,
120 s.brick_index_in_chunk,
121 type_name(s.component_type_index),
122 port_name(s.port_index)
123 );
124 }
125 for t in &soa.remote_wire_targets {
126 println!(
127 " remote target: brick_in_chunk={} type={} port={}",
128 t.brick_index_in_chunk,
129 type_name(t.component_type_index),
130 port_name(t.port_index)
131 );
132 }
133 }
134 }
135 }
136
137 let entity_chunk_indices = db.entity_chunk_index()?;
139 println!("=== entities ===");
140 println!("Entity chunk indices: {entity_chunk_indices:?}");
141 for chunk_index in entity_chunk_indices {
142 let (soa, entity_data) = db.entity_chunk_soa(chunk_index)?;
143 println!("--- Chunk {chunk_index} (SoA) ---");
144 println!("Type counters: {:?}", soa.type_counters);
145 let type_names: Vec<String> = soa
146 .type_counters
147 .iter()
148 .flat_map(|c| {
149 let name = data
150 .entity_type_names
151 .get_index(c.type_index as usize)
152 .cloned()
153 .unwrap_or_default();
154 (0..c.num_entities).map(move |_| name.clone())
155 })
156 .collect();
157 println!("Entity type names (parallel to PersistentIndices): {type_names:?}");
158 println!("Persistent indices: {:?}", soa.persistent_indices);
159 println!("Locations: {:?}", soa.locations);
160 println!("Rotations: {:?}", soa.rotations);
161 println!("Physics locked (frozen): {:?}", soa.physics_locked_flags);
162 println!("Physics sleeping: {:?}", soa.physics_sleeping_flags);
163 for (i, data) in entity_data.iter().enumerate() {
164 match data {
165 Some(struct_data) => println!(" Entity {i} struct: {struct_data}"),
166 None => println!(" Entity {i}: None"),
167 }
168 }
169 }
170
171 println!("Files: {}", db.get_fs()?.render());
172
173 Ok(())
174}
175
176fn main() -> Result<(), Box<dyn std::error::Error>> {
177 let p = PathBuf::from(std::env::args().nth(1).unwrap());
178 if p.extension().and_then(|e| e.to_str()) == Some("brdb") {
179 run(&Brdb::open(&p)?.into_reader())
180 } else {
181 run(&Brz::open(&p)?.into_reader())
182 }
183}