diff --git a/inventory-framework-api/src/main/java/me/devnatan/inventoryframework/component/ItemComponent.java b/inventory-framework-api/src/main/java/me/devnatan/inventoryframework/component/ItemComponent.java index daa203b04..a5e27d83a 100644 --- a/inventory-framework-api/src/main/java/me/devnatan/inventoryframework/component/ItemComponent.java +++ b/inventory-framework-api/src/main/java/me/devnatan/inventoryframework/component/ItemComponent.java @@ -34,6 +34,7 @@ public class ItemComponent implements Component, InteractionHandler { private boolean isVisible; private volatile String lastKey; + private volatile Object lastRenderedItem; public ItemComponent( Function keyFactory, @@ -67,6 +68,7 @@ public ItemComponent( this.updateOnClick = updateOnClick; this.isVisible = isVisible; this.reference = reference; + this.lastRenderedItem = stack; } @Override @@ -145,12 +147,16 @@ public void render(@NotNull IFSlotRenderContext context) { if (getRenderHandler() != null) { final int initialSlot = getPosition(); + if (lastRenderedItem != null) context.setResult(lastRenderedItem); + try { getRenderHandler().accept(context); } catch (Exception e) { throw new InventoryFrameworkException("Failed to render item component", e); } + lastRenderedItem = context.getResult(); + // Externally managed components have its own displacement measures if (!isManagedExternally()) { final int updatedSlot = context.getSlot(); @@ -197,6 +203,7 @@ public void updated(@NotNull IFSlotRenderContext context) { boolean isWatchingAnyState = getWatchingStates() != null && !getWatching().isEmpty(); if (isVisible() && getUpdateHandler() != null) { + if (lastRenderedItem != null) context.setResult(lastRenderedItem); getUpdateHandler().accept(context); if (context.isCancelled()) return; } diff --git a/inventory-framework-api/src/main/java/me/devnatan/inventoryframework/context/IFSlotRenderContext.java b/inventory-framework-api/src/main/java/me/devnatan/inventoryframework/context/IFSlotRenderContext.java index e560876d0..0afeb7169 100644 --- a/inventory-framework-api/src/main/java/me/devnatan/inventoryframework/context/IFSlotRenderContext.java +++ b/inventory-framework-api/src/main/java/me/devnatan/inventoryframework/context/IFSlotRenderContext.java @@ -7,6 +7,15 @@ public interface IFSlotRenderContext extends IFSlotContext, IFConfinedContext { @ApiStatus.Internal Object getResult(); + /** + * Sets the item that was rendered by the owning component in a previous render. + * + *

This is an internal inventory-framework API that should not be used from outside of + * this library. No compatibility guarantees are provided. + */ + @ApiStatus.Internal + void setResult(Object result); + boolean isCancelled(); void setCancelled(boolean cancelled); diff --git a/inventory-framework-platform-bukkit/src/main/java/me/devnatan/inventoryframework/context/SlotRenderContext.java b/inventory-framework-platform-bukkit/src/main/java/me/devnatan/inventoryframework/context/SlotRenderContext.java index 8ee0b8035..cd9a2e22c 100644 --- a/inventory-framework-platform-bukkit/src/main/java/me/devnatan/inventoryframework/context/SlotRenderContext.java +++ b/inventory-framework-platform-bukkit/src/main/java/me/devnatan/inventoryframework/context/SlotRenderContext.java @@ -54,6 +54,11 @@ public final void setItem(ItemStack item) { setChanged(true); } + @Override + public final void setResult(Object result) { + this.item = (ItemStack) result; + } + @Override public final boolean isCancelled() { return cancelled; diff --git a/inventory-framework-platform-minestom/src/main/kotlin/me/devnatan/inventoryframework/context/SlotRenderContext.kt b/inventory-framework-platform-minestom/src/main/kotlin/me/devnatan/inventoryframework/context/SlotRenderContext.kt index 385dcab43..c85cdeefc 100644 --- a/inventory-framework-platform-minestom/src/main/kotlin/me/devnatan/inventoryframework/context/SlotRenderContext.kt +++ b/inventory-framework-platform-minestom/src/main/kotlin/me/devnatan/inventoryframework/context/SlotRenderContext.kt @@ -27,6 +27,10 @@ class SlotRenderContext override fun getResult(): ItemStack = item + override fun setResult(result: Any?) { + item = result as? ItemStack ?: ItemStack.AIR + } + override fun isCancelled(): Boolean = cancelled override fun setCancelled(cancelled: Boolean) {