parse screen into enum at compile time

This commit is contained in:
Alexander Medvedev 2025-01-10 14:31:43 +01:00
parent 03e81a1436
commit 1208e67f36
13 changed files with 21 additions and 75 deletions

View File

@ -8,6 +8,7 @@ build = "build/build.rs"
serde.workspace = true serde.workspace = true
serde_json.workspace = true serde_json.workspace = true
heck = "0.5.0"
proc-macro2 = "1.0" proc-macro2 = "1.0"
quote = "1.0" quote = "1.0"
syn = "2.0" syn = "2.0"

View File

@ -1,3 +1,7 @@
pub mod packet { pub mod packet {
include!(concat!(env!("OUT_DIR"), "/packet.rs")); include!(concat!(env!("OUT_DIR"), "/packet.rs"));
} }
pub mod screen {
include!(concat!(env!("OUT_DIR"), "/screen.rs"));
}

View File

@ -5,10 +5,10 @@ edition.workspace = true
[dependencies] [dependencies]
pumpkin-protocol = { path = "../pumpkin-protocol" } pumpkin-protocol = { path = "../pumpkin-protocol" }
pumpkin-data = { path = "../pumpkin-data" }
pumpkin-world = { path = "../pumpkin-world" } pumpkin-world = { path = "../pumpkin-world" }
pumpkin-registry = {path = "../pumpkin-registry"} pumpkin-registry = {path = "../pumpkin-registry"}
pumpkin-macros = { path = "../pumpkin-macros" }
pumpkin-util = { path = "../pumpkin-util" } pumpkin-util = { path = "../pumpkin-util" }
log.workspace = true log.workspace = true

View File

@ -1,6 +1,6 @@
use crate::container_click::MouseClick; use crate::container_click::MouseClick;
use crate::player::PlayerInventory; use crate::player::PlayerInventory;
use pumpkin_macros::screen; use pumpkin_data::screen::WindowType;
use pumpkin_world::item::ItemStack; use pumpkin_world::item::ItemStack;
pub mod container_click; pub mod container_click;
@ -14,45 +14,6 @@ pub mod window_property;
pub use error::InventoryError; pub use error::InventoryError;
pub use open_container::*; pub use open_container::*;
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
#[repr(u8)]
pub enum WindowType {
// not used
Generic9x1 = screen!("generic_9x1"),
// not used
Generic9x2 = screen!("generic_9x2"),
// General-purpose 3-row inventory. Used by Chest, minecart with chest, ender chest, and barrel
Generic9x3 = screen!("generic_9x3"),
// not used
Generic9x4 = screen!("generic_9x4"),
// not used
Generic9x5 = screen!("generic_9x5"),
// Used by large chests
Generic9x6 = screen!("generic_9x6"),
// General-purpose 3-by-3 square inventory, used by Dispenser and Dropper
Generic3x3 = screen!("generic_3x3"),
// General-purpose 3-by-3 square inventory, used by the Crafter
Craft3x3 = screen!("crafter_3x3"),
Anvil = screen!("anvil"),
Beacon = screen!("beacon"),
BlastFurnace = screen!("blast_furnace"),
BrewingStand = screen!("brewing_stand"),
CraftingTable = screen!("crafting"),
EnchantmentTable = screen!("enchantment"),
Furnace = screen!("furnace"),
Grindstone = screen!("grindstone"),
// Hopper or minecart with hopper
Hopper = screen!("hopper"),
Lectern = screen!("lectern"),
Loom = screen!("loom"),
// Villager, Wandering Trader
Merchant = screen!("merchant"),
ShulkerBox = screen!("shulker_box"),
SmithingTable = screen!("smithing"),
Smoker = screen!("smoker"),
CartographyTable = screen!("cartography_table"),
Stonecutter = screen!("stonecutter"),
}
pub struct ContainerStruct<const SLOTS: usize>([Option<ItemStack>; SLOTS]); pub struct ContainerStruct<const SLOTS: usize>([Option<ItemStack>; SLOTS]);
// Container needs Sync + Send to be able to be in async Server // Container needs Sync + Send to be able to be in async Server

View File

