Add first blueprint abstraction
This commit is contained in:
parent
505ca6ff5c
commit
2f12802507
4 changed files with 251 additions and 70 deletions
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 use structs::*;
|
||||
pub mod abstraction;
|
||||
|
||||
pub fn decode(s: &str) -> String {
|
||||
let raw = s.trim().as_bytes();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue