From 42c2c56937da686e27ff8d4d965d88cc6fcaa3d7 Mon Sep 17 00:00:00 2001 From: NichtStudioCode <51272202+NichtStudioCode@users.noreply.github.com> Date: Sat, 30 Sep 2023 17:45:21 +0200 Subject: [PATCH] Improve Paged- and ScrollGui - PagedGui pages and ScrollGui content is now saved as List to improve performance - Added PagedGui#bake and ScrollGui#bake to recreate those slot element lists if needed - PagedInventoriesGuiImpl now lets oversized inventories overflow to the next page - Added resize handler to VirtualInventory that is called whenever the inventory is resized - PagedInventoriesGuiImpl and ScrollInventoriesGuiImpl automatically register a resize handler to virtual inventories that they display --- .../xenondevs/invui/gui/AbstractPagedGui.java | 23 ++++++- .../invui/gui/AbstractScrollGui.java | 29 +++++++- .../xyz/xenondevs/invui/gui/PagedGui.java | 8 +++ .../invui/gui/PagedInventoriesGuiImpl.java | 66 +++++++++++++------ .../invui/gui/PagedItemsGuiImpl.java | 39 +++++------ .../invui/gui/PagedNestedGuiImpl.java | 35 ++++------ .../xyz/xenondevs/invui/gui/ScrollGui.java | 8 +++ .../invui/gui/ScrollInventoryGuiImpl.java | 54 +++++++++------ .../invui/gui/ScrollItemsGuiImpl.java | 24 ++----- .../invui/gui/ScrollNestedGuiImpl.java | 29 ++------ .../invui/inventory/VirtualInventory.java | 52 +++++++++++++++ 11 files changed, 237 insertions(+), 130 deletions(-) diff --git a/invui-core/src/main/java/xyz/xenondevs/invui/gui/AbstractPagedGui.java b/invui-core/src/main/java/xyz/xenondevs/invui/gui/AbstractPagedGui.java index e72d3ba..29729ee 100644 --- a/invui-core/src/main/java/xyz/xenondevs/invui/gui/AbstractPagedGui.java +++ b/invui-core/src/main/java/xyz/xenondevs/invui/gui/AbstractPagedGui.java @@ -21,6 +21,8 @@ public abstract class AbstractPagedGui extends AbstractGui implements PagedGu private int currentPage; private List> pageChangeHandlers; + protected List content; + protected List> pages; public AbstractPagedGui(int width, int height, boolean infinitePages, int... contentListSlots) { super(width, height); @@ -93,7 +95,7 @@ public abstract class AbstractPagedGui extends AbstractGui implements PagedGu } private void updatePageContent() { - List slotElements = getPageElements(currentPage); + List slotElements = (pages != null && !pages.isEmpty()) ? pages.get(currentPage) : List.of(); for (int i = 0; i < contentListSlots.length; i++) { if (slotElements.size() > i) setSlotElement(contentListSlots[i], slotElements.get(i)); @@ -101,6 +103,23 @@ public abstract class AbstractPagedGui extends AbstractGui implements PagedGu } } + @Override + public void setContent(@Nullable List content) { + if (content == null || content.isEmpty()) { + this.content = List.of(); + this.pages = List.of(); + update(); + } else { + this.content = content; + bake(); // calls update() + } + } + + @Override + public int getPageAmount() { + return pages != null ? pages.size() : 0; + } + @Override public int getCurrentPage() { return currentPage; @@ -142,8 +161,6 @@ public abstract class AbstractPagedGui extends AbstractGui implements PagedGu return pageChangeHandlers; } - protected abstract List getPageElements(int page); - public static abstract class AbstractBuilder extends AbstractGui.AbstractBuilder, PagedGui.Builder> implements PagedGui.Builder diff --git a/invui-core/src/main/java/xyz/xenondevs/invui/gui/AbstractScrollGui.java b/invui-core/src/main/java/xyz/xenondevs/invui/gui/AbstractScrollGui.java index acb431b..51641ba 100644 --- a/invui-core/src/main/java/xyz/xenondevs/invui/gui/AbstractScrollGui.java +++ b/invui-core/src/main/java/xyz/xenondevs/invui/gui/AbstractScrollGui.java @@ -1,6 +1,7 @@ package xyz.xenondevs.invui.gui; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import xyz.xenondevs.invui.gui.structure.Structure; import xyz.xenondevs.invui.util.SlotUtils; @@ -24,6 +25,8 @@ public abstract class AbstractScrollGui extends AbstractGui implements Scroll private int offset; private List> scrollHandlers; + protected List content; + protected List elements; public AbstractScrollGui(int width, int height, boolean infiniteLines, int... contentListSlots) { super(width, height); @@ -109,6 +112,24 @@ public abstract class AbstractScrollGui extends AbstractGui implements Scroll } } + @Override + public int getMaxLine() { + if (elements == null) return 0; + return (int) Math.ceil((double) elements.size() / (double) getLineLength()) - 1; + } + + @Override + public void setContent(@Nullable List content) { + if (content == null || content.isEmpty()) { + this.content = List.of(); + this.elements = List.of(); + update(); + } else { + this.content = content; + bake(); // calls update() + } + } + protected void update() { correctCurrentLine(); updateControlItems(); @@ -116,7 +137,7 @@ public abstract class AbstractScrollGui extends AbstractGui implements Scroll } private void updateContent() { - List slotElements = getElements(offset, contentListSlots.length + offset); + List slotElements = getElements(offset, contentListSlots.length + offset); for (int i = 0; i < contentListSlots.length; i++) { if (slotElements.size() > i) setSlotElement(contentListSlots[i], slotElements.get(i)); @@ -124,6 +145,10 @@ public abstract class AbstractScrollGui extends AbstractGui implements Scroll } } + protected List getElements(int from, int to) { + return elements.subList(from, Math.min(elements.size(), to)); + } + @Override public void setScrollHandlers(@NotNull List<@NotNull BiConsumer> scrollHandlers) { this.scrollHandlers = scrollHandlers; @@ -143,8 +168,6 @@ public abstract class AbstractScrollGui extends AbstractGui implements Scroll scrollHandlers.remove(scrollHandler); } - protected abstract List getElements(int from, int to); - public abstract static class AbstractBuilder extends AbstractGui.AbstractBuilder, ScrollGui.Builder> implements ScrollGui.Builder diff --git a/invui-core/src/main/java/xyz/xenondevs/invui/gui/PagedGui.java b/invui-core/src/main/java/xyz/xenondevs/invui/gui/PagedGui.java index ac514ae..1be1146 100644 --- a/invui-core/src/main/java/xyz/xenondevs/invui/gui/PagedGui.java +++ b/invui-core/src/main/java/xyz/xenondevs/invui/gui/PagedGui.java @@ -219,6 +219,14 @@ public interface PagedGui extends Gui { */ void setContent(@Nullable List<@NotNull C> content); + /** + * Bakes and updates the pages of this {@link PagedGui} based on the current content. + *

+ * This method does not need to be called when using {@link #setContent(List)}, + * but is required when the size of the content itself changes. + */ + void bake(); + /** * Gets the registered page change handlers. * diff --git a/invui-core/src/main/java/xyz/xenondevs/invui/gui/PagedInventoriesGuiImpl.java b/invui-core/src/main/java/xyz/xenondevs/invui/gui/PagedInventoriesGuiImpl.java index eabbd52..7769b66 100644 --- a/invui-core/src/main/java/xyz/xenondevs/invui/gui/PagedInventoriesGuiImpl.java +++ b/invui-core/src/main/java/xyz/xenondevs/invui/gui/PagedInventoriesGuiImpl.java @@ -4,11 +4,11 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import xyz.xenondevs.invui.gui.structure.Structure; import xyz.xenondevs.invui.inventory.Inventory; +import xyz.xenondevs.invui.inventory.VirtualInventory; import java.util.ArrayList; import java.util.List; -import java.util.stream.Collectors; -import java.util.stream.IntStream; +import java.util.function.BiConsumer; /** * An {@link AbstractPagedGui} where every page is its own {@link Inventory}. @@ -18,7 +18,7 @@ import java.util.stream.IntStream; */ final class PagedInventoriesGuiImpl extends AbstractPagedGui { - private List inventories; + private final @NotNull BiConsumer<@NotNull Integer, @NotNull Integer> resizeHandler = (from, to) -> bake(); /** * Creates a new {@link PagedInventoriesGuiImpl}. @@ -44,29 +44,57 @@ final class PagedInventoriesGuiImpl extends AbstractPagedGui { setContent(inventories); } + @SuppressWarnings("DuplicatedCode") @Override - public int getPageAmount() { - return inventories.size(); + public void setContent(@Nullable List content) { + // remove resize handlers from previous inventories + if (this.content != null) { + for (Inventory inventory : this.content) { + if (inventory instanceof VirtualInventory) { + ((VirtualInventory) inventory).removeResizeHandler(resizeHandler); + } + } + } + + // set content, bake pages, update + super.setContent(content); + + // add resize handlers to new inventories + if (this.content != null) { + for (Inventory inventory : this.content) { + if (inventory instanceof VirtualInventory) { + ((VirtualInventory) inventory).addResizeHandler(resizeHandler); + } + } + } } @Override - public void setContent(@Nullable List<@NotNull Inventory> inventories) { - this.inventories = inventories == null ? new ArrayList<>() : inventories; + public void bake() { + int contentSize = getContentListSlots().length; + + List> pages = new ArrayList<>(); + List page = new ArrayList<>(contentSize); + + for (Inventory inventory : content) { + for (int slot = 0; slot < inventory.getSize(); slot++) { + page.add(new SlotElement.InventorySlotElement(inventory, slot)); + + if (page.size() >= contentSize) { + pages.add(page); + page = new ArrayList<>(contentSize); + } + } + } + + if (!page.isEmpty()) { + pages.add(page); + } + + this.pages = pages; update(); } - @Override - protected List getPageElements(int page) { - if (inventories.size() <= page) return new ArrayList<>(); - - Inventory inventory = inventories.get(page); - int size = inventory.getSize(); - - return IntStream.range(0, size) - .mapToObj(i -> new SlotElement.InventorySlotElement(inventory, i)) - .collect(Collectors.toList()); - } - public static final class Builder extends AbstractBuilder { @Override diff --git a/invui-core/src/main/java/xyz/xenondevs/invui/gui/PagedItemsGuiImpl.java b/invui-core/src/main/java/xyz/xenondevs/invui/gui/PagedItemsGuiImpl.java index 9e3991c..0d6063b 100644 --- a/invui-core/src/main/java/xyz/xenondevs/invui/gui/PagedItemsGuiImpl.java +++ b/invui-core/src/main/java/xyz/xenondevs/invui/gui/PagedItemsGuiImpl.java @@ -7,8 +7,6 @@ import xyz.xenondevs.invui.item.Item; import java.util.ArrayList; import java.util.List; -import java.util.function.BiConsumer; -import java.util.stream.Collectors; /** * An {@link AbstractPagedGui} that is filled with {@link Item Items}. @@ -18,9 +16,6 @@ import java.util.stream.Collectors; */ final class PagedItemsGuiImpl extends AbstractPagedGui { - private List items; - private List> pageChangeHandlers; - /** * Creates a new {@link PagedItemsGuiImpl}. * @@ -46,23 +41,25 @@ final class PagedItemsGuiImpl extends AbstractPagedGui { } @Override - public int getPageAmount() { - return (int) Math.ceil((double) items.size() / (double) getContentListSlots().length); - } - - @Override - public void setContent(@Nullable List<@NotNull Item> items) { - this.items = items != null ? items : new ArrayList<>(); - update(); - } - - @Override - protected List getPageElements(int page) { - int length = getContentListSlots().length; - int from = page * length; - int to = Math.min(from + length, items.size()); + public void bake() { + List items = content; + int contentSize = getContentListSlots().length; + List> pages = new ArrayList<>(); - return items.subList(from, to).stream().map(SlotElement.ItemSlotElement::new).collect(Collectors.toList()); + int pageAmount = items.size() / contentSize; + for (int pageIdx = 0; pageIdx < pageAmount; pageIdx++) { + int from = pageIdx * contentSize; + int to = Math.min(from + contentSize, items.size()); + + ArrayList page = new ArrayList<>(contentSize); + for (int i = from; i < to; i++) { + page.add(new SlotElement.ItemSlotElement(items.get(i))); + } + pages.add(page); + } + + this.pages = pages; + update(); } public static final class Builder extends AbstractBuilder { diff --git a/invui-core/src/main/java/xyz/xenondevs/invui/gui/PagedNestedGuiImpl.java b/invui-core/src/main/java/xyz/xenondevs/invui/gui/PagedNestedGuiImpl.java index fb4f357..22739ed 100644 --- a/invui-core/src/main/java/xyz/xenondevs/invui/gui/PagedNestedGuiImpl.java +++ b/invui-core/src/main/java/xyz/xenondevs/invui/gui/PagedNestedGuiImpl.java @@ -6,8 +6,6 @@ import xyz.xenondevs.invui.gui.structure.Structure; import java.util.ArrayList; import java.util.List; -import java.util.stream.Collectors; -import java.util.stream.IntStream; /** * An {@link AbstractPagedGui} where every page is its own {@link Gui}. @@ -17,8 +15,6 @@ import java.util.stream.IntStream; */ final class PagedNestedGuiImpl extends AbstractPagedGui { - private List guis; - /** * Creates a new {@link PagedNestedGuiImpl}. * @@ -44,28 +40,21 @@ final class PagedNestedGuiImpl extends AbstractPagedGui { } @Override - public int getPageAmount() { - return guis.size(); - } - - @Override - public void setContent(@Nullable List<@NotNull Gui> guis) { - this.guis = guis == null ? new ArrayList<>() : guis; + public void bake() { + List> pages = new ArrayList<>(); + for (Gui gui : content) { + List page = new ArrayList<>(gui.getSize()); + for (int slot = 0; slot < gui.getSize(); slot++) { + page.add(new SlotElement.LinkedSlotElement(gui, slot)); + } + + pages.add(page); + } + + this.pages = pages; update(); } - @Override - protected List getPageElements(int page) { - if (guis.size() <= page) return new ArrayList<>(); - - Gui gui = guis.get(page); - int size = gui.getSize(); - - return IntStream.range(0, size) - .mapToObj(i -> new SlotElement.LinkedSlotElement(gui, i)) - .collect(Collectors.toList()); - } - public static final class Builder extends AbstractBuilder { @Override diff --git a/invui-core/src/main/java/xyz/xenondevs/invui/gui/ScrollGui.java b/invui-core/src/main/java/xyz/xenondevs/invui/gui/ScrollGui.java index 4fff2c8..09da444 100644 --- a/invui-core/src/main/java/xyz/xenondevs/invui/gui/ScrollGui.java +++ b/invui-core/src/main/java/xyz/xenondevs/invui/gui/ScrollGui.java @@ -193,6 +193,14 @@ public interface ScrollGui extends Gui { */ void setContent(@Nullable List<@NotNull C> content); + /** + * Bakes the elements of this {@link PagedGui} based on the current content. + *

+ * This method does not need to be called when using {@link #setContent(List)}, + * but is required when the size of the content itself changes. + */ + void bake(); + /** * Replaces the currently registered scroll handlers with the specified ones. * diff --git a/invui-core/src/main/java/xyz/xenondevs/invui/gui/ScrollInventoryGuiImpl.java b/invui-core/src/main/java/xyz/xenondevs/invui/gui/ScrollInventoryGuiImpl.java index 1d79325..fd2675e 100644 --- a/invui-core/src/main/java/xyz/xenondevs/invui/gui/ScrollInventoryGuiImpl.java +++ b/invui-core/src/main/java/xyz/xenondevs/invui/gui/ScrollInventoryGuiImpl.java @@ -4,9 +4,11 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import xyz.xenondevs.invui.gui.structure.Structure; import xyz.xenondevs.invui.inventory.Inventory; +import xyz.xenondevs.invui.inventory.VirtualInventory; import java.util.ArrayList; import java.util.List; +import java.util.function.BiConsumer; /** * A {@link AbstractScrollGui} that uses {@link Inventory VirtualInventories} as content. @@ -16,8 +18,7 @@ import java.util.List; */ final class ScrollInventoryGuiImpl extends AbstractScrollGui { - private List inventories; - private List elements; + private final @NotNull BiConsumer<@NotNull Integer, @NotNull Integer> resizeHandler = (from, to) -> bake(); /** * Creates a new {@link ScrollInventoryGuiImpl}. @@ -43,31 +44,42 @@ final class ScrollInventoryGuiImpl extends AbstractScrollGui { setContent(inventories); } + @SuppressWarnings("DuplicatedCode") @Override - public void setContent(@Nullable List<@NotNull Inventory> inventories) { - this.inventories = inventories != null ? inventories : new ArrayList<>(); - updateElements(); - update(); - } - - private void updateElements() { - elements = new ArrayList<>(); - for (Inventory inventory : inventories) { - for (int i = 0; i < inventory.getSize(); i++) { - elements.add(new SlotElement.InventorySlotElement(inventory, i)); + public void setContent(@Nullable List content) { + // remove resize handlers from previous inventories + if (this.content != null) { + for (Inventory inventory : this.content) { + if (inventory instanceof VirtualInventory) { + ((VirtualInventory) inventory).removeResizeHandler(resizeHandler); + } + } + } + + // set content, bake pages, update + super.setContent(content); + + // add resize handlers to new inventories + if (this.content != null) { + for (Inventory inventory : this.content) { + if (inventory instanceof VirtualInventory) { + ((VirtualInventory) inventory).addResizeHandler(resizeHandler); + } } } } @Override - protected List getElements(int from, int to) { - return elements.subList(from, Math.min(elements.size(), to)); - } - - @Override - public int getMaxLine() { - if (elements == null) return 0; - return (int) Math.ceil((double) elements.size() / (double) getLineLength()) - 1; + public void bake() { + List elements = new ArrayList<>(); + for (Inventory inventory : content) { + for (int i = 0; i < inventory.getSize(); i++) { + elements.add(new SlotElement.InventorySlotElement(inventory, i)); + } + } + + this.elements = elements; + update(); } public static final class Builder extends AbstractBuilder { diff --git a/invui-core/src/main/java/xyz/xenondevs/invui/gui/ScrollItemsGuiImpl.java b/invui-core/src/main/java/xyz/xenondevs/invui/gui/ScrollItemsGuiImpl.java index 9dfd757..2c990e2 100644 --- a/invui-core/src/main/java/xyz/xenondevs/invui/gui/ScrollItemsGuiImpl.java +++ b/invui-core/src/main/java/xyz/xenondevs/invui/gui/ScrollItemsGuiImpl.java @@ -7,7 +7,6 @@ import xyz.xenondevs.invui.item.Item; import java.util.ArrayList; import java.util.List; -import java.util.stream.Collectors; /** * A {@link AbstractScrollGui} that uses {@link Item Items} as content. @@ -17,8 +16,6 @@ import java.util.stream.Collectors; */ final class ScrollItemsGuiImpl extends AbstractScrollGui { - private List items; - /** * Creates a new {@link ScrollItemsGuiImpl}. * @@ -44,23 +41,16 @@ final class ScrollItemsGuiImpl extends AbstractScrollGui { } @Override - public void setContent(@Nullable List<@NotNull Item> items) { - this.items = items != null ? items : new ArrayList<>(); + public void bake() { + ArrayList elements = new ArrayList<>(content.size()); + for (Item item : content) { + elements.add(new SlotElement.ItemSlotElement(item)); + } + + this.elements = elements; update(); } - @Override - protected List getElements(int from, int to) { - return items.subList(from, Math.min(items.size(), to)).stream() - .map(SlotElement.ItemSlotElement::new) - .collect(Collectors.toList()); - } - - @Override - public int getMaxLine() { - return (int) Math.ceil((double) items.size() / (double) getLineLength()) - 1; - } - public static final class Builder extends AbstractBuilder { @Override diff --git a/invui-core/src/main/java/xyz/xenondevs/invui/gui/ScrollNestedGuiImpl.java b/invui-core/src/main/java/xyz/xenondevs/invui/gui/ScrollNestedGuiImpl.java index 5ed2bb1..2f43f30 100644 --- a/invui-core/src/main/java/xyz/xenondevs/invui/gui/ScrollNestedGuiImpl.java +++ b/invui-core/src/main/java/xyz/xenondevs/invui/gui/ScrollNestedGuiImpl.java @@ -15,9 +15,6 @@ import java.util.List; */ final class ScrollNestedGuiImpl extends AbstractScrollGui { - private List guis; - private List elements; - /** * Creates a new {@link ScrollNestedGuiImpl}. * @@ -43,30 +40,16 @@ final class ScrollNestedGuiImpl extends AbstractScrollGui { } @Override - public void setContent(@Nullable List<@NotNull Gui> guis) { - this.guis = guis != null ? guis : new ArrayList<>(); - updateElements(); - update(); - } - - private void updateElements() { - elements = new ArrayList<>(); - for (Gui gui : guis) { + public void bake() { + ArrayList elements = new ArrayList<>(); + for (Gui gui : content) { for (int i = 0; i < gui.getSize(); i++) { elements.add(new SlotElement.LinkedSlotElement(gui, i)); } } - } - - @Override - protected List getElements(int from, int to) { - return elements.subList(from, Math.min(elements.size(), to)); - } - - @Override - public int getMaxLine() { - if (elements == null) return 0; - return (int) Math.ceil((double) elements.size() / (double) getLineLength()) - 1; + + this.elements = elements; + update(); } public static final class Builder extends AbstractBuilder { diff --git a/invui-core/src/main/java/xyz/xenondevs/invui/inventory/VirtualInventory.java b/invui-core/src/main/java/xyz/xenondevs/invui/inventory/VirtualInventory.java index d75e8d9..5c1aaa7 100644 --- a/invui-core/src/main/java/xyz/xenondevs/invui/inventory/VirtualInventory.java +++ b/invui-core/src/main/java/xyz/xenondevs/invui/inventory/VirtualInventory.java @@ -8,8 +8,11 @@ import xyz.xenondevs.invui.util.DataUtils; import xyz.xenondevs.invui.util.ItemUtils; import java.io.*; +import java.util.ArrayList; import java.util.Arrays; +import java.util.List; import java.util.UUID; +import java.util.function.BiConsumer; /** * A serializable {@link Inventory} implementation that is identified by a {@link UUID} and backed by a simple {@link ItemStack} array. @@ -22,6 +25,7 @@ public class VirtualInventory extends Inventory { private int size; private @Nullable ItemStack @NotNull [] items; private int @NotNull [] maxStackSizes; + private @Nullable List<@NotNull BiConsumer<@NotNull Integer, @NotNull Integer>> resizeHandlers; /** * Constructs a new {@link VirtualInventory} @@ -149,6 +153,7 @@ public class VirtualInventory extends Inventory { setGuiPriority(inventory.getGuiPriority()); setPreUpdateHandler(inventory.getPreUpdateHandler()); setPostUpdateHandler(inventory.getPostUpdateHandler()); + setResizeHandlers(inventory.getResizeHandlers()); } /** @@ -236,6 +241,46 @@ public class VirtualInventory extends Inventory { } } + /** + * Sets the handlers that are called every time this {@link VirtualInventory} is resized. + * + * @param resizeHandlers The handlers to set. + */ + public void setResizeHandlers(@Nullable List<@NotNull BiConsumer<@NotNull Integer, @NotNull Integer>> resizeHandlers) { + this.resizeHandlers = resizeHandlers; + } + + /** + * Gets the handlers that are called every time this {@link VirtualInventory} is resized. + * + * @return The handlers. + */ + public @Nullable List<@NotNull BiConsumer<@NotNull Integer, @NotNull Integer>> getResizeHandlers() { + return resizeHandlers; + } + + /** + * Adds a handler that is called every time this {@link VirtualInventory} is resized. + * + * @param resizeHandler The handler to add. + */ + public void addResizeHandler(@NotNull BiConsumer<@NotNull Integer, @NotNull Integer> resizeHandler) { + if (resizeHandlers == null) + resizeHandlers = new ArrayList<>(); + + resizeHandlers.add(resizeHandler); + } + + /** + * Removes a handler that is called every time this {@link VirtualInventory} is resized. + * + * @param resizeHandler The handler to remove. + */ + public void removeResizeHandler(@NotNull BiConsumer<@NotNull Integer, @NotNull Integer> resizeHandler) { + if (resizeHandlers != null) + resizeHandlers.remove(resizeHandler); + } + /** * Changes the size of the {@link VirtualInventory}. *

@@ -259,6 +304,13 @@ public class VirtualInventory extends Inventory { int stackSize = previousSize != 0 ? maxStackSizes[previousSize - 1] : 64; Arrays.fill(maxStackSizes, previousSize, maxStackSizes.length, stackSize); } + + // call resize handlers if present + if (resizeHandlers != null) { + for (BiConsumer resizeHandler : resizeHandlers) { + resizeHandler.accept(previousSize, size); + } + } } /**