improve block to_props

This commit is contained in:
Alexander Medvedev
2025-11-27 18:44:14 +01:00
parent ed737dd75f
commit 6f7006fcb9
12 changed files with 73 additions and 86 deletions

View File

@@ -154,7 +154,7 @@ impl ToTokens for PropertyStruct {
}
}
fn to_value(&self) -> &str {
fn to_value(&self) -> &'static str {
match self {
#(#to_values),*
}
@@ -200,26 +200,16 @@ impl ToTokens for BlockPropertyStruct {
.map(|(_, id)| *id)
.collect::<Vec<_>>();
let to_index_body = self
.data
.variant_mappings
.iter()
.rev()
.map(|entry| {
let field_name = Ident::new_raw(&entry.original_name, Span::call_site());
match &entry.property_type {
PropertyType::Bool => quote! {
(!self.#field_name as u16, 2)
},
PropertyType::Enum { name } => {
let enum_ident = Ident::new(name, Span::call_site());
quote! {
(self.#field_name.to_index(), #enum_ident::variant_count())
}
}
let to_index_logic = self.data.variant_mappings.iter().rev().map(|entry| {
let field = Ident::new_raw(&entry.original_name, Span::call_site());
match &entry.property_type {
PropertyType::Bool => quote! { (!self.#field as u16, 2) },
PropertyType::Enum { name } => {
let ty = Ident::new(name, Span::call_site());
quote! { (self.#field.to_index(), #ty::variant_count()) }
}
})
.collect::<Vec<_>>();
}
});
let from_index_body = self
.data
@@ -250,15 +240,15 @@ impl ToTokens for BlockPropertyStruct {
})
.collect::<Vec<_>>();
let to_props_values = self.data.variant_mappings.iter().map(|entry| {
let key = &entry.original_name;
let field_name = Ident::new_raw(&entry.original_name, Span::call_site());
let to_props_entries = self.data.variant_mappings.iter().map(|entry| {
let key_str = &entry.original_name;
let field = Ident::new_raw(&entry.original_name, Span::call_site());
match &entry.property_type {
PropertyType::Bool => quote! {
(#key.to_string(), self.#field_name.to_string()),
(#key_str, if self.#field { "true" } else { "false" })
},
PropertyType::Enum { name: _ } => quote! {
(#key.to_string(), self.#field_name.to_value().to_string()),
PropertyType::Enum { .. } => quote! {
(#key_str, self.#field.to_value())
},
}
});
@@ -290,12 +280,10 @@ impl ToTokens for BlockPropertyStruct {
}
impl BlockProperties for #name {
fn to_index(&self) -> u16 {
let (index, _) = [#(#to_index_body),*]
.iter()
.fold((0, 1), |(current_index, multiplier), &(value, count)| {
(current_index + value * multiplier, multiplier * count)
});
fn to_index(&self) -> u16 {
let (index, _) = [#(#to_index_logic),*]
.iter()
.fold((0, 1), |(curr, mul), &(val, count)| (curr + val * mul, mul * count));
index
}
@@ -337,9 +325,10 @@ impl ToTokens for BlockPropertyStruct {
Self::from_state_id(block.default_state.id, block)
}
fn to_props(&self) -> Box<[(String, String)]> {
[#(#to_props_values)*].into()
fn to_props(&self) -> Vec<(&'static str, &'static str)> {
vec![ #(#to_props_entries),* ]
}
fn from_props(props: &[(&str, &str)], block: &Block) -> Self {
if ![#(#block_ids),*].contains(&block.id) {
panic!("{} is not a valid block for {}", &block.name, #struct_name);
@@ -939,7 +928,7 @@ pub(crate) fn build() -> TokenStream {
fn default(block: &Block) -> Self where Self: Sized;
// Convert properties to a `Vec` of `(name, value)`
fn to_props(&self) -> Box<[(String, String)]>;
fn to_props(&self) -> Vec<(&'static str, &'static str)>;
// Convert properties to a block state, and add them onto the default state.
fn from_props(props: &[(&str, &str)], block: &Block) -> Self where Self: Sized;
@@ -949,7 +938,7 @@ pub(crate) fn build() -> TokenStream {
fn variant_count() -> u16;
fn to_index(&self) -> u16;
fn from_index(index: u16) -> Self;
fn to_value(&self) -> &str;
fn to_value(&self) -> &'static str;
fn from_value(value: &str) -> Self;
}

View File

@@ -117,19 +117,20 @@ impl BlockState {
.iter()
.map(|&id| COLLISION_SHAPES[id as usize])
.collect();
let block = Block::from_state_id(self.id);
if block.properties(self.id).and_then(|properties| {
properties
if let Some(props) = block.properties(self.id) {
let is_waterlogged = props
.to_props()
.into_iter()
.find(|p| p.0 == "waterlogged")
.map(|(_, value)| value == true.to_string())
}) == Some(true)
{
// If the block is waterlogged, add a water shape
let shape =
&CollisionShape::new(Vector3::new(0.0, 0.0, 0.0), Vector3::new(1.0, 0.875, 1.0));
shapes.push(*shape);
.iter()
.any(|(k, v)| *k == "waterlogged" && *v == "true");
if is_waterlogged {
shapes.push(CollisionShape::new(
Vector3::new(0.0, 0.0, 0.0),
Vector3::new(1.0, 0.875, 1.0),
));
}
}
Some(shapes)

View File

@@ -51,17 +51,18 @@ impl BlockStateCodec {
pub fn get_state_id(&self) -> BlockStateId {
let block = self.name;
let mut state_id = block.default_state.id;
let properties_map = match &self.properties {
Some(map) => map,
None => return block.default_state.id,
};
if let Some(properties) = &self.properties {
let props: Vec<(&str, &str)> = properties
.iter()
.map(|(k, v)| (k.as_str(), v.as_str()))
.collect();
let block_properties = block.from_properties(&props);
state_id = block_properties.to_state_id(block);
}
state_id
let props_iter = properties_map
.iter()
.map(|(k, v)| (k.as_str(), v.as_str()))
.collect::<Vec<(&str, &str)>>();
let block_properties = block.from_properties(&props_iter);
block_properties.to_state_id(block)
}
}

View File

@@ -527,9 +527,12 @@ impl BlockPalette {
BlockStateCodec {
name: block,
properties: block
.properties(registry_id)
.map(|p| p.to_props().into_iter().collect()),
properties: block.properties(registry_id).map(|p| {
p.to_props()
.into_iter()
.map(|(k, v)| (k.to_owned(), v.to_owned()))
.collect()
}),
}
}
}

View File

@@ -62,10 +62,10 @@ impl CoralFeature {
let props: Vec<(&str, &str)> = original_props
.iter()
.map(|(key, value)| {
if key == "facing" {
(key.as_str(), facing.to_value())
if *key == "facing" {
(*key, facing.to_value())
} else {
(key.as_str(), value.as_str())
(*key, *value)
}
})
.collect();

View File

@@ -150,13 +150,13 @@ impl FancyTrunkPlacer {
let original_props = &block.properties(trunk_provider.id).unwrap().to_props();
let axis = axis.to_value();
// Set the right Axis
let props: Vec<(&str, &str)> = original_props
let props: Vec<(&'static str, &'static str)> = original_props
.iter()
.map(|(key, value)| {
if key == "axis" {
(key.as_str(), axis)
if *key == "axis" {
(*key, axis)
} else {
(key.as_str(), value.as_str())
(*key, *value)
}
})
.collect();

View File

@@ -95,7 +95,7 @@ pub trait FlowingFluid {
&& properties
.to_props()
.iter()
.any(|(key, value)| key == "waterlogged" && value == "true")
.any(|(key, value)| *key == "waterlogged" && *value == "true")
{
return Some(state_id);
}

View File

@@ -84,10 +84,10 @@ fn set_waterlogged(block: &Block, state: u16, waterlogged: bool) -> u16 {
let props: Vec<(&str, &str)> = original_props
.iter()
.map(|(key, value)| {
if key == "waterlogged" {
if *key == "waterlogged" {
("waterlogged", waterlogged.as_str())
} else {
(key.as_str(), value.as_str())
(*key, *value)
}
})
.collect();

View File

@@ -40,10 +40,10 @@ impl ItemBehaviour for EnderEyeItem {
let props: Vec<(&str, &str)> = original_props
.iter()
.map(|(key, value)| {
if key == "eye" {
(key.as_str(), "true")
if *key == "eye" {
(*key, "true")
} else {
(key.as_str(), value.as_str())
(*key, *value)
}
})
.collect();

View File

@@ -52,19 +52,14 @@ fn can_be_lit(block: &Block, state_id: u16) -> Option<u16> {
None => return None,
};
if let Some((_, value)) = props.iter_mut().find(|(k, _)| k == "extinguished") {
*value = "false".into();
} else if let Some((_, value)) = props.iter_mut().find(|(k, _)| k == "lit") {
*value = "true".into();
if let Some((_, value)) = props.iter_mut().find(|(k, _)| *k == "extinguished") {
*value = "false";
} else if let Some((_, value)) = props.iter_mut().find(|(k, _)| *k == "lit") {
*value = "true";
} else {
return None;
}
let props: Vec<(&str, &str)> = props
.iter()
.map(|(k, v)| (k.as_str(), v.as_str()))
.collect();
let new_state_id = block.from_properties(&props).to_state_id(block);
(new_state_id != state_id).then_some(new_state_id)

View File

@@ -177,7 +177,7 @@ impl LootConditionExt for LootCondition {
properties,
} => {
if let Some(state) = &params.block_state {
let block_actual_properties: Box<[(String, String)]> =
let block_actual_properties =
match Block::properties(Block::from_state_id(state.id), state.id) {
Some(props_data) => props_data.to_props(), // Assuming to_props() returns HashMap<String, String>
None => {

View File

@@ -2723,12 +2723,10 @@ impl World {
let block = Block::from_state_id(id);
if let Some(properties) = block.properties(id) {
for (name, value) in properties.to_props() {
if name == *"waterlogged" {
if name == "waterlogged" {
if value == true.to_string() {
let fluid = Fluid::FLOWING_WATER;
let state = fluid.states[0].clone();
return (fluid, state);
}