@ -1,5 +1,6 @@
use crate::crafting::check_if_matches_crafting; use crate::crafting::check_if_matches_crafting;
use crate::{Container, WindowType}; use crate::Container;
use pumpkin_data::screen::WindowType;
use pumpkin_util::math::position::WorldPosition; use pumpkin_util::math::position::WorldPosition;
use pumpkin_world::block::block_registry::Block; use pumpkin_world::block::block_registry::Block;
use pumpkin_world::item::ItemStack; use pumpkin_world::item::ItemStack;
@ -125,7 +126,7 @@ pub struct CraftingTable {
impl Container for CraftingTable { impl Container for CraftingTable {
fn window_type(&self) -> &'static WindowType { fn window_type(&self) -> &'static WindowType {
&WindowType::CraftingTable &WindowType::Crafting
} }
fn window_name(&self) -> &'static str { fn window_name(&self) -> &'static str {

View File

@ -67,11 +67,6 @@ pub fn pumpkin_block(input: TokenStream, item: TokenStream) -> TokenStream {
gen.into() gen.into()
} }
mod screen;
#[proc_macro]
pub fn screen(item: TokenStream) -> TokenStream {
screen::screen_impl(item)
}
mod sound; mod sound;
#[proc_macro] #[proc_macro]
pub fn sound(item: TokenStream) -> TokenStream { pub fn sound(item: TokenStream) -> TokenStream {

View File

@ -1,21 +0,0 @@
use std::{collections::HashMap, sync::LazyLock};
use proc_macro::TokenStream;
use quote::quote;
static SCREENS: LazyLock<HashMap<String, u8>> = LazyLock::new(|| {
serde_json::from_str::<Vec<String>>(include_str!("../../assets/screens.json"))
.expect("Could not parse screens.json registry.")
.into_iter()
.enumerate()
.map(|(i, s)| (s, i as u8))
.collect()
});
pub(crate) fn screen_impl(item: TokenStream) -> TokenStream {
let input_string = item.to_string();
let screen_name = input_string.trim_matches('"');
let id = *SCREENS.get(screen_name).expect("Invalid Screen");
quote! { #id }.into()
}

View File

@ -16,6 +16,7 @@ pumpkin-util = { path = "../pumpkin-util" }
pumpkin-config = { path = "../pumpkin-config" } pumpkin-config = { path = "../pumpkin-config" }
pumpkin-inventory = { path = "../pumpkin-inventory" } pumpkin-inventory = { path = "../pumpkin-inventory" }
pumpkin-world = { path = "../pumpkin-world" } pumpkin-world = { path = "../pumpkin-world" }
pumpkin-data = { path = "../pumpkin-data" }
pumpkin-entity = { path = "../pumpkin-entity" } pumpkin-entity = { path = "../pumpkin-entity" }
pumpkin-protocol = { path = "../pumpkin-protocol" } pumpkin-protocol = { path = "../pumpkin-protocol" }
pumpkin-registry = { path = "../pumpkin-registry" } pumpkin-registry = { path = "../pumpkin-registry" }

View File

@ -1,5 +1,6 @@
use async_trait::async_trait; use async_trait::async_trait;
use pumpkin_inventory::{Chest, OpenContainer, WindowType}; use pumpkin_data::screen::WindowType;
use pumpkin_inventory::{Chest, OpenContainer};
use pumpkin_macros::{pumpkin_block, sound}; use pumpkin_macros::{pumpkin_block, sound};
use pumpkin_protocol::{client::play::CBlockAction, codec::var_int::VarInt}; use pumpkin_protocol::{client::play::CBlockAction, codec::var_int::VarInt};
use pumpkin_util::math::position::WorldPosition; use pumpkin_util::math::position::WorldPosition;

View File

@ -3,7 +3,8 @@ use crate::block::pumpkin_block::PumpkinBlock;
use crate::entity::player::Player; use crate::entity::player::Player;
use crate::server::Server; use crate::server::Server;
use async_trait::async_trait; use async_trait::async_trait;
use pumpkin_inventory::{CraftingTable, OpenContainer, WindowType}; use pumpkin_data::screen::WindowType;
use pumpkin_inventory::{CraftingTable, OpenContainer};
use pumpkin_macros::pumpkin_block; use pumpkin_macros::pumpkin_block;
use pumpkin_util::math::position::WorldPosition; use pumpkin_util::math::position::WorldPosition;
use pumpkin_world::{block::block_registry::Block, item::item_registry::Item}; use pumpkin_world::{block::block_registry::Block, item::item_registry::Item};
@ -83,7 +84,7 @@ impl CraftingTableBlock {
player, player,
location, location,
server, server,
WindowType::CraftingTable, WindowType::Crafting,
) )
.await; .await;
} }

View File

@ -1,8 +1,8 @@
use crate::block::block_manager::BlockActionResult; use crate::block::block_manager::BlockActionResult;
use crate::entity::player::Player; use crate::entity::player::Player;
use async_trait::async_trait; use async_trait::async_trait;
use pumpkin_data::screen::WindowType;
use pumpkin_inventory::Furnace; use pumpkin_inventory::Furnace;
use pumpkin_inventory::WindowType;
use pumpkin_macros::pumpkin_block; use pumpkin_macros::pumpkin_block;
use pumpkin_util::math::position::WorldPosition; use pumpkin_util::math::position::WorldPosition;
use pumpkin_world::block::block_registry::Block; use pumpkin_world::block::block_registry::Block;

View File

@ -1,4 +1,5 @@
use pumpkin_inventory::{Container, OpenContainer, WindowType}; use pumpkin_data::screen::WindowType;
use pumpkin_inventory::{Container, OpenContainer};
use pumpkin_util::math::position::WorldPosition; use pumpkin_util::math::position::WorldPosition;
use pumpkin_world::block::block_registry::Block; use pumpkin_world::block::block_registry::Block;

View File

@ -1,12 +1,13 @@
use crate::entity::player::Player; use crate::entity::player::Player;
use crate::server::Server; use crate::server::Server;
use pumpkin_data::screen::WindowType;
use pumpkin_inventory::container_click::{ use pumpkin_inventory::container_click::{
Click, ClickType, KeyClick, MouseClick, MouseDragState, MouseDragType, Click, ClickType, KeyClick, MouseClick, MouseDragState, MouseDragType,
}; };
use pumpkin_inventory::drag_handler::DragHandler; use pumpkin_inventory::drag_handler::DragHandler;
use pumpkin_inventory::window_property::{WindowProperty, WindowPropertyTrait}; use pumpkin_inventory::window_property::{WindowProperty, WindowPropertyTrait};
use pumpkin_inventory::Container;
use pumpkin_inventory::{container_click, InventoryError, OptionallyCombinedContainer}; use pumpkin_inventory::{container_click, InventoryError, OptionallyCombinedContainer};
use pumpkin_inventory::{Container, WindowType};
use pumpkin_protocol::client::play::{ use pumpkin_protocol::client::play::{
CCloseContainer, COpenScreen, CSetContainerContent, CSetContainerProperty, CSetContainerSlot, CCloseContainer, COpenScreen, CSetContainerContent, CSetContainerProperty, CSetContainerSlot,
}; };