steel_core/block_entity/
components.rs1use rustc_hash::FxHashSet;
7use steel_registry::data_components::{
8 Component, ComponentPatchEntry, DataComponentMap, DataComponentType,
9 vanilla_components::{BLOCK_ENTITY_DATA, BLOCK_STATE},
10};
11use steel_registry::item_stack::ItemStack;
12use steel_utils::{DowncastType, Identifier};
13
14pub struct ImplicitComponentGetter<'a> {
17 stack: &'a ItemStack,
18 consumed: FxHashSet<Identifier>,
19}
20
21impl<'a> ImplicitComponentGetter<'a> {
22 pub(super) fn new(stack: &'a ItemStack) -> Self {
23 let consumed = [BLOCK_ENTITY_DATA.key().clone(), BLOCK_STATE.key().clone()]
24 .into_iter()
25 .collect();
26 Self { stack, consumed }
27 }
28
29 pub fn get<T: Component + DowncastType + Clone>(
31 &mut self,
32 component: DataComponentType<T>,
33 ) -> Option<T> {
34 self.consumed.insert(component.key().clone());
35 self.stack.get(component).cloned()
36 }
37
38 pub fn get_or_default<T: Component + DowncastType + Clone>(
40 &mut self,
41 component: DataComponentType<T>,
42 default: T,
43 ) -> T {
44 self.get(component).unwrap_or(default)
45 }
46
47 pub(super) fn remaining_stored_components(self) -> DataComponentMap {
49 let mut components = DataComponentMap::new();
50 for (key, entry) in self.stack.components_patch().iter() {
51 if self.consumed.contains(key) {
52 continue;
53 }
54 if let ComponentPatchEntry::Set(data) = entry {
55 components.set_raw(key.clone(), data.clone());
56 }
57 }
58 components
59 }
60}