diff --git a/src/main/java/de/studiocode/invui/item/ItemBuilder.java b/src/main/java/de/studiocode/invui/item/ItemBuilder.java index 052d655..817e3fb 100644 --- a/src/main/java/de/studiocode/invui/item/ItemBuilder.java +++ b/src/main/java/de/studiocode/invui/item/ItemBuilder.java @@ -68,16 +68,19 @@ public class ItemBuilder implements Cloneable { ItemStack itemStack = new ItemStack(material, amount); ItemMeta itemMeta = itemStack.getItemMeta(); - if (itemMeta instanceof Damageable) ((Damageable) itemMeta).setDamage(damage); - if (customModelData != -1) itemMeta.setCustomModelData(customModelData); - if (displayName != null) itemMeta.setDisplayName(displayName); - if (gameProfile != null) - ReflectionUtils.setFieldValue(ReflectionRegistry.CB_CRAFT_META_SKULL_PROFILE_FIELD, itemMeta, gameProfile); - enchantments.forEach((enchantment, pair) -> itemMeta.addEnchant(enchantment, pair.getFirst(), pair.getSecond())); - itemMeta.addItemFlags(itemFlags.toArray(new ItemFlag[0])); - itemMeta.setLore(lore); + if (itemMeta != null) { + if (itemMeta instanceof Damageable) ((Damageable) itemMeta).setDamage(damage); + if (customModelData != -1) itemMeta.setCustomModelData(customModelData); + if (displayName != null) itemMeta.setDisplayName(displayName); + if (gameProfile != null) + ReflectionUtils.setFieldValue(ReflectionRegistry.CB_CRAFT_META_SKULL_PROFILE_FIELD, itemMeta, gameProfile); + enchantments.forEach((enchantment, pair) -> itemMeta.addEnchant(enchantment, pair.getFirst(), pair.getSecond())); + itemMeta.addItemFlags(itemFlags.toArray(new ItemFlag[0])); + itemMeta.setLore(lore); + + itemStack.setItemMeta(itemMeta); + } - itemStack.setItemMeta(itemMeta); return itemStack; } diff --git a/src/main/java/de/studiocode/invui/item/impl/AsyncItem.java b/src/main/java/de/studiocode/invui/item/impl/AsyncItem.java new file mode 100644 index 0000000..5f072a3 --- /dev/null +++ b/src/main/java/de/studiocode/invui/item/impl/AsyncItem.java @@ -0,0 +1,47 @@ +package de.studiocode.invui.item.impl; + +import de.studiocode.invui.InvUI; +import de.studiocode.invui.item.Item; +import de.studiocode.invui.item.ItemBuilder; +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.ClickType; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.function.Supplier; + +/** + * An {@link Item} that creates it's {@link ItemBuilder} asynchronously and displays + * a placeholder {@link ItemBuilder} until the actual {@link ItemBuilder} has been created. + */ +public class AsyncItem extends BaseItem { + + private volatile ItemBuilder itemBuilder; + + public AsyncItem(@Nullable ItemBuilder itemBuilder, @NotNull Supplier builderSupplier) { + this.itemBuilder = itemBuilder == null ? new ItemBuilder(Material.AIR) : itemBuilder; + + Bukkit.getScheduler().runTaskAsynchronously(InvUI.getInstance().getPlugin(), () -> { + this.itemBuilder = builderSupplier.get(); + Bukkit.getScheduler().runTask(InvUI.getInstance().getPlugin(), this::notifyWindows); + }); + } + + public AsyncItem(@NotNull Supplier builderSupplier) { + this(null, builderSupplier); + } + + @Override + public ItemBuilder getItemBuilder() { + return itemBuilder; + } + + @Override + public void handleClick(ClickType clickType, Player player, InventoryClickEvent event) { + // empty + } + +}