pub enum BrickType {
Basic(BString),
Procedural {
asset: BString,
size: BrickSize,
},
}Variants§
Implementations§
Source§impl BrickType
impl BrickType
Sourcepub const fn str(asset: &'static str) -> Self
pub const fn str(asset: &'static str) -> Self
Examples found in repository?
examples/write_fixtures.rs (line 396)
365fn spawner_world() -> World {
366 // Prefab-embedding fixture: an outer prefab whose spawner gate references
367 // an inner single-brick prefab embedded at Prefabs/Uploads/<BLAKE3>.brz.
368 // Single grid, single chunk, one insertion-ordered prefab map entry —
369 // fully deterministic. The inner archive is written raw (no zstd) so the
370 // embedded bytes are cross-language reproducible.
371 let mut inner = World::new();
372 inner.meta.bundle.description = "Inner prefab".to_string();
373 inner.bricks.push(Brick {
374 position: (0, 0, 6).into(),
375 color: (255, 0, 0).into(),
376 ..Default::default()
377 });
378 inner.make_prefab();
379 let inner_bytes = {
380 let pending = inner.to_unsaved().unwrap().to_pending().unwrap();
381 let mut buf = Vec::new();
382 pending
383 .to_brz_data(None)
384 .unwrap()
385 .write(&mut buf, None)
386 .unwrap();
387 buf
388 };
389
390 let mut world = World::new();
391 world.register_all_components();
392 world.meta.bundle.description = "Spawner fixture".to_string();
393 let prefab_path = world.add_prefab(inner_bytes);
394 world.bricks.push(
395 Brick {
396 asset: brdb::BrickType::str("B_1x1_Gate_Exec_PrefabSpawner"),
397 position: (0, 0, 1).into(),
398 ..Default::default()
399 }
400 .with_component(
401 assets::LiteralComponent::new("BrickComponentType_WireGraph_Exec_PrefabSpawner")
402 .with_data([(
403 "Prefab",
404 Box::new(prefab_path) as Box<dyn AsBrdbValue>,
405 )]),
406 ),
407 );
408 world.make_prefab();
409 world
410}Source§impl BrickType
impl BrickType
pub fn is_procedural(&self) -> bool
pub fn is_basic(&self) -> bool
Sourcepub fn asset(&self) -> &BString
pub fn asset(&self) -> &BString
Examples found in repository?
examples/extract_components.rs (line 31)
18fn main() -> Result<(), Box<dyn std::error::Error>> {
19 let args: Vec<String> = std::env::args().collect();
20 let path = PathBuf::from(
21 args.get(1)
22 .expect("usage: extract_components <zoo.brdb> [out.rs]"),
23 );
24 let out_path = args.get(2).map(PathBuf::from);
25 let db = Brdb::open(path)?.into_reader();
26 let data = db.global_data()?;
27
28 // The standalone phase attaches otherwise-brickless components to this generic host for
29 // probing; it is never a real component host, so it is filtered out of the host lists.
30 let standalone_host_brick = brdb::assets::bricks::B_1X1F_ROUND;
31 let standalone_host: &str = standalone_host_brick.asset().as_ref();
32
33 // component type index -> host brick asset name(s) / wire port indices.
34 // Host names are resolved inline (basic and procedural bricks index different
35 // name sets), so this stores names rather than type indices.
36 let mut bricks: BTreeMap<u16, BTreeSet<String>> = BTreeMap::new();
37 let mut inputs: BTreeMap<u16, BTreeSet<u16>> = BTreeMap::new();
38 let mut outputs: BTreeMap<u16, BTreeSet<u16>> = BTreeMap::new();
39
40 // Grid 1 is the main grid; higher ids are microchip inner grids. Probe
41 // until a grid id is missing (same convention as read_components).
42 for gid in 1..64 {
43 let chunks = match db.brick_chunk_index(gid) {
44 Ok(c) => c,
45 Err(_) => break,
46 };
47 for chunk in &chunks {
48 // brick index -> brick type index (basic-brick asset), for the
49 // host-brick mapping.
50 let bsoa = db.brick_chunk_soa(gid, chunk.index)?;
51 let pb_start = bsoa.procedural_brick_starting_index;
52 // Procedural brick type index (>= pb_start) -> procedural asset index, via the
53 // per-size run-length counters (same expansion SoA::iter_bricks uses).
54 let proc_asset_by_size: Vec<u32> = bsoa
55 .brick_size_counters
56 .iter()
57 .flat_map(|c| std::iter::repeat(c.asset_index).take(c.num_sizes as usize))
58 .collect();
59 let brick_types = bsoa.brick_type_indices;
60
61 if chunk.num_components > 0 {
62 let (csoa, components) = db.component_chunk_soa(gid, chunk.index)?;
63 let brick_indices = csoa.component_brick_indices;
64 // Expand run-length (type_index, num_instances) into a flat
65 // per-instance list of component type indices.
66 let type_indices = csoa
67 .component_type_counters
68 .iter()
69 .flat_map(|v| {
70 let ti = v.type_index as u16;
71 (0..v.num_instances).map(move |_| ti)
72 })
73 .collect::<Vec<_>>();
74 for i in 0..components.len() {
75 let comp_ty = type_indices[i];
76 // ensure every placed component is present even with no wires
77 inputs.entry(comp_ty).or_default();
78 outputs.entry(comp_ty).or_default();
79 let brick_index = brick_indices[i].as_brdb_u32()? as usize;
80 if let Some(&bt) = brick_types.get(brick_index) {
81 // Basic bricks index basic_brick_asset_names directly; procedural
82 // bricks (type index >= pb_start) map through the size run-lengths to
83 // a procedural_brick_asset_names index.
84 let host = if bt < pb_start {
85 data.basic_brick_asset_names.get_index(bt as usize).cloned()
86 } else {
87 proc_asset_by_size
88 .get((bt - pb_start) as usize)
89 .and_then(|&ai| {
90 data.procedural_brick_asset_names.get_index(ai as usize).cloned()
91 })
92 };
93 if let Some(host) = host {
94 if host != standalone_host {
95 bricks.entry(comp_ty).or_default().insert(host);
96 }
97 }
98 }
99 }
100 }
101
102 if chunk.num_wires > 0 {
103 let soa = db.wire_chunk_soa(gid, chunk.index)?.to_value();
104 let soa: WireChunkSoA = (&soa).try_into()?;
105 // local and remote ports are distinct types, so handle each in
106 // its own loop (they share component_type_index / port_index).
107 for p in &soa.local_wire_sources {
108 outputs
109 .entry(p.component_type_index)
110 .or_default()
111 .insert(p.port_index);
112 }
113 for p in &soa.remote_wire_sources {
114 outputs
115 .entry(p.component_type_index)
116 .or_default()
117 .insert(p.port_index);
118 }
119 for p in &soa.local_wire_targets {
120 inputs
121 .entry(p.component_type_index)
122 .or_default()
123 .insert(p.port_index);
124 }
125 for p in &soa.remote_wire_targets {
126 inputs
127 .entry(p.component_type_index)
128 .or_default()
129 .insert(p.port_index);
130 }
131 }
132 }
133 }
134
135 // Resolve indices to names.
136 let name_of = |idx: u16| data.component_type_names.get_index(idx as usize).cloned();
137 let port_of = |idx: u16| data.component_wire_port_names.get_index(idx as usize).cloned();
138
139 let all: BTreeSet<u16> = bricks
140 .keys()
141 .chain(inputs.keys())
142 .chain(outputs.keys())
143 .copied()
144 .collect();
145
146 // (name, host bricks, input ports, output ports), sorted by name.
147 let mut rows: Vec<(String, Vec<String>, Vec<String>, Vec<String>)> = Vec::new();
148 for ty in all {
149 let Some(name) = name_of(ty) else { continue };
150 let mut bs: Vec<String> = bricks
151 .get(&ty)
152 .map(|s| s.iter().cloned().collect())
153 .unwrap_or_default();
154 bs.sort();
155 bs.dedup();
156 let mut ins: Vec<String> = inputs
157 .get(&ty)
158 .map(|s| s.iter().filter_map(|&p| port_of(p)).collect())
159 .unwrap_or_default();
160 ins.sort();
161 ins.dedup();
162 let mut outs: Vec<String> = outputs
163 .get(&ty)
164 .map(|s| s.iter().filter_map(|&p| port_of(p)).collect())
165 .unwrap_or_default();
166 outs.sort();
167 outs.dedup();
168 rows.push((name, bs, ins, outs));
169 }
170 rows.sort_by(|a, b| a.0.cmp(&b.0));
171
172 let mut out = String::new();
173 macro_rules! w {
174 ($($t:tt)*) => { writeln!(out, $($t)*).unwrap() };
175 }
176 let slice = |v: &[String]| {
177 v.iter()
178 .map(|s| format!("{s:?}"))
179 .collect::<Vec<_>>()
180 .join(", ")
181 };
182
183 w!("// Autogenerated from a zoo save:");
184 w!("// cargo run --example extract_components -- <zoo.brdb> src/assets/component_catalog.rs");
185 w!("// Do not edit by hand.");
186 w!();
187 w!("/// Per-component catalog entry: the full component type name, its host");
188 w!("/// brick asset(s), and its wire input/output port names. Extracted from a");
189 w!("/// fully-placed, fully-wired \"zoo\" save (mirrors brs-js's COMPONENTS).");
190 w!("#[derive(Debug, Clone, Copy, PartialEq, Eq)]");
191 w!("pub struct ComponentInfo {{");
192 w!(" /// e.g. \"BrickComponentType_WireGraph_Exec_Branch\".");
193 w!(" pub name: &'static str,");
194 w!(" /// Host brick asset name(s) that carry this component.");
195 w!(" pub bricks: &'static [&'static str],");
196 w!(" /// Wire input port names.");
197 w!(" pub inputs: &'static [&'static str],");
198 w!(" /// Wire output port names.");
199 w!(" pub outputs: &'static [&'static str],");
200 w!("}}");
201 w!();
202 w!("impl ComponentInfo {{");
203 w!(" /// The primary host brick asset (first, if any).");
204 w!(" pub const fn brick(&self) -> Option<&'static str> {{");
205 w!(" self.bricks.first().copied()");
206 w!(" }}");
207 w!("}}");
208 w!();
209 w!(
210 "/// Every component present in the zoo, sorted by `name` (binary-searchable)."
211 );
212 w!("pub static COMPONENTS: &[ComponentInfo] = &[");
213 for (name, bs, ins, outs) in &rows {
214 w!(
215 " ComponentInfo {{ name: {name:?}, bricks: &[{}], inputs: &[{}], outputs: &[{}] }},",
216 slice(bs),
217 slice(ins),
218 slice(outs),
219 );
220 }
221 w!("];");
222 w!();
223 w!("/// Look up a component by its full type name.");
224 w!("pub fn component(name: &str) -> Option<&'static ComponentInfo> {{");
225 w!(" COMPONENTS");
226 w!(" .binary_search_by(|c| c.name.cmp(name))");
227 w!(" .ok()");
228 w!(" .map(|i| &COMPONENTS[i])");
229 w!("}}");
230
231 if let Some(ref p) = out_path {
232 std::fs::write(p, &out)?;
233 eprintln!("Wrote {}", p.display());
234 } else {
235 print!("{out}");
236 }
237 eprintln!(
238 "Extracted {} components ({} with host bricks)",
239 rows.len(),
240 rows.iter().filter(|r| !r.1.is_empty()).count(),
241 );
242 Ok(())
243}Trait Implementations§
impl Eq for BrickType
Source§impl Ord for BrickType
impl Ord for BrickType
1.21.0 (const: unstable) · Source§fn max(self, other: Self) -> Selfwhere
Self: Sized,
fn max(self, other: Self) -> Selfwhere
Self: Sized,
Compares and returns the maximum of two values. Read more
Source§impl PartialOrd for BrickType
impl PartialOrd for BrickType
impl StructuralPartialEq for BrickType
Auto Trait Implementations§
impl Freeze for BrickType
impl RefUnwindSafe for BrickType
impl Send for BrickType
impl Sync for BrickType
impl Unpin for BrickType
impl UnsafeUnpin for BrickType
impl UnwindSafe for BrickType
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<Q, K> Comparable<K> for Q
impl<Q, K> Comparable<K> for Q
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
Compare self to
key and return true if they are equal.