#1059: Add MenuType ViewBuilder

This commit is contained in:
Miles Holder 2024-12-18 07:49:04 +11:00 committed by md_5
parent d7f9c1a86a
commit 3d4295ccbf
No known key found for this signature in database
GPG key ID: E8E901AC7C617C11
5 changed files with 188 additions and 28 deletions

View file

@ -14,6 +14,9 @@ import org.bukkit.inventory.view.LecternView;
import org.bukkit.inventory.view.LoomView; import org.bukkit.inventory.view.LoomView;
import org.bukkit.inventory.view.MerchantView; import org.bukkit.inventory.view.MerchantView;
import org.bukkit.inventory.view.StonecutterView; import org.bukkit.inventory.view.StonecutterView;
import org.bukkit.inventory.view.builder.InventoryViewBuilder;
import org.bukkit.inventory.view.builder.LocationInventoryViewBuilder;
import org.bukkit.inventory.view.builder.MerchantInventoryViewBuilder;
import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
@ -27,104 +30,104 @@ public interface MenuType extends Keyed {
/** /**
* A MenuType which represents a chest with 1 row. * A MenuType which represents a chest with 1 row.
*/ */
MenuType.Typed<InventoryView> GENERIC_9X1 = get("generic_9x1"); MenuType.Typed<InventoryView, InventoryViewBuilder<InventoryView>> GENERIC_9X1 = get("generic_9x1");
/** /**
* A MenuType which represents a chest with 2 rows. * A MenuType which represents a chest with 2 rows.
*/ */
MenuType.Typed<InventoryView> GENERIC_9X2 = get("generic_9x2"); MenuType.Typed<InventoryView, InventoryViewBuilder<InventoryView>> GENERIC_9X2 = get("generic_9x2");
/** /**
* A MenuType which represents a chest with 3 rows. * A MenuType which represents a chest with 3 rows.
*/ */
MenuType.Typed<InventoryView> GENERIC_9X3 = get("generic_9x3"); MenuType.Typed<InventoryView, LocationInventoryViewBuilder<InventoryView>> GENERIC_9X3 = get("generic_9x3");
/** /**
* A MenuType which represents a chest with 4 rows. * A MenuType which represents a chest with 4 rows.
*/ */
MenuType.Typed<InventoryView> GENERIC_9X4 = get("generic_9x4"); MenuType.Typed<InventoryView, InventoryViewBuilder<InventoryView>> GENERIC_9X4 = get("generic_9x4");
/** /**
* A MenuType which represents a chest with 5 rows. * A MenuType which represents a chest with 5 rows.
*/ */
MenuType.Typed<InventoryView> GENERIC_9X5 = get("generic_9x5"); MenuType.Typed<InventoryView, InventoryViewBuilder<InventoryView>> GENERIC_9X5 = get("generic_9x5");
/** /**
* A MenuType which represents a chest with 6 rows. * A MenuType which represents a chest with 6 rows.
*/ */
MenuType.Typed<InventoryView> GENERIC_9X6 = get("generic_9x6"); MenuType.Typed<InventoryView, InventoryViewBuilder<InventoryView>> GENERIC_9X6 = get("generic_9x6");
/** /**
* A MenuType which represents a dispenser/dropper like menu with 3 columns * A MenuType which represents a dispenser/dropper like menu with 3 columns
* and 3 rows. * and 3 rows.
*/ */
MenuType.Typed<InventoryView> GENERIC_3X3 = get("generic_3x3"); MenuType.Typed<InventoryView, LocationInventoryViewBuilder<InventoryView>> GENERIC_3X3 = get("generic_3x3");
/** /**
* A MenuType which represents a crafter * A MenuType which represents a crafter
*/ */
MenuType.Typed<CrafterView> CRAFTER_3X3 = get("crafter_3x3"); MenuType.Typed<CrafterView, LocationInventoryViewBuilder<CrafterView>> CRAFTER_3X3 = get("crafter_3x3");
/** /**
* A MenuType which represents an anvil. * A MenuType which represents an anvil.
*/ */
MenuType.Typed<AnvilView> ANVIL = get("anvil"); MenuType.Typed<AnvilView, LocationInventoryViewBuilder<AnvilView>> ANVIL = get("anvil");
/** /**
* A MenuType which represents a beacon. * A MenuType which represents a beacon.
*/ */
MenuType.Typed<BeaconView> BEACON = get("beacon"); MenuType.Typed<BeaconView, LocationInventoryViewBuilder<BeaconView>> BEACON = get("beacon");
/** /**
* A MenuType which represents a blast furnace. * A MenuType which represents a blast furnace.
*/ */
MenuType.Typed<FurnaceView> BLAST_FURNACE = get("blast_furnace"); MenuType.Typed<FurnaceView, LocationInventoryViewBuilder<FurnaceView>> BLAST_FURNACE = get("blast_furnace");
/** /**
* A MenuType which represents a brewing stand. * A MenuType which represents a brewing stand.
*/ */
MenuType.Typed<BrewingStandView> BREWING_STAND = get("brewing_stand"); MenuType.Typed<BrewingStandView, LocationInventoryViewBuilder<BrewingStandView>> BREWING_STAND = get("brewing_stand");
/** /**
* A MenuType which represents a crafting table. * A MenuType which represents a crafting table.
*/ */
MenuType.Typed<InventoryView> CRAFTING = get("crafting"); MenuType.Typed<InventoryView, LocationInventoryViewBuilder<InventoryView>> CRAFTING = get("crafting");
/** /**
* A MenuType which represents an enchantment table. * A MenuType which represents an enchantment table.
*/ */
MenuType.Typed<EnchantmentView> ENCHANTMENT = get("enchantment"); MenuType.Typed<EnchantmentView, LocationInventoryViewBuilder<EnchantmentView>> ENCHANTMENT = get("enchantment");
/** /**
* A MenuType which represents a furnace. * A MenuType which represents a furnace.
*/ */
MenuType.Typed<FurnaceView> FURNACE = get("furnace"); MenuType.Typed<FurnaceView, LocationInventoryViewBuilder<FurnaceView>> FURNACE = get("furnace");
/** /**
* A MenuType which represents a grindstone. * A MenuType which represents a grindstone.
*/ */
MenuType.Typed<InventoryView> GRINDSTONE = get("grindstone"); MenuType.Typed<InventoryView, LocationInventoryViewBuilder<InventoryView>> GRINDSTONE = get("grindstone");
/** /**
* A MenuType which represents a hopper. * A MenuType which represents a hopper.
*/ */
MenuType.Typed<InventoryView> HOPPER = get("hopper"); MenuType.Typed<InventoryView, LocationInventoryViewBuilder<InventoryView>> HOPPER = get("hopper");
/** /**
* A MenuType which represents a lectern, a book like view. * A MenuType which represents a lectern, a book like view.
*/ */
MenuType.Typed<LecternView> LECTERN = get("lectern"); MenuType.Typed<LecternView, LocationInventoryViewBuilder<LecternView>> LECTERN = get("lectern");
/** /**
* A MenuType which represents a loom. * A MenuType which represents a loom.
*/ */
MenuType.Typed<LoomView> LOOM = get("loom"); MenuType.Typed<LoomView, LocationInventoryViewBuilder<LoomView>> LOOM = get("loom");
/** /**
* A MenuType which represents a merchant. * A MenuType which represents a merchant.
*/ */
MenuType.Typed<MerchantView> MERCHANT = get("merchant"); MenuType.Typed<MerchantView, MerchantInventoryViewBuilder<MerchantView>> MERCHANT = get("merchant");
/** /**
* A MenuType which represents a shulker box. * A MenuType which represents a shulker box.
*/ */
MenuType.Typed<InventoryView> SHULKER_BOX = get("shulker_box"); MenuType.Typed<InventoryView, LocationInventoryViewBuilder<InventoryView>> SHULKER_BOX = get("shulker_box");
/** /**
* A MenuType which represents a stonecutter. * A MenuType which represents a stonecutter.
*/ */
MenuType.Typed<InventoryView> SMITHING = get("smithing"); MenuType.Typed<InventoryView, LocationInventoryViewBuilder<InventoryView>> SMITHING = get("smithing");
/** /**
* A MenuType which represents a smoker. * A MenuType which represents a smoker.
*/ */
MenuType.Typed<FurnaceView> SMOKER = get("smoker"); MenuType.Typed<FurnaceView, LocationInventoryViewBuilder<FurnaceView>> SMOKER = get("smoker");
/** /**
* A MenuType which represents a cartography table. * A MenuType which represents a cartography table.
*/ */
MenuType.Typed<InventoryView> CARTOGRAPHY_TABLE = get("cartography_table"); MenuType.Typed<InventoryView, LocationInventoryViewBuilder<InventoryView>> CARTOGRAPHY_TABLE = get("cartography_table");
/** /**
* A MenuType which represents a stonecutter. * A MenuType which represents a stonecutter.
*/ */
MenuType.Typed<StonecutterView> STONECUTTER = get("stonecutter"); MenuType.Typed<StonecutterView, LocationInventoryViewBuilder<StonecutterView>> STONECUTTER = get("stonecutter");
/** /**
* Typed represents a subtype of {@link MenuType}s that have a known * Typed represents a subtype of {@link MenuType}s that have a known
@ -132,8 +135,10 @@ public interface MenuType extends Keyed {
* *
* @param <V> the generic type of {@link InventoryView} that represents the * @param <V> the generic type of {@link InventoryView} that represents the
* view type. * view type.
* @param <B> the builder type of {@link InventoryViewBuilder} that
* represents the view builder.
*/ */
interface Typed<V extends InventoryView> extends MenuType { interface Typed<V extends InventoryView, B extends InventoryViewBuilder<V>> extends MenuType {
/** /**
* Creates a view of the specified menu type. * Creates a view of the specified menu type.
@ -148,6 +153,14 @@ public interface MenuType extends Keyed {
*/ */
@NotNull @NotNull
V create(@NotNull HumanEntity player, @NotNull String title); V create(@NotNull HumanEntity player, @NotNull String title);
/**
* Creates a builder for this type of InventoryView.
*
* @return the new builder
*/
@NotNull
B builder();
} }
/** /**
@ -157,7 +170,7 @@ public interface MenuType extends Keyed {
* @return the typed MenuType. * @return the typed MenuType.
*/ */
@NotNull @NotNull
MenuType.Typed<InventoryView> typed(); MenuType.Typed<InventoryView, InventoryViewBuilder<InventoryView>> typed();
/** /**
* Yields this MenuType as a typed version of itself with a specific * Yields this MenuType as a typed version of itself with a specific
@ -167,12 +180,14 @@ public interface MenuType extends Keyed {
* {@link InventoryView} with. * {@link InventoryView} with.
* @param <V> the generic type of the InventoryView to get this MenuType * @param <V> the generic type of the InventoryView to get this MenuType
* with * with
* @param <B> the generic type of the InventoryViewBuilder to get this
* MenuType with
* @return the typed MenuType * @return the typed MenuType
* @throws IllegalArgumentException if the provided viewClass cannot be * @throws IllegalArgumentException if the provided viewClass cannot be
* typed to this MenuType * typed to this MenuType
*/ */
@NotNull @NotNull
<V extends InventoryView> MenuType.Typed<V> typed(@NotNull final Class<V> viewClass) throws IllegalArgumentException; <V extends InventoryView, B extends InventoryViewBuilder<V>> MenuType.Typed<V, B> typed(@NotNull final Class<V> viewClass) throws IllegalArgumentException;
/** /**
* Gets the {@link InventoryView} class of this MenuType. * Gets the {@link InventoryView} class of this MenuType.

View file

@ -0,0 +1,41 @@
package org.bukkit.inventory.view.builder;
import org.bukkit.entity.HumanEntity;
import org.bukkit.inventory.InventoryView;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
/**
* Generic Builder for InventoryView's with no special attributes or parameters
*
* @param <V> the type of InventoryView created from this builder
*/
@ApiStatus.Experimental
public interface InventoryViewBuilder<V extends InventoryView> {
/**
* Makes a copy of this builder
*
* @return a copy of this builder
*/
@NotNull
InventoryViewBuilder<V> copy();
/**
* Sets the title of the builder
*
* @param title the title
* @return this builder
*/
@NotNull
InventoryViewBuilder<V> title(@NotNull final String title);
/**
* Builds this builder into a InventoryView
*
* @param player the player to assign to the view
* @return the created InventoryView
*/
@NotNull
V build(@NotNull final HumanEntity player);
}

View file

@ -0,0 +1,54 @@
package org.bukkit.inventory.view.builder;
import org.bukkit.Location;
import org.bukkit.inventory.InventoryView;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
/**
* An InventoryViewBuilder that can be bound by location within the world
*
* @param <V> the type of InventoryView created from this builder
*/
@ApiStatus.Experimental
public interface LocationInventoryViewBuilder<V extends InventoryView> extends InventoryViewBuilder<V> {
@NotNull
@Override
LocationInventoryViewBuilder<V> copy();
/**
* Determines whether or not the server should check if the player can reach
* the location.
* <p>
* Not providing a location but setting checkReachable to true will
* automatically close the view when opened.
* <p>
* If checkReachable is set to false and a location is set on the builder if
* the target block exists and this builder is the correct menu for that
* block, e.g. MenuType.GENERIC_9X3 builder and target block set to chest,
* if that block is destroyed the view would persist.
*
* @param checkReachable whether or not to check if the view is "reachable"
* @return this builder
*/
@NotNull
LocationInventoryViewBuilder<V> checkReachable(final boolean checkReachable);
/**
* Binds a location to this builder.
* <p>
* By binding a location in an unloaded chunk to this builder it is likely
* that the given chunk the location is will load. That means that when,
* building this view it may come with the costs associated with chunk
* loading.
* <p>
* Providing a location of a tile entity with a non matching menu comes with
* extra costs associated with ensuring that the correct view is created.
*
* @param location the location to bind to this view
* @return this builder
*/
@NotNull
LocationInventoryViewBuilder<V> location(@NotNull final Location location);
}

View file

@ -0,0 +1,43 @@
package org.bukkit.inventory.view.builder;
import org.bukkit.Server;
import org.bukkit.inventory.InventoryView;
import org.bukkit.inventory.Merchant;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
/**
* An InventoryViewBuilder for creating merchant views
*
* @param <V> the type of InventoryView created by this builder
*/
@ApiStatus.Experimental
public interface MerchantInventoryViewBuilder<V extends InventoryView> extends InventoryViewBuilder<V> {
@NotNull
@Override
MerchantInventoryViewBuilder<V> copy();
/**
* Adds a merchant to this builder
*
* @param merchant the merchant
* @return this builder
*/
@NotNull
MerchantInventoryViewBuilder<V> merchant(@NotNull final Merchant merchant);
/**
* Determines whether or not the server should check if the player can reach
* the location.
* <p>
* Given checkReachable is provided and a virtual merchant is provided to
* the builder from {@link Server#createMerchant(String)} this method will
* have no effect on the actual menu status.
*
* @param checkReachable whether or not to check if the view is "reachable"
* @return this builder
*/
@NotNull
MerchantInventoryViewBuilder<V> checkReachable(final boolean checkReachable);
}

View file

@ -0,0 +1,7 @@
/**
* A Package that contains builders for building InventoryViews.
*/
@ApiStatus.Experimental
package org.bukkit.inventory.view.builder;
import org.jetbrains.annotations.ApiStatus;