Move rules to a Resource
This commit is contained in:
parent
cd0674fdff
commit
af6fdb085b
|
@ -31,6 +31,7 @@ impl Plugin for FallingSandPlugin {
|
||||||
)
|
)
|
||||||
.chain(),
|
.chain(),
|
||||||
);
|
);
|
||||||
|
app.init_resource::<FallingSandRules>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -67,58 +68,16 @@ pub struct Chunk {
|
||||||
height: usize,
|
height: usize,
|
||||||
cells: Vec<Element>,
|
cells: Vec<Element>,
|
||||||
dirty_rect: DirtyRect,
|
dirty_rect: DirtyRect,
|
||||||
rules: HashMap<u32, u32>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Chunk {
|
impl Chunk {
|
||||||
pub fn new(width: usize, height: usize) -> Self {
|
pub fn new(width: usize, height: usize) -> Self {
|
||||||
// Pre-computed air-sand rules
|
|
||||||
let rules = HashMap::from([
|
|
||||||
gen_rule(
|
|
||||||
(Element::Air, Element::Sand, Element::Air, Element::Air),
|
|
||||||
(Element::Air, Element::Air, Element::Air, Element::Sand),
|
|
||||||
),
|
|
||||||
gen_rule(
|
|
||||||
(Element::Air, Element::Sand, Element::Air, Element::Sand),
|
|
||||||
(Element::Air, Element::Air, Element::Sand, Element::Sand),
|
|
||||||
),
|
|
||||||
gen_rule(
|
|
||||||
(Element::Air, Element::Sand, Element::Sand, Element::Air),
|
|
||||||
(Element::Air, Element::Air, Element::Sand, Element::Sand),
|
|
||||||
),
|
|
||||||
gen_rule(
|
|
||||||
(Element::Sand, Element::Air, Element::Air, Element::Air),
|
|
||||||
(Element::Air, Element::Air, Element::Sand, Element::Air),
|
|
||||||
),
|
|
||||||
gen_rule(
|
|
||||||
(Element::Sand, Element::Air, Element::Air, Element::Sand),
|
|
||||||
(Element::Air, Element::Air, Element::Sand, Element::Sand),
|
|
||||||
),
|
|
||||||
gen_rule(
|
|
||||||
(Element::Sand, Element::Air, Element::Sand, Element::Air),
|
|
||||||
(Element::Air, Element::Air, Element::Sand, Element::Sand),
|
|
||||||
),
|
|
||||||
gen_rule(
|
|
||||||
(Element::Sand, Element::Sand, Element::Air, Element::Air),
|
|
||||||
(Element::Air, Element::Air, Element::Sand, Element::Sand),
|
|
||||||
),
|
|
||||||
gen_rule(
|
|
||||||
(Element::Sand, Element::Sand, Element::Air, Element::Sand),
|
|
||||||
(Element::Air, Element::Sand, Element::Sand, Element::Sand),
|
|
||||||
),
|
|
||||||
gen_rule(
|
|
||||||
(Element::Sand, Element::Sand, Element::Sand, Element::Air),
|
|
||||||
(Element::Sand, Element::Air, Element::Sand, Element::Sand),
|
|
||||||
),
|
|
||||||
]);
|
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
step: 0,
|
step: 0,
|
||||||
width,
|
width,
|
||||||
height,
|
height,
|
||||||
cells: vec![Element::Air; width * height],
|
cells: vec![Element::Air; width * height],
|
||||||
dirty_rect: DirtyRect::default(),
|
dirty_rect: DirtyRect::default(),
|
||||||
rules,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -150,13 +109,6 @@ impl Chunk {
|
||||||
|
|
||||||
Some(self.cells[x + y * self.width])
|
Some(self.cells[x + y * self.width])
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_rule_result(&self, input: u32) -> u32 {
|
|
||||||
match self.rules.get(&input) {
|
|
||||||
Some(&result) => result,
|
|
||||||
None => input,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn place_sand_system(mut chunk: Query<&mut Chunk>) {
|
pub fn place_sand_system(mut chunk: Query<&mut Chunk>) {
|
||||||
|
@ -173,7 +125,7 @@ pub fn place_sand_system(mut chunk: Query<&mut Chunk>) {
|
||||||
chunk.set_cell(x, y, Element::Sand);
|
chunk.set_cell(x, y, Element::Sand);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn simulate_chunk_system(mut chunk: Query<&mut Chunk>) {
|
pub fn simulate_chunk_system(rules: Res<FallingSandRules>, mut chunk: Query<&mut Chunk>) {
|
||||||
// We know for now there's only one chunk
|
// We know for now there's only one chunk
|
||||||
let chunk = chunk.get_single_mut();
|
let chunk = chunk.get_single_mut();
|
||||||
if chunk.is_err() {
|
if chunk.is_err() {
|
||||||
|
@ -210,7 +162,7 @@ pub fn simulate_chunk_system(mut chunk: Query<&mut Chunk>) {
|
||||||
chunk.get_cell(x, y).unwrap_or(Element::None),
|
chunk.get_cell(x, y).unwrap_or(Element::None),
|
||||||
chunk.get_cell(x + 1, y).unwrap_or(Element::None),
|
chunk.get_cell(x + 1, y).unwrap_or(Element::None),
|
||||||
));
|
));
|
||||||
let end_state = chunk.get_rule_result(start_state);
|
let end_state = rules.get_result(start_state);
|
||||||
|
|
||||||
// We only need to actually update things if the state changed
|
// We only need to actually update things if the state changed
|
||||||
// Same ordering as above.
|
// Same ordering as above.
|
||||||
|
@ -298,3 +250,63 @@ fn gen_rule(
|
||||||
fn to_rule_state(input: (Element, Element, Element, Element)) -> u32 {
|
fn to_rule_state(input: (Element, Element, Element, Element)) -> u32 {
|
||||||
((input.0 as u32) << 24) + ((input.1 as u32) << 16) + ((input.2 as u32) << 8) + input.3 as u32
|
((input.0 as u32) << 24) + ((input.1 as u32) << 16) + ((input.2 as u32) << 8) + input.3 as u32
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Resource)]
|
||||||
|
pub struct FallingSandRules {
|
||||||
|
rules: HashMap<u32, u32>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for FallingSandRules {
|
||||||
|
fn default() -> Self {
|
||||||
|
// Pre-computed air-sand rules
|
||||||
|
Self {
|
||||||
|
rules: HashMap::from([
|
||||||
|
gen_rule(
|
||||||
|
(Element::Air, Element::Sand, Element::Air, Element::Air),
|
||||||
|
(Element::Air, Element::Air, Element::Air, Element::Sand),
|
||||||
|
),
|
||||||
|
gen_rule(
|
||||||
|
(Element::Air, Element::Sand, Element::Air, Element::Sand),
|
||||||
|
(Element::Air, Element::Air, Element::Sand, Element::Sand),
|
||||||
|
),
|
||||||
|
gen_rule(
|
||||||
|
(Element::Air, Element::Sand, Element::Sand, Element::Air),
|
||||||
|
(Element::Air, Element::Air, Element::Sand, Element::Sand),
|
||||||
|
),
|
||||||
|
gen_rule(
|
||||||
|
(Element::Sand, Element::Air, Element::Air, Element::Air),
|
||||||
|
(Element::Air, Element::Air, Element::Sand, Element::Air),
|
||||||
|
),
|
||||||
|
gen_rule(
|
||||||
|
(Element::Sand, Element::Air, Element::Air, Element::Sand),
|
||||||
|
(Element::Air, Element::Air, Element::Sand, Element::Sand),
|
||||||
|
),
|
||||||
|
gen_rule(
|
||||||
|
(Element::Sand, Element::Air, Element::Sand, Element::Air),
|
||||||
|
(Element::Air, Element::Air, Element::Sand, Element::Sand),
|
||||||
|
),
|
||||||
|
gen_rule(
|
||||||
|
(Element::Sand, Element::Sand, Element::Air, Element::Air),
|
||||||
|
(Element::Air, Element::Air, Element::Sand, Element::Sand),
|
||||||
|
),
|
||||||
|
gen_rule(
|
||||||
|
(Element::Sand, Element::Sand, Element::Air, Element::Sand),
|
||||||
|
(Element::Air, Element::Sand, Element::Sand, Element::Sand),
|
||||||
|
),
|
||||||
|
gen_rule(
|
||||||
|
(Element::Sand, Element::Sand, Element::Sand, Element::Air),
|
||||||
|
(Element::Sand, Element::Air, Element::Sand, Element::Sand),
|
||||||
|
),
|
||||||
|
]),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FallingSandRules {
|
||||||
|
pub fn get_result(&self, input_rule: u32) -> u32 {
|
||||||
|
match self.rules.get(&input_rule) {
|
||||||
|
Some(&result) => result,
|
||||||
|
None => input_rule,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue