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,
|
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>(
|
pub fn generate_factory<L: Layouter, P: Pathfinder + Sync, R: Rng + SeedableRng + Send + Sync>(
|
||||||
layouter: &L,
|
layouter: &L,
|
||||||
pathfinder: &P,
|
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 connections = Vec::new();
|
||||||
let mut intermediate_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() {
|
for (i, b) in factory_graph.subfactories.iter().enumerate() {
|
||||||
let mut input_connections = factory_graph
|
let mut input_connections = factory_graph
|
||||||
.factory_connections
|
.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_eq!(output_connections.len(), 1);
|
||||||
assert!(input_connections.len() <= 3);
|
assert!(input_connections.len() <= 3);
|
||||||
let output_connection = output_connections.first().unwrap();
|
let output_connection = output_connections.first().unwrap();
|
||||||
let intermediate_output_connection =
|
let intermediate_output_connection = HashMap::from([(
|
||||||
HashMap::from([(output_connection.0, (block_index, 0))]);
|
output_connection.0,
|
||||||
|
IntermediateConnectionEntry {
|
||||||
|
block: Some(block_index),
|
||||||
|
interface: 0,
|
||||||
|
},
|
||||||
|
)]);
|
||||||
|
|
||||||
input_connections.sort_by(|a, b| b.1.amount.total_cmp(&a.1.amount));
|
input_connections.sort_by(|a, b| b.1.amount.total_cmp(&a.1.amount));
|
||||||
let (input_belt1, input_belt2, addition_blocks) = if let Some(
|
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()
|
input_connections.first_chunk()
|
||||||
{
|
{
|
||||||
let c0_bigger = c0.amount > c1.amount + c2.amount;
|
let c0_bigger = c0.amount > c1.amount + c2.amount;
|
||||||
intermediate_connections.push((
|
intermediate_connections.push(IntermediateConnection {
|
||||||
HashMap::from([
|
input: HashMap::from([
|
||||||
(connection_id0, (block_index, if c0_bigger { 1 } else { 0 })),
|
(
|
||||||
(connection_id1, (block_index + 1, 0)),
|
connection_id0,
|
||||||
(connection_id2, (block_index + 1, 1)),
|
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 =
|
let beltspeed =
|
||||||
Beltspeed::from_items_per_second(2.0 * f64::max(c1.amount, c2.amount));
|
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)]) =
|
} else if let Some(&[(connection_id0, c0), (connection_id1, c1)]) =
|
||||||
input_connections.first_chunk()
|
input_connections.first_chunk()
|
||||||
{
|
{
|
||||||
intermediate_connections.push((
|
intermediate_connections.push(IntermediateConnection {
|
||||||
HashMap::from([
|
input: HashMap::from([
|
||||||
(connection_id0, (block_index, 0)),
|
(
|
||||||
(connection_id1, (block_index, 1)),
|
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),
|
Beltspeed::from_items_per_second(c0.amount),
|
||||||
Some(Beltspeed::from_items_per_second(c1.amount)),
|
Some(Beltspeed::from_items_per_second(c1.amount)),
|
||||||
vec![],
|
vec![],
|
||||||
)
|
)
|
||||||
} else if let Some(&[(connection_id, c)]) = input_connections.first_chunk() {
|
} else if let Some(&[(connection_id, c)]) = input_connections.first_chunk() {
|
||||||
intermediate_connections.push((
|
intermediate_connections.push(IntermediateConnection {
|
||||||
HashMap::from([(connection_id, (block_index, 0))]),
|
input: HashMap::from([(
|
||||||
intermediate_output_connection,
|
connection_id,
|
||||||
));
|
IntermediateConnectionEntry {
|
||||||
|
block: Some(block_index),
|
||||||
|
interface: 0,
|
||||||
|
},
|
||||||
|
)]),
|
||||||
|
output: intermediate_output_connection,
|
||||||
|
});
|
||||||
(Beltspeed::from_items_per_second(c.amount), None, vec![])
|
(Beltspeed::from_items_per_second(c.amount), None, vec![])
|
||||||
} else {
|
} else {
|
||||||
unreachable!()
|
unreachable!()
|
||||||
|
|
@ -202,35 +256,51 @@ pub fn generate_factory<L: Layouter, P: Pathfinder + Sync, R: Rng + SeedableRng
|
||||||
}
|
}
|
||||||
Building::ExternalConnection { inputs, outputs } => {
|
Building::ExternalConnection { inputs, outputs } => {
|
||||||
let step = 4;
|
let step = 4;
|
||||||
blocks.push(MacroBlock {
|
let static_input_offset = static_input.len();
|
||||||
size: Position::new(1, step * (inputs + outputs) as PositionType),
|
let static_output_offset = static_output.len();
|
||||||
input: (0..*inputs)
|
static_input.extend((0..*inputs).map(|y| Interface {
|
||||||
.map(|y| Interface {
|
offset: Position::new(
|
||||||
offset: Position::new(0, step * y as PositionType),
|
0,
|
||||||
|
step * (y + static_input_offset + static_output_offset) as PositionType,
|
||||||
|
),
|
||||||
dir: Direction::Left,
|
dir: Direction::Left,
|
||||||
})
|
}));
|
||||||
.collect(),
|
static_output.extend((0..*outputs).map(|y| Interface {
|
||||||
output: (0..*outputs)
|
offset: Position::new(
|
||||||
.map(|y| Interface {
|
0,
|
||||||
offset: Position::new(0, step * (inputs + y) as PositionType),
|
step * (y + static_input_offset + static_output_offset + inputs)
|
||||||
|
as PositionType,
|
||||||
|
),
|
||||||
dir: Direction::Right,
|
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 => {
|
Building::SideLoader => {
|
||||||
let mut blueprint = Blueprint::new();
|
let mut blueprint = Blueprint::new();
|
||||||
|
|
@ -263,18 +333,34 @@ pub fn generate_factory<L: Layouter, P: Pathfinder + Sync, R: Rng + SeedableRng
|
||||||
}],
|
}],
|
||||||
});
|
});
|
||||||
blueprints.push(blueprint);
|
blueprints.push(blueprint);
|
||||||
intermediate_connections.push((
|
intermediate_connections.push(IntermediateConnection {
|
||||||
input_connections
|
input: input_connections
|
||||||
.iter()
|
.iter()
|
||||||
.enumerate()
|
.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<_, _>>(),
|
.collect::<HashMap<_, _>>(),
|
||||||
output_connections
|
output: output_connections
|
||||||
.iter()
|
.iter()
|
||||||
.enumerate()
|
.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<_, _>>(),
|
.collect::<HashMap<_, _>>(),
|
||||||
));
|
});
|
||||||
}
|
}
|
||||||
Building::Splitter => {
|
Building::Splitter => {
|
||||||
let mut blueprint = Blueprint::new();
|
let mut blueprint = Blueprint::new();
|
||||||
|
|
@ -315,18 +401,34 @@ pub fn generate_factory<L: Layouter, P: Pathfinder + Sync, R: Rng + SeedableRng
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
blueprints.push(blueprint);
|
blueprints.push(blueprint);
|
||||||
intermediate_connections.push((
|
intermediate_connections.push(IntermediateConnection {
|
||||||
input_connections
|
input: input_connections
|
||||||
.iter()
|
.iter()
|
||||||
.enumerate()
|
.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<_, _>>(),
|
.collect::<HashMap<_, _>>(),
|
||||||
output_connections
|
output: output_connections
|
||||||
.iter()
|
.iter()
|
||||||
.enumerate()
|
.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<_, _>>(),
|
.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() {
|
for (i, c) in factory_graph.factory_connections.iter().enumerate() {
|
||||||
// dbg!(i, c);
|
// dbg!(i, c);
|
||||||
connections.push(Connection {
|
connections.push(Connection {
|
||||||
startblock: Some(intermediate_connections[c.from].1[&i].0),
|
startblock: intermediate_connections[c.from].output[&i].block,
|
||||||
startpoint: intermediate_connections[c.from].1[&i].1,
|
startpoint: intermediate_connections[c.from].output[&i].interface,
|
||||||
endblock: Some(intermediate_connections[c.to].0[&i].0),
|
endblock: intermediate_connections[c.to].input[&i].block,
|
||||||
endpoint: intermediate_connections[c.to].0[&i].1,
|
endpoint: intermediate_connections[c.to].input[&i].interface,
|
||||||
lanes: 1,
|
lanes: 1,
|
||||||
beltspeed: Beltspeed::from_items_per_second(c.amount),
|
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);
|
// dbg!(&connections);
|
||||||
|
|
||||||
let layout_input = LayoutInput {
|
let layout_input = LayoutInput {
|
||||||
input: Vec::new(),
|
static_input,
|
||||||
output: Vec::new(),
|
static_output,
|
||||||
blocks,
|
blocks,
|
||||||
connections,
|
connections,
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -41,8 +41,8 @@ pub struct Connection {
|
||||||
#[derive(Debug, Serialize, Deserialize)]
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
pub struct LayoutInput {
|
pub struct LayoutInput {
|
||||||
pub blocks: Vec<MacroBlock>,
|
pub blocks: Vec<MacroBlock>,
|
||||||
pub input: Vec<Interface>,
|
pub static_input: Vec<Interface>,
|
||||||
pub output: Vec<Interface>,
|
pub static_output: Vec<Interface>,
|
||||||
pub connections: Vec<Connection>,
|
pub connections: Vec<Connection>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -121,8 +121,8 @@ pub fn path_input_from_blocks_positions(
|
||||||
.dir
|
.dir
|
||||||
.transform(start_transform);
|
.transform(start_transform);
|
||||||
} else {
|
} else {
|
||||||
start_pos = input.output[c.startpoint].offset;
|
start_pos = input.static_output[c.startpoint].offset;
|
||||||
start_dir = input.output[c.startpoint].dir;
|
start_dir = input.static_output[c.startpoint].dir;
|
||||||
}
|
}
|
||||||
let end_pos;
|
let end_pos;
|
||||||
let end_dir;
|
let end_dir;
|
||||||
|
|
@ -135,8 +135,8 @@ pub fn path_input_from_blocks_positions(
|
||||||
.dir
|
.dir
|
||||||
.transform(end_transform);
|
.transform(end_transform);
|
||||||
} else {
|
} else {
|
||||||
end_pos = input.input[c.endpoint].offset;
|
end_pos = input.static_input[c.endpoint].offset;
|
||||||
end_dir = input.input[c.endpoint].dir;
|
end_dir = input.static_input[c.endpoint].dir;
|
||||||
}
|
}
|
||||||
|
|
||||||
connections.push(Connection {
|
connections.push(Connection {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue