1use crate::item;
3
4macro_rules! state_impl {
5 ($vis:vis $type:ty) => {
6 #[must_use] $vis fn get_state(state: &$crate::block::State) -> &$type
7 where Self: Sized {
8 state.downcast_ref::<$type>().unwrap()
9 }
10
11 $vis fn get_state_mut(state: &mut $crate::block::State) -> &mut $type
12 where Self: Sized {
13 state.downcast_mut::<$type>().unwrap()
14 }
15
16 fn create_state(val: $type) -> $crate::block::State
17 where Self: Sized {
18 State::from(val)
19 }
20 };
21}
22
23pub(crate) use state_impl;
24
25macro_rules! make_simple {
28 ($name: ident, $draw: expr, $read: expr) => {
29 pub struct $name {
30 size: u8,
31 symmetric: bool,
32 build_cost: crate::block::simple::BuildCost,
33 }
34 impl $name {
35 #[must_use]
36 pub const fn new(
37 size: u8,
38 symmetric: bool,
39 build_cost: crate::block::simple::BuildCost,
40 ) -> Self {
41 assert!(size != 0, "invalid size");
42 Self {
43 size,
44 symmetric,
45 build_cost,
46 }
47 }
48 }
49
50 impl crate::block::BlockLogic for $name {
51 crate::block::impl_block!();
52
53 fn data_from_i32(
54 &self,
55 _: i32,
56 _: crate::data::GridPos,
57 ) -> Result<crate::data::dynamic::DynData, crate::block::DataConvertError> {
58 Ok(crate::data::dynamic::DynData::Empty)
59 }
60
61 fn deserialize_state(
62 &self,
63 _: crate::data::dynamic::DynData,
64 ) -> Result<Option<crate::block::State>, crate::block::DeserializeError> {
65 Ok(None)
66 }
67
68 fn mirror_state(&self, _: &mut crate::block::State, _: bool, _: bool) {
69 panic!("{} has no custom state", stringify!($name));
70 }
71
72 fn rotate_state(&self, _: &mut crate::block::State, _: bool) {
73 panic!("{} has no custom state", stringify!($name));
74 }
75
76 fn serialize_state(
77 &self,
78 _: &crate::block::State,
79 ) -> Result<crate::data::dynamic::DynData, crate::block::SerializeError> {
80 Ok(crate::data::dynamic::DynData::Empty)
81 }
82
83 fn draw(
84 &self,
85 name: &str,
86 state: Option<&crate::block::State>,
87 context: Option<&crate::data::renderer::RenderingContext>,
88 rot: crate::block::Rotation,
89 scale: crate::data::renderer::Scale,
90 ) -> crate::data::renderer::ImageHolder<4> {
91 $draw(self, name, state, context, rot, scale)
92 }
93
94 fn read(
95 &self,
96 build: &mut crate::data::map::Build,
97 buff: &mut crate::data::DataRead,
98 ) -> Result<(), crate::data::ReadError> {
99 $read(build, buff)
100 }
101 }
102 };
103 ($name: ident, $draw: expr) => {
104 crate::block::simple::make_simple!($name, $draw, |_, _| Ok(()));
105 };
106 ($name: ident, $draw: expr, $read: expr) => {
107 crate::block::simple::make_simple!($name, $draw, $read);
108 };
109 ($name: ident => $read: expr) => {
110 crate::block::simple::make_simple!($name, |_, n, _, _, _, _| unimplemented!("{n}"), $read);
111 };
112 ($name: ident => $draw: expr, $read: expr) => {
113 crate::block::simple::make_simple!($name, |_, _, _, _, _, scl| $draw(scl), $read);
114 };
115 ($name: ident / $draw: expr) => {
116 crate::block::simple::make_simple!($name, |_, _, _, _, _, scl| $draw(scl), |_, _| Ok(()));
117 };
118 ($name: ident) => {
119 crate::block::simple::make_simple!($name, |_, n, _, _, _, _| unimplemented!("{n}"));
120 };
121}
122pub(crate) use make_simple;
123
124pub type BuildCost = &'static [(item::Type, u32)];
125
126macro_rules! cost {
127 ($($item:ident: $cnt:expr),+) => {
128 &[$((crate::item::Type::$item, $cnt)),*]
129 };
130}
131pub(crate) use cost;
132
133make_simple!(BasicBlock);