Skip to main content

MenuBuilder

Struct MenuBuilder 

Source
pub struct MenuBuilder {
    instance: MenuInstanceId,
    menu_type: Option<MenuTypeRef>,
    container_id: u8,
    overrides_player_slots: bool,
    slots: Vec<Box<dyn Slot>>,
    container_refs: Vec<ContainerRef>,
    data_slots: Vec<i16>,
    routes: Vec<Route>,
    drain_sections: Vec<Range<usize>>,
    claimed: Vec<(ContainerId, Range<usize>)>,
}
Expand description

Builds a Menu.

See the module documentation for an overview.

Fields§

§instance: MenuInstanceId§menu_type: Option<MenuTypeRef>§container_id: u8§overrides_player_slots: bool§slots: Vec<Box<dyn Slot>>§container_refs: Vec<ContainerRef>§data_slots: Vec<i16>§routes: Vec<Route>§drain_sections: Vec<Range<usize>>§claimed: Vec<(ContainerId, Range<usize>)>

Container-local slot ranges already covered by a section, used to catch two sections mapping onto the same container slots.

Implementations§

Source§

impl MenuBuilder

Source

pub fn new(menu_type: impl Into<Option<MenuTypeRef>>, container_id: u8) -> Self

Creates a new builder for a menu of the given type and container id.

Pass None for the player’s own inventory menu, or a menu type (&vanilla_menu_types::ANVIL, …).

Source

pub fn split(&mut self, container: impl Into<ContainerRef>) -> ContainerSlots

Starts splitting a Container into multiple sections.

Use this when you are locked to storing items in one Container and need to split them into different Sections.

§Example
use steel_core::inventory::prelude::*;
use steel_core::inventory::menu::kinds::BasicKind;

let mut b = MenuBuilder::new(None, 0);

let mut stand = b.split(SimpleContainer::new(5).into_shared());
let bottles = b.section(&mut stand, 3); // slots 0..3
let ingredient = b.section(&mut stand, 1); // slot 3
let fuel = b.section(&mut stand, 1); // slot 4

b.build(BasicKind);
§Panics

Panics if the sections carved from the returned handle take more slots than the container has.

Source

fn container_size(container: &ContainerRef) -> usize

The container’s size, read under a short lock.

Source

pub fn section(&mut self, source: impl SectionSource, count: usize) -> Section

Adds count plain slots backed by source.

Pass a container directly to cover its slots 0..count, or a ContainerSlots handle from MenuBuilder::split to cover the next count slots of a container shared between several sections.

Returns a Section handle over the slots that were added.

§Panics

Panics if the covered container slots overlap another section of this menu.

Source

pub fn section_with( &mut self, source: impl SectionSource, count: usize, kind: impl Into<SectionKind>, ) -> Section

Adds count slots backed by source, lowered through kind.

§Example
use steel_registry::vanilla_items;
use steel_core::inventory::prelude::*;
use steel_core::inventory::menu::kinds::BasicKind;

let mut b = MenuBuilder::new(None, 0);

let container = SimpleContainer::new(9).into_shared();
let fuel = b.section_with(container, 9, SectionKind::restricted(|_slot, stack| {
    stack.is(&vanilla_items::COAL)
}));

b.build(BasicKind);
§Panics

Panics if the covered container slots overlap another section of this menu.

Source

pub fn section_all(&mut self, container: impl Into<ContainerRef>) -> Section

Adds a section covering every slot of container.

Like section with the container’s full size as the count, so the section can never drift from the container when it is resized.

§Panics

Panics if the covered container slots overlap another section of this menu.

Source

pub fn section_all_with( &mut self, container: impl Into<ContainerRef>, kind: impl Into<SectionKind>, ) -> Section

Like section_all, but lowered through kind.

§Panics

Panics if the covered container slots overlap another section of this menu.

Source

pub fn section_at( &mut self, container: impl Into<ContainerRef>, indices: impl IntoIterator<Item = usize>, kind: impl Into<SectionKind>, ) -> Section

Adds slots over explicit container indices, in the given order.

The indices may be non-contiguous and in any order; each menu slot maps to the next index of the iterator. Like section_with, the covered indices are claimed against overlapping sections.

§Panics

Panics if an index repeats or the covered container slots overlap another section of this menu.

Source

pub fn player_inventory( &mut self, inventory: &Shared<PlayerInventory>, ) -> PlayerInventorySections

Adds the player’s 36 inventory slots (main inventory then hotbar).

Source

pub fn player_inventory_with( &mut self, inventory: &Shared<PlayerInventory>, kind: impl Into<SectionKind>, ) -> PlayerInventorySections

Like player_inventory, but lowers the slots through kind, e.g. SectionKind::Display for a read-only view of another player’s inventory.

Player inventory sections never claim their container slots: menus like invsee legitimately map the same inventory into two sections, and quick-move skips aliased slots at runtime.

Source

