Add first blueprint abstraction
This commit is contained in:
parent
505ca6ff5c
commit
2f12802507
4 changed files with 251 additions and 70 deletions
|
|
@ -1,8 +1,100 @@
|
||||||
use factorio_blueprint::{
|
use factorio_blueprint::{
|
||||||
Blueprint, BlueprintEntity, BlueprintPosition, belt::convert_to_blueprint,
|
Blueprint, BlueprintEntity, BlueprintPosition,
|
||||||
|
abstraction::{self, Entity},
|
||||||
|
belt::convert_to_blueprint,
|
||||||
};
|
};
|
||||||
use factorio_core::{beltoptions::Beltspeed, pathfield::PathField, prelude::*};
|
use factorio_core::{beltoptions::Beltspeed, pathfield::PathField, prelude::*};
|
||||||
|
|
||||||
|
fn balancer_path() -> Vec<PathField> {
|
||||||
|
vec![
|
||||||
|
PathField::Belt {
|
||||||
|
pos: Position::new(0, 1),
|
||||||
|
dir: Direction::Up,
|
||||||
|
},
|
||||||
|
PathField::Belt {
|
||||||
|
pos: Position::new(3, 1),
|
||||||
|
dir: Direction::Up,
|
||||||
|
},
|
||||||
|
PathField::Belt {
|
||||||
|
pos: Position::new(0, 2),
|
||||||
|
dir: Direction::Up,
|
||||||
|
},
|
||||||
|
PathField::Belt {
|
||||||
|
pos: Position::new(3, 2),
|
||||||
|
dir: Direction::Up,
|
||||||
|
},
|
||||||
|
PathField::Belt {
|
||||||
|
pos: Position::new(0, 3),
|
||||||
|
dir: Direction::Up,
|
||||||
|
},
|
||||||
|
PathField::Belt {
|
||||||
|
pos: Position::new(1, 3),
|
||||||
|
dir: Direction::Left,
|
||||||
|
},
|
||||||
|
PathField::Belt {
|
||||||
|
pos: Position::new(2, 3),
|
||||||
|
dir: Direction::Right,
|
||||||
|
},
|
||||||
|
PathField::Belt {
|
||||||
|
pos: Position::new(3, 3),
|
||||||
|
dir: Direction::Up,
|
||||||
|
},
|
||||||
|
PathField::Belt {
|
||||||
|
pos: Position::new(0, 5),
|
||||||
|
dir: Direction::Right,
|
||||||
|
},
|
||||||
|
PathField::Belt {
|
||||||
|
pos: Position::new(1, 5),
|
||||||
|
dir: Direction::Up,
|
||||||
|
},
|
||||||
|
PathField::Belt {
|
||||||
|
pos: Position::new(2, 5),
|
||||||
|
dir: Direction::Up,
|
||||||
|
},
|
||||||
|
PathField::Belt {
|
||||||
|
pos: Position::new(3, 5),
|
||||||
|
dir: Direction::Left,
|
||||||
|
},
|
||||||
|
PathField::Belt {
|
||||||
|
pos: Position::new(0, 6),
|
||||||
|
dir: Direction::Up,
|
||||||
|
},
|
||||||
|
PathField::Belt {
|
||||||
|
pos: Position::new(3, 6),
|
||||||
|
dir: Direction::Up,
|
||||||
|
},
|
||||||
|
PathField::Underground {
|
||||||
|
pos: Position::new(1, 6),
|
||||||
|
dir: Direction::Up,
|
||||||
|
len: 4,
|
||||||
|
},
|
||||||
|
PathField::Underground {
|
||||||
|
pos: Position::new(2, 6),
|
||||||
|
dir: Direction::Up,
|
||||||
|
len: 4,
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn generate_4_lane_balancer2() -> Blueprint {
|
||||||
|
let mut b = abstraction::Blueprint::new();
|
||||||
|
|
||||||
|
let splitter_pos = [(0, 0), (2, 0), (1, 1), (1, 4), (0, 7), (2, 7)];
|
||||||
|
|
||||||
|
for (x, y) in splitter_pos {
|
||||||
|
b.add_entity(Entity::new(
|
||||||
|
"splitter",
|
||||||
|
Position::new(x, y),
|
||||||
|
Direction::Up,
|
||||||
|
Position::new(2, 1),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
b.add_path(&balancer_path(), Beltspeed::Normal);
|
||||||
|
|
||||||
|
b.to_blueprint()
|
||||||
|
}
|
||||||
|
|
||||||
pub fn generate_4_lane_balancer() -> Blueprint {
|
pub fn generate_4_lane_balancer() -> Blueprint {
|
||||||
let mut e = vec![
|
let mut e = vec![
|
||||||
BlueprintEntity::builder("splitter".to_owned(), 1, BlueprintPosition::new(1.0, 0.5))
|
BlueprintEntity::builder("splitter".to_owned(), 1, BlueprintPosition::new(1.0, 0.5))
|
||||||
|
|
@ -21,74 +113,7 @@ pub fn generate_4_lane_balancer() -> Blueprint {
|
||||||
|
|
||||||
let mut nextfree = e.len() as u32;
|
let mut nextfree = e.len() as u32;
|
||||||
e.extend(convert_to_blueprint(
|
e.extend(convert_to_blueprint(
|
||||||
&[
|
&balancer_path(),
|
||||||
PathField::Belt {
|
|
||||||
pos: Position::new(0, 1),
|
|
||||||
dir: Direction::Up,
|
|
||||||
},
|
|
||||||
PathField::Belt {
|
|
||||||
pos: Position::new(3, 1),
|
|
||||||
dir: Direction::Up,
|
|
||||||
},
|
|
||||||
PathField::Belt {
|
|
||||||
pos: Position::new(0, 2),
|
|
||||||
dir: Direction::Up,
|
|
||||||
},
|
|
||||||
PathField::Belt {
|
|
||||||
pos: Position::new(3, 2),
|
|
||||||
dir: Direction::Up,
|
|
||||||
},
|
|
||||||
PathField::Belt {
|
|
||||||
pos: Position::new(0, 3),
|
|
||||||
dir: Direction::Up,
|
|
||||||
},
|
|
||||||
PathField::Belt {
|
|
||||||
pos: Position::new(1, 3),
|
|
||||||
dir: Direction::Left,
|
|
||||||
},
|
|
||||||
PathField::Belt {
|
|
||||||
pos: Position::new(2, 3),
|
|
||||||
dir: Direction::Right,
|
|
||||||
},
|
|
||||||
PathField::Belt {
|
|
||||||
pos: Position::new(3, 3),
|
|
||||||
dir: Direction::Up,
|
|
||||||
},
|
|
||||||
PathField::Belt {
|
|
||||||
pos: Position::new(0, 5),
|
|
||||||
dir: Direction::Right,
|
|
||||||
},
|
|
||||||
PathField::Belt {
|
|
||||||
pos: Position::new(1, 5),
|
|
||||||
dir: Direction::Up,
|
|
||||||
},
|
|
||||||
PathField::Belt {
|
|
||||||
pos: Position::new(2, 5),
|
|
||||||
dir: Direction::Up,
|
|
||||||
},
|
|
||||||
PathField::Belt {
|
|
||||||
pos: Position::new(3, 5),
|
|
||||||
dir: Direction::Left,
|
|
||||||
},
|
|
||||||
PathField::Belt {
|
|
||||||
pos: Position::new(0, 6),
|
|
||||||
dir: Direction::Up,
|
|
||||||
},
|
|
||||||
PathField::Belt {
|
|
||||||
pos: Position::new(3, 6),
|
|
||||||
dir: Direction::Up,
|
|
||||||
},
|
|
||||||
PathField::Underground {
|
|
||||||
pos: Position::new(1, 6),
|
|
||||||
dir: Direction::Up,
|
|
||||||
len: 4,
|
|
||||||
},
|
|
||||||
PathField::Underground {
|
|
||||||
pos: Position::new(2, 6),
|
|
||||||
dir: Direction::Up,
|
|
||||||
len: 4,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
&Beltspeed::Normal,
|
&Beltspeed::Normal,
|
||||||
&mut nextfree,
|
&mut nextfree,
|
||||||
));
|
));
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,13 @@
|
||||||
use factorio_blueprint::{BlueprintString, encode};
|
use factorio_blueprint::{BlueprintString, encode};
|
||||||
use factorio_blueprint_generator::balancer::generate_4_lane_balancer;
|
use factorio_blueprint_generator::balancer::{generate_4_lane_balancer, generate_4_lane_balancer2};
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let b = BlueprintString::Blueprint(generate_4_lane_balancer());
|
let b = BlueprintString::Blueprint(generate_4_lane_balancer());
|
||||||
|
let b2 = BlueprintString::Blueprint(generate_4_lane_balancer2());
|
||||||
|
|
||||||
|
println!("{}", serde_json::to_string_pretty(&b).unwrap());
|
||||||
println!("{}", serde_json::to_string_pretty(&b).unwrap());
|
println!("{}", serde_json::to_string_pretty(&b).unwrap());
|
||||||
|
|
||||||
println!("{}", encode(&serde_json::to_string(&b).unwrap()));
|
println!("{}", encode(&serde_json::to_string(&b).unwrap()));
|
||||||
|
println!("{}", encode(&serde_json::to_string(&b2).unwrap()));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
152
factorio-blueprint/src/abstraction.rs
Normal file
152
factorio-blueprint/src/abstraction.rs
Normal file
|
|
@ -0,0 +1,152 @@
|
||||||
|
use factorio_core::{
|
||||||
|
beltoptions::Beltspeed,
|
||||||
|
pathfield::PathField,
|
||||||
|
prelude::{Direction, Position, PositionType},
|
||||||
|
};
|
||||||
|
use std::{collections::HashMap, str::FromStr, sync::atomic::AtomicUsize};
|
||||||
|
|
||||||
|
use crate::{BlueprintEntity, BlueprintPosition};
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||||
|
pub enum UndergroundType {
|
||||||
|
Input,
|
||||||
|
Output,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Entity {
|
||||||
|
name: String,
|
||||||
|
position: Position,
|
||||||
|
direction: Direction,
|
||||||
|
size: Position,
|
||||||
|
underground_type: Option<UndergroundType>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Entity {
|
||||||
|
pub fn new(
|
||||||
|
name: impl AsRef<str>,
|
||||||
|
position: Position,
|
||||||
|
direction: Direction,
|
||||||
|
size: Position,
|
||||||
|
) -> Self {
|
||||||
|
Self {
|
||||||
|
name: name.as_ref().to_owned(),
|
||||||
|
position,
|
||||||
|
direction,
|
||||||
|
size,
|
||||||
|
underground_type: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn underground_type(mut self, underground_type: UndergroundType) -> Self {
|
||||||
|
self.underground_type = Some(underground_type);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||||
|
pub struct EntityKey(usize);
|
||||||
|
|
||||||
|
static ENTITY_COUNTER: AtomicUsize = AtomicUsize::new(0);
|
||||||
|
|
||||||
|
pub struct Blueprint {
|
||||||
|
entities: Vec<(EntityKey, Entity)>,
|
||||||
|
keys: HashMap<EntityKey, usize>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Blueprint {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self {
|
||||||
|
entities: Vec::new(),
|
||||||
|
keys: HashMap::new(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn add_entity(&mut self, entity: Entity) -> EntityKey {
|
||||||
|
let id = EntityKey(ENTITY_COUNTER.fetch_add(1, std::sync::atomic::Ordering::Relaxed));
|
||||||
|
let pos = self.entities.len();
|
||||||
|
|
||||||
|
self.keys.insert(id, pos);
|
||||||
|
self.entities.push((id, entity));
|
||||||
|
|
||||||
|
id
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn add_path<'a>(
|
||||||
|
&mut self,
|
||||||
|
path: impl IntoIterator<Item = &'a PathField>,
|
||||||
|
beltspeed: Beltspeed,
|
||||||
|
) {
|
||||||
|
for &p in path {
|
||||||
|
match p {
|
||||||
|
PathField::Belt { pos, dir } => {
|
||||||
|
self.add_entity(Entity::new(
|
||||||
|
beltspeed.string(),
|
||||||
|
pos,
|
||||||
|
dir,
|
||||||
|
Position::new(1, 1),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
PathField::Underground { pos, dir, len } => {
|
||||||
|
self.add_entity(
|
||||||
|
Entity::new(
|
||||||
|
beltspeed.string_underground(),
|
||||||
|
pos,
|
||||||
|
dir,
|
||||||
|
Position::new(1, 1),
|
||||||
|
)
|
||||||
|
.underground_type(UndergroundType::Input),
|
||||||
|
);
|
||||||
|
self.add_entity(
|
||||||
|
Entity::new(
|
||||||
|
beltspeed.string_underground(),
|
||||||
|
pos.in_direction(&dir, len as PositionType),
|
||||||
|
dir,
|
||||||
|
Position::new(1, 1),
|
||||||
|
)
|
||||||
|
.underground_type(UndergroundType::Output),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn to_blueprint(&self) -> super::Blueprint {
|
||||||
|
let entities = self
|
||||||
|
.entities
|
||||||
|
.iter()
|
||||||
|
.enumerate()
|
||||||
|
.map(|(i, (_, e))| {
|
||||||
|
BlueprintEntity::builder(
|
||||||
|
e.name.clone(),
|
||||||
|
i as u32 + 1,
|
||||||
|
BlueprintPosition::new(
|
||||||
|
e.position.x as f64 + 0.5 * e.size.x as f64,
|
||||||
|
e.position.y as f64 + 0.5 * e.size.y as f64,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.direction(match e.direction {
|
||||||
|
Direction::Up => 0,
|
||||||
|
Direction::Right => 4,
|
||||||
|
Direction::Down => 8,
|
||||||
|
Direction::Left => 12,
|
||||||
|
})
|
||||||
|
.maybe_underground_type(e.underground_type.map(|u| match u {
|
||||||
|
UndergroundType::Input => String::from("input"),
|
||||||
|
UndergroundType::Output => String::from("output"),
|
||||||
|
}))
|
||||||
|
.build()
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
super::Blueprint::builder()
|
||||||
|
.label(String::from("test"))
|
||||||
|
.entities(entities)
|
||||||
|
.build()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for Blueprint {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self::new()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -5,6 +5,7 @@ pub mod belt;
|
||||||
pub mod structs;
|
pub mod structs;
|
||||||
|
|
||||||
pub use structs::*;
|
pub use structs::*;
|
||||||
|
pub mod abstraction;
|
||||||
|
|
||||||
pub fn decode(s: &str) -> String {
|
pub fn decode(s: &str) -> String {
|
||||||
let raw = s.trim().as_bytes();
|
let raw = s.trim().as_bytes();
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue