diff --git a/.gitignore b/.gitignore index 661c5d3..2e90c27 100644 --- a/.gitignore +++ b/.gitignore @@ -3,4 +3,4 @@ flamegraph.svg perf.data* out proptest-regressions -out.* +out* diff --git a/factorio-blueprint-generator/src/bin/generate_factory.rs b/factorio-blueprint-generator/src/bin/generate_factory.rs index 8784b9c..f5c69b7 100644 --- a/factorio-blueprint-generator/src/bin/generate_factory.rs +++ b/factorio-blueprint-generator/src/bin/generate_factory.rs @@ -133,11 +133,15 @@ where b.print_visualization(); - let b = BlueprintString::Blueprint(b.to_blueprint()); + let bs = BlueprintString::Blueprint(b.to_blueprint()); if args.json { - println!("{}", serde_json::to_string_pretty(&b).unwrap()); + println!("{}", serde_json::to_string_pretty(&bs).unwrap()); } - let _ = std::fs::write("out.bp", encode(&serde_json::to_string(&b).unwrap())); + let _ = std::fs::write("out.bp", encode(&serde_json::to_string(&bs).unwrap())); + + let bs2 = factorio_blueprint::abstraction::serde::AbstractBlueprintString { blueprint: &b }; + + let _ = std::fs::write("out2.bp", encode(&serde_json::to_string(&bs2).unwrap())); } diff --git a/factorio-blueprint/src/abstraction.rs b/factorio-blueprint/src/abstraction.rs index 6cbac69..aacf24a 100644 --- a/factorio-blueprint/src/abstraction.rs +++ b/factorio-blueprint/src/abstraction.rs @@ -12,6 +12,7 @@ use std::{collections::HashMap, sync::atomic::AtomicUsize}; mod power_connection; mod roboports; +pub mod serde; mod visualize; #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] @@ -126,6 +127,13 @@ impl DirectionType { DirectionType::QuarterDir(_quater_direction) => panic!(), } } + + fn get_index(&self) -> u8 { + match self { + DirectionType::Dir(direction) => direction.get_index() * 4, + DirectionType::QuarterDir(quater_direction) => quater_direction.to_int_direction(), + } + } } #[derive(Debug, Clone)] diff --git a/factorio-blueprint/src/abstraction/serde.rs b/factorio-blueprint/src/abstraction/serde.rs new file mode 100644 index 0000000..af5e28a --- /dev/null +++ b/factorio-blueprint/src/abstraction/serde.rs @@ -0,0 +1,93 @@ +use factorio_core::prelude::Position; +use serde::{ + Serialize, + ser::{SerializeMap, SerializeSeq, SerializeTuple}, +}; + +use super::{Blueprint, Entity, EntityKey}; + +pub struct AbstractBlueprintString<'a> { + pub blueprint: &'a Blueprint, +} + +impl Serialize for AbstractBlueprintString<'_> { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + let mut blueprint_string_map = serializer.serialize_map(Some(1))?; + + blueprint_string_map.serialize_entry("blueprint", self.blueprint)?; + + blueprint_string_map.end() + } +} + +impl Serialize for Blueprint { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + let mut blueprint_object = serializer.serialize_map(None)?; + + blueprint_object.serialize_entry("label", "test")?; + + blueprint_object.serialize_entry("entities", &SerialzeEntitiesWrapper(&self.entities))?; + + blueprint_object.end() + } +} + +struct SerialzeEntitiesWrapper<'a>(&'a [(EntityKey, Entity)]); + +impl Serialize for SerialzeEntitiesWrapper<'_> { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + let mut entity_array = serializer.serialize_seq(Some(self.0.len()))?; + + for (i, (_, e)) in self.0.iter().enumerate() { + entity_array.serialize_element(&SerializeEntityWrapper(i + 1, &e))?; + } + + entity_array.end() + } +} + +struct SerializeEntityWrapper<'a>(usize, &'a Entity); + +impl Serialize for SerializeEntityWrapper<'_> { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + let mut entity_map = serializer.serialize_map(None)?; + entity_map.serialize_entry("entity_number", &self.0)?; + + entity_map.serialize_entry("name", &self.1.get_name())?; + + entity_map.serialize_entry("position", &SerializePosition(self.1.position))?; + + if self.1.direction.get_index() != 0 { + entity_map.serialize_entry("direction", &self.1.direction.get_index())?; + } + + entity_map.end() + } +} + +struct SerializePosition(Position); +impl Serialize for SerializePosition { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + let mut position_object = serializer.serialize_map(Some(2))?; + + position_object.serialize_entry("x", &(0.5 * self.0.x as f64))?; + position_object.serialize_entry("y", &(0.5 * self.0.y as f64))?; + + position_object.end() + } +}