pub fn result_slot(&mut self, handler: impl ResultHandler + 'static) -> Section

Adds a single fake result slot driven by handler, backed by the handler’s result_container.

See crate::inventory::container::ResultContainer and crate::inventory::slots::ResultHandler.

§Panics

Panics if the result container has no slot 0, or that slot is already covered by another section of this menu.

Source

pub fn data_slot(&mut self, initial: i16) -> DataSlot

Adds a data slot with an initial value and returns a typed handle to it.

Source

pub fn route( &mut self, from: impl IntoSections, targets: impl IntoSections, direction: FillDirection, ) -> &mut Self

Declares a shift-click route from each section of from into targets.

Both arguments accept anything IntoSections: pass a single Section directly and use an array/slice/Vec only when there is genuinely more than one, so brackets signal arity. A multi-section from declares one route per source section.

Most commonly: player_inventory -> container is FillDirection::Forward container -> player_inventory is FillDirection::Backward

§Panics

Panics if a section belongs to another builder, a source overlaps an existing route, or a target overlaps its source.

Source

pub fn route_with_remainder_policy( &mut self, from: impl IntoSections, targets: impl IntoSections, direction: FillDirection, fake_result_remainder: FakeResultRemainderPolicy, ) -> &mut Self

Declares a shift-click route with an explicit fake-result remainder policy. The policy has no effect on ordinary source slots.

§Panics

Panics if a section belongs to another builder, a source overlaps an existing route, or a target overlaps its source.

Source

pub fn drain(&mut self, sections: impl IntoSections) -> &mut Self

Marks sections to be emptied back into the player or dropped on the floor on close.

Accepts anything IntoSections: pass a single Section directly and use an array only for genuinely multiple sections.

§Panics

Panics if any section was created by a different MenuBuilder.

§Example
use std::sync::Arc;

use steel_registry::{item_stack::ItemStack, vanilla_items};
use steel_utils::locks::SyncMutex;

use steel_core::inventory::prelude::*;
use steel_core::inventory::menu::kinds::BasicKind;
use steel_core::inventory::container::SimpleContainer;

let container_id = 0;

let mut b = MenuBuilder::new(None, container_id);

let items = vec![ItemStack::empty(); 9];
let upper_container = SimpleContainer::from_items(items).into_shared();

let items = vec![ItemStack::new(&vanilla_items::BARRIER); 9];
let lower_container = SimpleContainer::from_items(items).into_shared();

let display = b.section_with(lower_container, 9, SectionKind::Display);

let section = b.section(upper_container, 9);
b.drain(section); // only 'section' gets drained when the menu is closed
b.build(BasicKind);
Source

pub const fn override_player_slots(&mut self) -> &mut Self

Declares that this menu paints over the client’s standard 36 player slots.

Pending logical inventory updates are deferred while the menu is open and the slots are restored when it closes.

Source

pub fn build(self, kind: impl MenuKind + 'static) -> Menu

Consumes the builder, creating the finished Menu.

§Panics

Panics if the number of slots does not match the client layout declared by the menu type, or if a fake slot aliases another physical slot.

Source

pub fn build_boxed(self, kind: Box<dyn MenuKind>) -> Menu

Consumes the builder using menu behavior selected at runtime.

This is the erased counterpart to Self::build for plugin factories and other callers that already own a boxed menu kind.

§Panics

Panics if the number of slots does not match the client layout declared by the menu type, or if a fake slot aliases another physical slot.

Source

fn assert_no_fake_slot_aliases(slots: &[Box<dyn Slot>])

Fake slots have special removal and persistence semantics, so no other menu slot may expose their physical backing storage.

Source

pub(crate) const fn instance(&self) -> MenuInstanceId

The identity of the menu being built.

Source

pub const fn slot_count(&self) -> usize

The number of menu slots added so far.

Source

pub(crate) fn push_boxed_slot(&mut self, slot: Box<dyn Slot>)

Appends a single already-erased slot without creating a section.

Source

pub(crate) fn push_section_slot( &mut self, slot: Box<dyn Slot>, source: &ContainerRef, source_index: usize, )

Appends a slot whose physical backing must match its declarative source.

Source

pub(crate) fn claim(&mut self, container: &ContainerRef, range: Range<usize>)

Records that a section covers the container-local range of container.

§Panics

Panics if the range exceeds the container or was already covered by another range.

Source

pub(crate) fn register_container(&mut self, container: impl Into<ContainerRef>)

Records a container to lock.

Source

fn owned(&self, section: Section) -> Range<usize>

Verifies that section was created by this builder.

Source

fn section_from(&self, start: usize) -> Section

Returns a section spanning start..self.slots.len().

Source§

impl MenuBuilder

Source

pub fn grid<R>( &mut self, rows: usize, f: impl FnOnce(&mut GridPlacer<'_>) -> R, ) -> R

Runs f against a fresh 9-wide, rows-tall grid and appends its slots in row-major order.

Grids compose. Each call covers the next rows rows of the menu. See the module documentation for placement rules and an example.

§Panics

If rows is zero, if the slots so far do not fill complete rows, or if f leaves cells neither placed nor painted.

Source

fn flush_grid(&mut self, state: GridState)

Emits the resolved grid cells as menu slots in row-major order.

Trait Implementations§

Source§

impl Debug for MenuBuilder

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T> IntoShared for T

Source§

fn into_shared(self) -> Arc<Mutex<RawMutex, Self>>

Wraps this value in an Arc<SyncMutex<>>
§

impl<T> Pointable for T

§

const ALIGN: usize

The alignment of pointer.
§

type Init = T

The type for initializers.
§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
§

impl<T> PolicyExt for T
where T: ?Sized,

§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns [Action::Follow] only if self and other return Action::Follow. Read more
§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns [Action::Follow] if either self or other returns Action::Follow. Read more
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a [WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a [WithDispatch] wrapper. Read more