Skip to content

Commit

Permalink
✨Menu dynamic content registry.
Browse files Browse the repository at this point in the history
  • Loading branch information
MarcusSlover committed Apr 23, 2024
1 parent b14b926 commit aaeb8a7
Showing 1 changed file with 69 additions and 20 deletions.
89 changes: 69 additions & 20 deletions src/main/java/com/marcusslover/plus/lib/item/Canvas.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import java.util.Objects;
import java.util.UUID;
import java.util.function.Consumer;
import java.util.function.Supplier;

/**
* A canvas is a representation of a menu.
Expand Down Expand Up @@ -63,6 +64,10 @@ public class Canvas implements InventoryHolder { // Inventory holder to keep tra
@Setter(AccessLevel.PRIVATE)
private LinkedList<@NotNull PopulatorContext<?>> populatorContext = new LinkedList<>();

@Getter(AccessLevel.PACKAGE)
@Setter(AccessLevel.PRIVATE)
private List<DynamicSupplier<?>> dynamicSuppliers = new ArrayList<>();

/**
* Set the title of the canvas.
*
Expand Down Expand Up @@ -109,7 +114,8 @@ public class Canvas implements InventoryHolder { // Inventory holder to keep tra
*
* @return the inventory
*/
@NotNull Inventory craftInventory() {
@NotNull
Inventory craftInventory() {
if (this.title == null) {
return Bukkit.createInventory(this, this.rows * 9);
}
Expand Down Expand Up @@ -239,6 +245,7 @@ public class Canvas implements InventoryHolder { // Inventory holder to keep tra

/**
* Gets list of all populator contexts.
*
* @return the list of all populator contexts
*/
public @NotNull List<@NotNull PopulatorContext<?>> populatorContexts() {
Expand Down Expand Up @@ -266,6 +273,35 @@ public void clear() {
this.selfInventory = null;
this.closeInventory = null;
this.populatorContext.clear(); // clear the populator context
this.dynamicSuppliers.clear(); // clear the dynamic suppliers
}

/**
* Registers a dynamic content supplier.
* @param type Type of the content
* @param supplier Supplier of the content
* @return The canvas
* @param <T> the type of the content
*/
public <T> @NotNull Canvas registerDynamicContent(@NotNull Class<T> type, @NotNull Supplier<T> supplier) {
this.dynamicSuppliers.add(new DynamicSupplier<>(type, supplier));
return this;
}

/**
* Gets the dynamic content supplier.
* @param type Type of the content
* @return The supplier
* @param <T> the type of the content
*/
public <T> @NotNull Supplier<@Nullable T> dynamicContent(@NotNull Class<T> type) {
for (DynamicSupplier<?> dynamicSupplier : this.dynamicSuppliers) {
if (dynamicSupplier.type().equals(type)) {
//noinspection unchecked
return (Supplier<T>) dynamicSupplier.supplier();
}
}
return () -> null;
}

/**
Expand Down Expand Up @@ -306,6 +342,38 @@ public interface CloseInventory {
void onClose(@NotNull Player target, @NotNull InventoryCloseEvent event, @NotNull Canvas it);
}

/**
* Represents a decorator that puts "free" items in the inventory.
* Free items can be interpreted as items that are not associated with any button.
* This is useful, for example, to put a border around the inventory -
* We do not want to create objects for each item in the border.
* Instead, we can use this light-weight decorator.
*/
@FunctionalInterface
public interface ItemDecorator {

/**
* Decorates the inventory.
*
* @param canvas The canvas associated with the inventory.
* @param inventory The inventory to decorate.
*/
void handle(@NotNull Canvas canvas, @NotNull Inventory inventory);
}

/**
* Represents a dynamic supplier.
*
* @param <T> the type of the supplier
* This is used to provide dynamic content to the canvas.
*/
@Data
@Accessors(fluent = true, chain = true)
public static class DynamicSupplier<T> {
private final @NotNull Class<T> type;
private final @NotNull Supplier<T> supplier;
}

/**
* Represents the context of the population.
* It holds the elements and the canvas.
Expand Down Expand Up @@ -649,25 +717,6 @@ public static class ClickContext {
}
}

/**
* Represents a decorator that puts "free" items in the inventory.
* Free items can be interpreted as items that are not associated with any button.
* This is useful, for example, to put a border around the inventory -
* We do not want to create objects for each item in the border.
* Instead, we can use this light-weight decorator.
*/
@FunctionalInterface
public interface ItemDecorator {

/**
* Decorates the inventory.
*
* @param canvas The canvas associated with the inventory.
* @param inventory The inventory to decorate.
*/
void handle(@NotNull Canvas canvas, @NotNull Inventory inventory);
}

/**
* A full decorator that fills all empty slots with a given item.
*
Expand Down

0 comments on commit aaeb8a7

Please sign in to comment.