use std::error::Error;
use crate::{
pending::BrPendingFs,
schema::{ReadBrdbSchema, as_brdb::AsBrdbValue},
wrapper::{
Brick, Entity, World,
schemas::{
BRICK_CHUNK_INDEX_SOA, BRICK_CHUNK_SOA, BRICK_COMPONENT_SOA, BRICK_WIRE_SOA,
ENTITY_CHUNK_SOA, GLOBAL_DATA_SOA, OWNER_TABLE_SOA,
},
},
};
#[test]
fn test_brick_write() -> Result<(), Box<dyn Error>> {
let mut world = World::new();
world.add_brick(Brick {
position: (0, 0, 3).into(),
color: (255, 0, 0).into(),
..Default::default()
});
world.add_brick_grid(
Entity {
frozen: true,
..Default::default()
},
[Brick {
position: (0, 0, 3).into(),
color: (255, 0, 0).into(),
..Default::default()
}],
);
let pending = world.to_unsaved()?.to_pending()?;
let root = pending.to_root().unwrap();
let world_dir = 'world: {
for (name, root_dir) in root {
let children = root_dir.to_folder().unwrap();
match name.as_str() {
"Meta" => {
children.into_iter().for_each(|(n, _)| match n.as_str() {
"World.json" | "Bundle.json" | "Screenshot.jpg" | "Thumbnail.png" => {}
other => panic!("unknown Meta/{other}"),
});
continue;
}
"World" => {
assert_eq!(children.len(), 1);
break 'world children.into_iter().next().unwrap().1.to_folder().unwrap();
}
other => panic!("unknown {other}"),
};
}
unreachable!()
};
let mut owners_schema = None;
let mut owners_vec = None;
let mut global_data_schema = None;
let mut global_data_vec = None;
let mut bricks_dir = None;
let mut entities_dir = None;
for (n, d) in world_dir {
match (n.as_str(), d) {
("Owners.schema", BrPendingFs::File(Some(data))) => {
owners_schema = Some(data.as_slice().read_brdb_schema()?);
}
("Owners.mps", BrPendingFs::File(data)) => {
owners_vec = data;
}
("GlobalData.schema", BrPendingFs::File(Some(data))) => {
global_data_schema = Some(data.as_slice().read_brdb_schema()?);
}
("GlobalData.mps", BrPendingFs::File(data)) => {
global_data_vec = data;
}
("Bricks", BrPendingFs::Folder(items)) => {
bricks_dir = items;
}
("Entities", BrPendingFs::Folder(items)) => {
entities_dir = items;
}
(name, BrPendingFs::File(_)) => unreachable!("{name}: no more files"),
(name, BrPendingFs::Folder(_)) => unreachable!("{name}: no more folders"),
(name, BrPendingFs::Root(_)) => unreachable!("{name}: no root"),
}
}
let global_data = global_data_vec
.unwrap()
.as_slice()
.read_brdb(global_data_schema.as_ref().unwrap(), GLOBAL_DATA_SOA)?;
let _owners = owners_vec
.unwrap()
.as_slice()
.read_brdb(&owners_schema.unwrap(), OWNER_TABLE_SOA)?;
let mut brick_index_schema = None;
let mut brick_schema = None;
let mut component_schema = None;
let mut wire_schema = None;
let mut brick_grids = None;
for (n, fs) in bricks_dir.unwrap() {
match (n.as_str(), fs) {
("Grids", BrPendingFs::Folder(items)) => {
brick_grids = items;
}
("ChunkIndexShared.schema", BrPendingFs::File(Some(data))) => {
brick_index_schema = Some(data.as_slice().read_brdb_schema()?);
}
("ChunksShared.schema", BrPendingFs::File(Some(data))) => {
brick_schema = Some(data.as_slice().read_brdb_schema()?);
}
("ComponentsShared.schema", BrPendingFs::File(Some(data))) => {
component_schema = Some(data.as_slice().read_brdb_schema()?);
}
("WiresShared.schema", BrPendingFs::File(Some(data))) => {
wire_schema = Some(data.as_slice().read_brdb_schema()?);
}
(other, f) => unreachable!("unknown Bricks/{other}: {f}"),
}
}
let component_schema = component_schema.as_ref().unwrap();
for (grid_id, grid) in brick_grids.unwrap() {
let children = grid.to_folder().unwrap();
for (n, child) in children {
match (n.as_str(), child) {
("Chunks", BrPendingFs::Folder(Some(chunks))) => {
for (_, c) in chunks {
let _chunk = c
.to_file()
.unwrap()
.as_slice()
.read_brdb(brick_schema.as_ref().unwrap(), BRICK_CHUNK_SOA)?;
}
}
("Components", BrPendingFs::Folder(Some(chunks))) => {
for (_, c) in chunks {
let content = c.to_file().unwrap();
let buf = &mut content.as_slice();
let chunk = buf.read_brdb(&component_schema, BRICK_COMPONENT_SOA)?;
let type_counters = chunk.prop("ComponentTypeCounters")?.as_array()?;
for counter in type_counters {
let type_idx = counter.as_struct()?.prop("TypeIndex")?.as_brdb_u32()?;
let num_instances =
counter.as_struct()?.prop("NumInstances")?.as_brdb_u32()?;
let struct_name = global_data
.prop("ComponentDataStructNames")?
.index(type_idx as usize)?
.map(|s| s.as_str())
.transpose()?
.unwrap_or("illegal")
.to_owned();
if struct_name == "None" {
continue;
}
for _ in 0..num_instances {
let _component = buf.read_brdb(&component_schema, &struct_name)?;
}
}
}
}
("Wires", BrPendingFs::Folder(Some(chunks))) => {
for (_, c) in chunks {
let _chunk = c
.to_file()
.unwrap()
.as_slice()
.read_brdb(wire_schema.as_ref().unwrap(), BRICK_WIRE_SOA)?;
}
}
("ChunkIndex.mps", BrPendingFs::File(data)) => {
let _chunk_index = data
.unwrap()
.as_slice()
.read_brdb(brick_index_schema.as_ref().unwrap(), BRICK_CHUNK_INDEX_SOA)?;
}
(n, other) => unreachable!("unknown Grids/{grid_id}/{n}: {other}"),
}
}
}
let mut _entity_index_schema = None;
let mut _entity_index_vec = None;
let mut entity_schema = None;
let mut entity_chunks = None;
for (n, fs) in entities_dir.unwrap() {
match (n.as_str(), fs) {
("Chunks", BrPendingFs::Folder(items)) => {
entity_chunks = items;
}
("ChunksShared.schema", BrPendingFs::File(data)) => {
entity_schema = Some(data.unwrap().as_slice().read_brdb_schema()?);
}
("ChunkIndex.schema", BrPendingFs::File(data)) => {
_entity_index_schema = Some(data.unwrap().as_slice().read_brdb_schema()?);
}
("ChunkIndex.mps", BrPendingFs::File(data)) => {
_entity_index_vec = data;
}
(n, other) => unreachable!("unknown Entities/{n}: {other}"),
}
}
for (_chunk_id, chunk) in entity_chunks.unwrap() {
let content = chunk.to_file().unwrap();
let buf = &mut content.as_slice();
let _chunk_data = buf.read_brdb(entity_schema.as_ref().unwrap(), ENTITY_CHUNK_SOA)?;
}
Ok(())
}