steel_core/inventory/slots/
normal_slot.rs1use steel_registry::item_stack::ItemStack;
2use steel_utils::{DowncastType, DowncastTypeKey};
3
4use crate::inventory::{
5 lock::{ContainerLockGuard, ContainerRef},
6 slots::slot::{Slot, SlotStorage},
7};
8
9pub struct NormalSlot {
11 storage: SlotStorage,
12}
13
14unsafe impl DowncastType for NormalSlot {
16 const TYPE_KEY: DowncastTypeKey = DowncastTypeKey::new("steel:slot/normal");
17}
18
19impl NormalSlot {
20 pub fn new(container: impl Into<ContainerRef>, index: usize) -> Self {
22 Self {
23 storage: SlotStorage::physical(container, index),
24 }
25 }
26
27 #[must_use]
29 pub fn container_ref(&self) -> ContainerRef {
30 self.backing().0.clone()
31 }
32
33 fn backing(&self) -> (&ContainerRef, usize) {
34 let Some(backing) = self.storage.physical_backing() else {
35 unreachable!("NormalSlot always has physical storage");
36 };
37 backing
38 }
39}
40
41impl Slot for NormalSlot {
42 fn storage(&self) -> &SlotStorage {
43 &self.storage
44 }
45
46 fn get_item<'a>(&self, guard: &'a ContainerLockGuard) -> &'a ItemStack {
47 let (container, index) = self.backing();
48 guard
49 .get(container.container_id())
50 .expect("container not locked")
51 .get_item(index)
52 }
53
54 fn get_item_mut<'a>(&self, guard: &'a mut ContainerLockGuard) -> &'a mut ItemStack {
55 let (container, index) = self.backing();
56 guard
57 .get_mut(container.container_id())
58 .expect("container not locked")
59 .get_item_mut(index)
60 }
61
62 fn set_item(&self, guard: &mut ContainerLockGuard, stack: ItemStack) {
63 let (container, index) = self.backing();
64 assert!(
65 guard.set_item(container.container_id(), index, stack),
66 "container not locked"
67 );
68 self.set_changed(guard);
69 }
70
71 fn remove(&self, guard: &mut ContainerLockGuard, amount: i32) -> ItemStack {
72 if amount <= 0 || self.get_item(guard).is_empty() {
73 return ItemStack::empty();
74 }
75 let (container, index) = self.backing();
76 guard
77 .remove_item(container.container_id(), index, amount)
78 .expect("container not locked")
79 }
80
81 fn set_changed(&self, guard: &mut ContainerLockGuard) {
82 let (container, _) = self.backing();
83 assert!(
84 guard.set_changed(container.container_id()),
85 "container not locked"
86 );
87 }
88
89 fn get_container_slot(&self) -> usize {
90 self.backing().1
91 }
92
93 fn get_max_stack_size(&self, guard: &ContainerLockGuard) -> i32 {
94 let (container, _) = self.backing();
95 guard
96 .get(container.container_id())
97 .expect("container not locked")
98 .get_max_stack_size()
99 }
100}