Use stationary interfaces for external connections
This commit is contained in:
parent
fda5361a2b
commit
41a528a49c
3 changed files with 171 additions and 69 deletions
|
|
@ -38,6 +38,16 @@ pub struct FactoryConnection {
|
|||
pub to: usize,
|
||||
}
|
||||
|
||||
struct IntermediateConnection {
|
||||
input: HashMap<usize, IntermediateConnectionEntry>,
|
||||
output: HashMap<usize, IntermediateConnectionEntry>,
|
||||
}
|
||||
|
||||
struct IntermediateConnectionEntry {
|
||||
block: Option<usize>,
|
||||
interface: usize,
|
||||
}
|
||||
|
||||
pub fn generate_factory<L: Layouter, P: Pathfinder + Sync, R: Rng + SeedableRng + Send + Sync>(
|
||||
layouter: &L,
|
||||
pathfinder: &P,
|
||||
|
|
@ -49,6 +59,9 @@ pub fn generate_factory<L: Layouter, P: Pathfinder + Sync, R: Rng + SeedableRng
|
|||
let mut connections = Vec::new();
|
||||
let mut intermediate_connections = Vec::new();
|
||||
|
||||
let mut static_input = Vec::new();
|
||||
let mut static_output = Vec::new();
|
||||
|
||||
for (i, b) in factory_graph.subfactories.iter().enumerate() {
|
||||
let mut input_connections = factory_graph
|
||||
.factory_connections
|
||||
|
|
@ -76,8 +89,13 @@ pub fn generate_factory<L: Layouter, P: Pathfinder + Sync, R: Rng + SeedableRng
|
|||
assert_eq!(output_connections.len(), 1);
|
||||
assert!(input_connections.len() <= 3);
|
||||
let output_connection = output_connections.first().unwrap();
|
||||
let intermediate_output_connection =
|
||||
HashMap::from([(output_connection.0, (block_index, 0))]);
|
||||
let intermediate_output_connection = HashMap::from([(
|
||||
output_connection.0,
|
||||
IntermediateConnectionEntry {
|
||||
block: Some(block_index),
|
||||
interface: 0,
|
||||
},
|
||||
)]);
|
||||
|
||||
input_connections.sort_by(|a, b| b.1.amount.total_cmp(&a.1.amount));
|
||||
let (input_belt1, input_belt2, addition_blocks) = if let Some(
|
||||
|
|
@ -90,14 +108,32 @@ pub fn generate_factory<L: Layouter, P: Pathfinder + Sync, R: Rng + SeedableRng
|
|||
input_connections.first_chunk()
|
||||
{
|
||||
let c0_bigger = c0.amount > c1.amount + c2.amount;
|
||||
intermediate_connections.push((
|
||||
HashMap::from([
|
||||
(connection_id0, (block_index, if c0_bigger { 1 } else { 0 })),
|
||||
(connection_id1, (block_index + 1, 0)),
|
||||
(connection_id2, (block_index + 1, 1)),
|
||||
intermediate_connections.push(IntermediateConnection {
|
||||
input: HashMap::from([
|
||||
(
|
||||
connection_id0,
|
||||
IntermediateConnectionEntry {
|
||||
block: Some(block_index),
|
||||
interface: if c0_bigger { 1 } else { 0 },
|
||||
},
|
||||
),
|
||||
(
|
||||
connection_id1,
|
||||
IntermediateConnectionEntry {
|
||||
block: Some(block_index + 1),
|
||||
interface: 0,
|
||||
},
|
||||
),
|
||||
(
|
||||
connection_id2,
|
||||
IntermediateConnectionEntry {
|
||||
block: Some(block_index + 1),
|
||||
interface: 1,
|
||||
},
|
||||
),
|
||||
]),
|
||||
intermediate_output_connection,
|
||||
));
|
||||
output: intermediate_output_connection,
|
||||
});
|
||||
|
||||
let beltspeed =
|
||||
Beltspeed::from_items_per_second(2.0 * f64::max(c1.amount, c2.amount));
|
||||
|
|
@ -144,23 +180,41 @@ pub fn generate_factory<L: Layouter, P: Pathfinder + Sync, R: Rng + SeedableRng
|
|||
} else if let Some(&[(connection_id0, c0), (connection_id1, c1)]) =
|
||||
input_connections.first_chunk()
|
||||
{
|
||||
intermediate_connections.push((
|
||||
HashMap::from([
|
||||
(connection_id0, (block_index, 0)),
|
||||
(connection_id1, (block_index, 1)),
|
||||
intermediate_connections.push(IntermediateConnection {
|
||||
input: HashMap::from([
|
||||
(
|
||||
connection_id0,
|
||||
IntermediateConnectionEntry {
|
||||
block: Some(block_index),
|
||||
interface: 0,
|
||||
},
|
||||
),
|
||||
(
|
||||
connection_id1,
|
||||
IntermediateConnectionEntry {
|
||||
block: Some(block_index),
|
||||
interface: 1,
|
||||
},
|
||||
),
|
||||
]),
|
||||
intermediate_output_connection,
|
||||
));
|
||||
output: intermediate_output_connection,
|
||||
});
|
||||
(
|
||||
Beltspeed::from_items_per_second(c0.amount),
|
||||
Some(Beltspeed::from_items_per_second(c1.amount)),
|
||||
vec![],
|
||||
)
|
||||
} else if let Some(&[(connection_id, c)]) = input_connections.first_chunk() {
|
||||
intermediate_connections.push((
|
||||
HashMap::from([(connection_id, (block_index, 0))]),
|
||||
intermediate_output_connection,
|
||||
));
|
||||
intermediate_connections.push(IntermediateConnection {
|
||||
input: HashMap::from([(
|
||||
connection_id,
|
||||
IntermediateConnectionEntry {
|
||||
block: Some(block_index),
|
||||
interface: 0,
|
||||
},
|
||||
)]),
|
||||
output: intermediate_output_connection,
|
||||
});
|
||||
(Beltspeed::from_items_per_second(c.amount), None, vec![])
|
||||
} else {
|
||||
unreachable!()
|
||||
|
|
@ -202,35 +256,51 @@ pub fn generate_factory<L: Layouter, P: Pathfinder + Sync, R: Rng + SeedableRng
|
|||
}
|
||||
Building::ExternalConnection { inputs, outputs } => {
|
||||
let step = 4;
|
||||
blocks.push(MacroBlock {
|
||||
size: Position::new(1, step * (inputs + outputs) as PositionType),
|
||||
input: (0..*inputs)
|
||||
.map(|y| Interface {
|
||||
offset: Position::new(0, step * y as PositionType),
|
||||
let static_input_offset = static_input.len();
|
||||
let static_output_offset = static_output.len();
|
||||
static_input.extend((0..*inputs).map(|y| Interface {
|
||||
offset: Position::new(
|
||||
0,
|
||||
step * (y + static_input_offset + static_output_offset) as PositionType,
|
||||
),
|
||||
dir: Direction::Left,
|
||||
})
|
||||
.collect(),
|
||||
output: (0..*outputs)
|
||||
.map(|y| Interface {
|
||||
offset: Position::new(0, step * (inputs + y) as PositionType),
|
||||
}));
|
||||
static_output.extend((0..*outputs).map(|y| Interface {
|
||||
offset: Position::new(
|
||||
0,
|
||||
step * (y + static_input_offset + static_output_offset + inputs)
|
||||
as PositionType,
|
||||
),
|
||||
dir: Direction::Right,
|
||||
}));
|
||||
intermediate_connections.push(IntermediateConnection {
|
||||
input: input_connections
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|(port, &(connection_id, _))| {
|
||||
(
|
||||
connection_id,
|
||||
IntermediateConnectionEntry {
|
||||
block: None,
|
||||
interface: static_input_offset + port,
|
||||
},
|
||||
)
|
||||
})
|
||||
.collect(),
|
||||
.collect::<HashMap<_, _>>(),
|
||||
output: output_connections
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|(port, &(connection_id, _))| {
|
||||
(
|
||||
connection_id,
|
||||
IntermediateConnectionEntry {
|
||||
block: None,
|
||||
interface: static_output_offset + port,
|
||||
},
|
||||
)
|
||||
})
|
||||
.collect::<HashMap<_, _>>(),
|
||||
});
|
||||
|
||||
blueprints.push(Blueprint::new());
|
||||
intermediate_connections.push((
|
||||
input_connections
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|(port, &(connection_id, _))| (connection_id, (block_index, port)))
|
||||
.collect::<HashMap<_, _>>(),
|
||||
output_connections
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|(port, &(connection_id, _))| (connection_id, (block_index, port)))
|
||||
.collect::<HashMap<_, _>>(),
|
||||
));
|
||||
}
|
||||
Building::SideLoader => {
|
||||
let mut blueprint = Blueprint::new();
|
||||
|
|
@ -263,18 +333,34 @@ pub fn generate_factory<L: Layouter, P: Pathfinder + Sync, R: Rng + SeedableRng
|
|||
}],
|
||||
});
|
||||
blueprints.push(blueprint);
|
||||
intermediate_connections.push((
|
||||
input_connections
|
||||
intermediate_connections.push(IntermediateConnection {
|
||||
input: input_connections
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|(port, &(connection_id, _))| (connection_id, (block_index, port)))
|
||||
.map(|(port, &(connection_id, _))| {
|
||||
(
|
||||
connection_id,
|
||||
IntermediateConnectionEntry {
|
||||
block: Some(block_index),
|
||||
interface: port,
|
||||
},
|
||||
)
|
||||
})
|
||||
.collect::<HashMap<_, _>>(),
|
||||
output_connections
|
||||
output: output_connections
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|(port, &(connection_id, _))| (connection_id, (block_index, port)))
|
||||
.map(|(port, &(connection_id, _))| {
|
||||
(
|
||||
connection_id,
|
||||
IntermediateConnectionEntry {
|
||||
block: Some(block_index),
|
||||
interface: port,
|
||||
},
|
||||
)
|
||||
})
|
||||
.collect::<HashMap<_, _>>(),
|
||||
));
|
||||
});
|
||||
}
|
||||
Building::Splitter => {
|
||||
let mut blueprint = Blueprint::new();
|
||||
|
|
@ -315,18 +401,34 @@ pub fn generate_factory<L: Layouter, P: Pathfinder + Sync, R: Rng + SeedableRng
|
|||
],
|
||||
});
|
||||
blueprints.push(blueprint);
|
||||
intermediate_connections.push((
|
||||
input_connections
|
||||
intermediate_connections.push(IntermediateConnection {
|
||||
input: input_connections
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|(port, &(connection_id, _))| (connection_id, (block_index, port)))
|
||||
.map(|(port, &(connection_id, _))| {
|
||||
(
|
||||
connection_id,
|
||||
IntermediateConnectionEntry {
|
||||
block: Some(block_index),
|
||||
interface: port,
|
||||
},
|
||||
)
|
||||
})
|
||||
.collect::<HashMap<_, _>>(),
|
||||
output_connections
|
||||
output: output_connections
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|(port, &(connection_id, _))| (connection_id, (block_index, port)))
|
||||
.map(|(port, &(connection_id, _))| {
|
||||
(
|
||||
connection_id,
|
||||
IntermediateConnectionEntry {
|
||||
block: Some(block_index),
|
||||
interface: port,
|
||||
},
|
||||
)
|
||||
})
|
||||
.collect::<HashMap<_, _>>(),
|
||||
));
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -335,10 +437,10 @@ pub fn generate_factory<L: Layouter, P: Pathfinder + Sync, R: Rng + SeedableRng
|
|||
for (i, c) in factory_graph.factory_connections.iter().enumerate() {
|
||||
// dbg!(i, c);
|
||||
connections.push(Connection {
|
||||
startblock: Some(intermediate_connections[c.from].1[&i].0),
|
||||
startpoint: intermediate_connections[c.from].1[&i].1,
|
||||
endblock: Some(intermediate_connections[c.to].0[&i].0),
|
||||
endpoint: intermediate_connections[c.to].0[&i].1,
|
||||
startblock: intermediate_connections[c.from].output[&i].block,
|
||||
startpoint: intermediate_connections[c.from].output[&i].interface,
|
||||
endblock: intermediate_connections[c.to].input[&i].block,
|
||||
endpoint: intermediate_connections[c.to].input[&i].interface,
|
||||
lanes: 1,
|
||||
beltspeed: Beltspeed::from_items_per_second(c.amount),
|
||||
});
|
||||
|
|
@ -348,8 +450,8 @@ pub fn generate_factory<L: Layouter, P: Pathfinder + Sync, R: Rng + SeedableRng
|
|||
// dbg!(&connections);
|
||||
|
||||
let layout_input = LayoutInput {
|
||||
input: Vec::new(),
|
||||
output: Vec::new(),
|
||||
static_input,
|
||||
static_output,
|
||||
blocks,
|
||||
connections,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -41,8 +41,8 @@ pub struct Connection {
|
|||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct LayoutInput {
|
||||
pub blocks: Vec<MacroBlock>,
|
||||
pub input: Vec<Interface>,
|
||||
pub output: Vec<Interface>,
|
||||
pub static_input: Vec<Interface>,
|
||||
pub static_output: Vec<Interface>,
|
||||
pub connections: Vec<Connection>,
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -121,8 +121,8 @@ pub fn path_input_from_blocks_positions(
|
|||
.dir
|
||||
.transform(start_transform);
|
||||
} else {
|
||||
start_pos = input.output[c.startpoint].offset;
|
||||
start_dir = input.output[c.startpoint].dir;
|
||||
start_pos = input.static_output[c.startpoint].offset;
|
||||
start_dir = input.static_output[c.startpoint].dir;
|
||||
}
|
||||
let end_pos;
|
||||
let end_dir;
|
||||
|
|
@ -135,8 +135,8 @@ pub fn path_input_from_blocks_positions(
|
|||
.dir
|
||||
.transform(end_transform);
|
||||
} else {
|
||||
end_pos = input.input[c.endpoint].offset;
|
||||
end_dir = input.input[c.endpoint].dir;
|
||||
end_pos = input.static_input[c.endpoint].offset;
|
||||
end_dir = input.static_input[c.endpoint].dir;
|
||||
}
|
||||
|
||||
connections.push(Connection {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue