diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/guide/SurvivalSlimefunGuide.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/guide/SurvivalSlimefunGuide.java index 048dc3436..aab49ab77 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/guide/SurvivalSlimefunGuide.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/guide/SurvivalSlimefunGuide.java @@ -41,7 +41,7 @@ import io.github.thebusybiscuit.slimefun4.core.multiblocks.MultiBlock; import io.github.thebusybiscuit.slimefun4.core.multiblocks.MultiBlockMachine; import io.github.thebusybiscuit.slimefun4.core.researching.Research; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; -import io.github.thebusybiscuit.slimefun4.implementation.tasks.RecipeChoiceTask; +import io.github.thebusybiscuit.slimefun4.implementation.tasks.AsyncRecipeChoiceTask; import io.github.thebusybiscuit.slimefun4.utils.ChatUtils; import io.github.thebusybiscuit.slimefun4.utils.ChestMenuUtils; import io.github.thebusybiscuit.slimefun4.utils.itemstack.SlimefunGuideItem; @@ -408,7 +408,7 @@ public class SurvivalSlimefunGuide implements SlimefunGuideImplementation { ItemStack result = null; Optional> optional = MinecraftRecipe.of(recipe); - RecipeChoiceTask task = new RecipeChoiceTask(); + AsyncRecipeChoiceTask task = new AsyncRecipeChoiceTask(); if (optional.isPresent()) { showRecipeChoices(recipe, recipeItems, task); @@ -454,7 +454,7 @@ public class SurvivalSlimefunGuide implements SlimefunGuideImplementation { } } - private void showRecipeChoices(T recipe, ItemStack[] recipeItems, RecipeChoiceTask task) { + private void showRecipeChoices(T recipe, ItemStack[] recipeItems, AsyncRecipeChoiceTask task) { RecipeChoice[] choices = SlimefunPlugin.getMinecraftRecipeService().getRecipeShape(recipe); if (choices.length == 1 && choices[0] instanceof MaterialChoice) { @@ -496,7 +496,7 @@ public class SurvivalSlimefunGuide implements SlimefunGuideImplementation { }); } - RecipeChoiceTask task = new RecipeChoiceTask(); + AsyncRecipeChoiceTask task = new AsyncRecipeChoiceTask(); if (addToHistory) { profile.getGuideHistory().add(item); @@ -519,7 +519,7 @@ public class SurvivalSlimefunGuide implements SlimefunGuideImplementation { } } - private void displayItem(ChestMenu menu, PlayerProfile profile, Player p, Object item, ItemStack output, RecipeType recipeType, ItemStack[] recipe, RecipeChoiceTask task) { + private void displayItem(ChestMenu menu, PlayerProfile profile, Player p, Object item, ItemStack output, RecipeType recipeType, ItemStack[] recipe, AsyncRecipeChoiceTask task) { addBackButton(menu, 0, p, profile); MenuClickHandler clickHandler = (pl, slot, itemstack, action) -> { diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/auto_crafters/AbstractAutoCrafter.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/auto_crafters/AbstractAutoCrafter.java index 082b78fed..5b064b327 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/auto_crafters/AbstractAutoCrafter.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/auto_crafters/AbstractAutoCrafter.java @@ -31,7 +31,7 @@ import io.github.thebusybiscuit.slimefun4.core.attributes.EnergyNetComponent; import io.github.thebusybiscuit.slimefun4.core.handlers.BlockUseHandler; import io.github.thebusybiscuit.slimefun4.core.networks.energy.EnergyNetComponentType; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; -import io.github.thebusybiscuit.slimefun4.implementation.tasks.RecipeChoiceTask; +import io.github.thebusybiscuit.slimefun4.implementation.tasks.AsyncRecipeChoiceTask; import io.github.thebusybiscuit.slimefun4.utils.ChestMenuUtils; import io.papermc.lib.PaperLib; import me.mrCookieSlime.CSCoreLibPlugin.Configuration.Config; @@ -205,7 +205,7 @@ public abstract class AbstractAutoCrafter extends SlimefunItem implements Energy return false; }); - RecipeChoiceTask task = new RecipeChoiceTask(); + AsyncRecipeChoiceTask task = new AsyncRecipeChoiceTask(); recipe.show(menu, task); menu.open(p); diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/auto_crafters/AbstractRecipe.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/auto_crafters/AbstractRecipe.java index 42a0ec35b..0b25a6052 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/auto_crafters/AbstractRecipe.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/auto_crafters/AbstractRecipe.java @@ -13,7 +13,7 @@ import org.bukkit.inventory.Recipe; import org.bukkit.inventory.ShapedRecipe; import org.bukkit.inventory.ShapelessRecipe; -import io.github.thebusybiscuit.slimefun4.implementation.tasks.RecipeChoiceTask; +import io.github.thebusybiscuit.slimefun4.implementation.tasks.AsyncRecipeChoiceTask; import me.mrCookieSlime.CSCoreLibPlugin.general.Inventory.ChestMenu; import me.mrCookieSlime.Slimefun.Lists.RecipeType; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem; @@ -42,7 +42,7 @@ public abstract class AbstractRecipe { return result; } - public abstract void show(@Nonnull ChestMenu menu, @Nonnull RecipeChoiceTask task); + public abstract void show(@Nonnull ChestMenu menu, @Nonnull AsyncRecipeChoiceTask task); @Nullable public static AbstractRecipe of(@Nullable Recipe recipe) { diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/auto_crafters/EnhancedRecipe.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/auto_crafters/EnhancedRecipe.java index ebf0320b9..1f22042d4 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/auto_crafters/EnhancedRecipe.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/auto_crafters/EnhancedRecipe.java @@ -7,7 +7,7 @@ import javax.annotation.Nonnull; import org.bukkit.inventory.ItemStack; import io.github.thebusybiscuit.slimefun4.implementation.items.multiblocks.EnhancedCraftingTable; -import io.github.thebusybiscuit.slimefun4.implementation.tasks.RecipeChoiceTask; +import io.github.thebusybiscuit.slimefun4.implementation.tasks.AsyncRecipeChoiceTask; import io.github.thebusybiscuit.slimefun4.utils.ChestMenuUtils; import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils; import me.mrCookieSlime.CSCoreLibPlugin.general.Inventory.ChestMenu; @@ -39,7 +39,7 @@ class EnhancedRecipe extends AbstractRecipe { } @Override - public void show(@Nonnull ChestMenu menu, @Nonnull RecipeChoiceTask task) { + public void show(@Nonnull ChestMenu menu, @Nonnull AsyncRecipeChoiceTask task) { menu.addItem(24, getResult().clone(), ChestMenuUtils.getEmptyClickHandler()); ItemStack[] recipe = item.getRecipe(); diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/auto_crafters/VanillaAutoCrafter.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/auto_crafters/VanillaAutoCrafter.java index 07c98cdfc..7aba79446 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/auto_crafters/VanillaAutoCrafter.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/auto_crafters/VanillaAutoCrafter.java @@ -21,12 +21,14 @@ import org.bukkit.inventory.ShapelessRecipe; import io.github.thebusybiscuit.cscorelib2.data.PersistentDataAPI; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; +import io.github.thebusybiscuit.slimefun4.implementation.tasks.AsyncRecipeChoiceTask; import io.github.thebusybiscuit.slimefun4.utils.PatternUtils; import io.papermc.lib.PaperLib; import me.mrCookieSlime.Slimefun.Lists.RecipeType; import me.mrCookieSlime.Slimefun.Objects.Category; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem; import me.mrCookieSlime.Slimefun.api.SlimefunItemStack; +import me.mrCookieSlime.Slimefun.api.inventory.BlockMenu; public class VanillaAutoCrafter extends AbstractAutoCrafter { @@ -90,6 +92,11 @@ public class VanillaAutoCrafter extends AbstractAutoCrafter { // TODO Choose vanilla recipe } } + + @ParametersAreNonnullByDefault + private void offerRecipe(Player p, Block b, List recipes, int page, BlockMenu menu, AsyncRecipeChoiceTask task) { + + } @Nonnull private List getRecipesFor(@Nonnull ItemStack item) { diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/auto_crafters/VanillaRecipe.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/auto_crafters/VanillaRecipe.java index 1afa449c7..f257daeb9 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/auto_crafters/VanillaRecipe.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/auto_crafters/VanillaRecipe.java @@ -15,7 +15,7 @@ import org.bukkit.inventory.ShapedRecipe; import org.bukkit.inventory.ShapelessRecipe; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; -import io.github.thebusybiscuit.slimefun4.implementation.tasks.RecipeChoiceTask; +import io.github.thebusybiscuit.slimefun4.implementation.tasks.AsyncRecipeChoiceTask; import io.github.thebusybiscuit.slimefun4.utils.ChestMenuUtils; import me.mrCookieSlime.CSCoreLibPlugin.general.Inventory.ChestMenu; @@ -68,7 +68,7 @@ class VanillaRecipe extends AbstractRecipe { } @Override - public void show(@Nonnull ChestMenu menu, @Nonnull RecipeChoiceTask task) { + public void show(@Nonnull ChestMenu menu, @Nonnull AsyncRecipeChoiceTask task) { menu.addItem(24, getResult().clone(), ChestMenuUtils.getEmptyClickHandler()); RecipeChoice[] choices = SlimefunPlugin.getMinecraftRecipeService().getRecipeShape(recipe); ItemStack[] items = new ItemStack[9]; diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/RecipeChoiceTask.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/AsyncRecipeChoiceTask.java similarity index 66% rename from src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/RecipeChoiceTask.java rename to src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/AsyncRecipeChoiceTask.java index 2864cd18b..a0e51256f 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/RecipeChoiceTask.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/AsyncRecipeChoiceTask.java @@ -2,6 +2,8 @@ package io.github.thebusybiscuit.slimefun4.implementation.tasks; import java.util.HashMap; import java.util.Map; +import java.util.concurrent.locks.ReadWriteLock; +import java.util.concurrent.locks.ReentrantReadWriteLock; import javax.annotation.Nonnull; @@ -19,7 +21,7 @@ import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; import io.github.thebusybiscuit.slimefun4.implementation.guide.SurvivalSlimefunGuide; /** - * A {@link RecipeChoiceTask} is an asynchronously repeating task that cycles + * A {@link AsyncRecipeChoiceTask} is an asynchronously repeating task that cycles * through the different variants of {@link Material} that a {@link MaterialChoice} or {@link Tag} can represent. * * It is used in the {@link SurvivalSlimefunGuide} for any {@link ItemStack} from Minecraft @@ -28,11 +30,13 @@ import io.github.thebusybiscuit.slimefun4.implementation.guide.SurvivalSlimefunG * @author TheBusyBiscuit * */ -public class RecipeChoiceTask implements Runnable { +public class AsyncRecipeChoiceTask implements Runnable { private static final int UPDATE_INTERVAL = 14; private final Map> iterators = new HashMap<>(); + private final ReadWriteLock lock = new ReentrantReadWriteLock(); + private Inventory inventory; private int id; @@ -44,21 +48,33 @@ public class RecipeChoiceTask implements Runnable { */ public void start(@Nonnull Inventory inv) { Validate.notNull(inv, "Inventory must not be null"); - + inventory = inv; id = Bukkit.getScheduler().runTaskTimerAsynchronously(SlimefunPlugin.instance(), this, 0, UPDATE_INTERVAL).getTaskId(); } public void add(int slot, @Nonnull MaterialChoice choice) { Validate.notNull(choice, "Cannot add a null RecipeChoice"); - - iterators.put(slot, new LoopIterator<>(choice.getChoices())); + + lock.writeLock().lock(); + + try { + iterators.put(slot, new LoopIterator<>(choice.getChoices())); + } finally { + lock.writeLock().unlock(); + } } public void add(int slot, @Nonnull Tag tag) { Validate.notNull(tag, "Cannot add a null Tag"); - - iterators.put(slot, new LoopIterator<>(tag.getValues())); + + lock.writeLock().lock(); + + try { + iterators.put(slot, new LoopIterator<>(tag.getValues())); + } finally { + lock.writeLock().unlock(); + } } /** @@ -67,7 +83,13 @@ public class RecipeChoiceTask implements Runnable { * @return Whether this task has nothing to do */ public boolean isEmpty() { - return iterators.isEmpty(); + lock.readLock().lock(); + + try { + return iterators.isEmpty(); + } finally { + lock.readLock().unlock(); + } } @Override @@ -78,8 +100,14 @@ public class RecipeChoiceTask implements Runnable { return; } - for (Map.Entry> entry : iterators.entrySet()) { - inventory.setItem(entry.getKey(), new ItemStack(entry.getValue().next())); + lock.readLock().lock(); + + try { + for (Map.Entry> entry : iterators.entrySet()) { + inventory.setItem(entry.getKey(), new ItemStack(entry.getValue().next())); + } + } finally { + lock.readLock().unlock(); } }