Rework abstractions again and add SettingGuiListConfigGui

This commit is contained in:
alexcrea 2024-04-09 14:12:00 +02:00
parent 44b2ef7424
commit 52bb0785e7
No known key found for this signature in database
GPG key ID: 43FD265DB0DBF91F
9 changed files with 233 additions and 84 deletions

View file

@ -6,15 +6,15 @@ import org.bukkit.inventory.ItemFlag;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.inventory.meta.ItemMeta;
import xyz.alexcrea.cuanvil.config.ConfigHolder; import xyz.alexcrea.cuanvil.config.ConfigHolder;
import xyz.alexcrea.cuanvil.gui.config.list.MappedElementListConfigGui; import xyz.alexcrea.cuanvil.gui.config.list.MappedGuiListConfigGui;
import xyz.alexcrea.cuanvil.gui.config.settings.subsetting.CustomRecipeSubSettingGui; import xyz.alexcrea.cuanvil.gui.config.list.elements.CustomRecipeSubSettingGui;
import xyz.alexcrea.cuanvil.recipe.AnvilCustomRecipe; import xyz.alexcrea.cuanvil.recipe.AnvilCustomRecipe;
import xyz.alexcrea.cuanvil.util.CasedStringUtil; import xyz.alexcrea.cuanvil.util.CasedStringUtil;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
public class CustomRecipeConfigGui extends MappedElementListConfigGui<AnvilCustomRecipe, CustomRecipeSubSettingGui> { public class CustomRecipeConfigGui extends MappedGuiListConfigGui<AnvilCustomRecipe, CustomRecipeSubSettingGui> {
public final static CustomRecipeConfigGui INSTANCE = new CustomRecipeConfigGui(); public final static CustomRecipeConfigGui INSTANCE = new CustomRecipeConfigGui();

View file

@ -7,15 +7,15 @@ import org.bukkit.inventory.meta.ItemMeta;
import xyz.alexcrea.cuanvil.config.ConfigHolder; import xyz.alexcrea.cuanvil.config.ConfigHolder;
import xyz.alexcrea.cuanvil.group.EnchantConflictGroup; import xyz.alexcrea.cuanvil.group.EnchantConflictGroup;
import xyz.alexcrea.cuanvil.group.IncludeGroup; import xyz.alexcrea.cuanvil.group.IncludeGroup;
import xyz.alexcrea.cuanvil.gui.config.list.MappedElementListConfigGui; import xyz.alexcrea.cuanvil.gui.config.list.MappedGuiListConfigGui;
import xyz.alexcrea.cuanvil.gui.config.settings.subsetting.EnchantConflictSubSettingGui; import xyz.alexcrea.cuanvil.gui.config.list.elements.EnchantConflictSubSettingGui;
import xyz.alexcrea.cuanvil.gui.util.GuiSharedConstant; import xyz.alexcrea.cuanvil.gui.util.GuiSharedConstant;
import xyz.alexcrea.cuanvil.util.CasedStringUtil; import xyz.alexcrea.cuanvil.util.CasedStringUtil;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
public class EnchantConflictGui extends MappedElementListConfigGui<EnchantConflictGroup, EnchantConflictSubSettingGui> { public class EnchantConflictGui extends MappedGuiListConfigGui<EnchantConflictGroup, EnchantConflictSubSettingGui> {
public final static EnchantConflictGui INSTANCE = new EnchantConflictGui(); public final static EnchantConflictGui INSTANCE = new EnchantConflictGui();

View file

@ -9,7 +9,7 @@ public interface ElementMappedToListGui {
void updateLocal(); void updateLocal();
void cleanUnused(); void cleanAndBeUnusable();
Gui getMappedGui(); Gui getMappedGui();

View file

@ -11,12 +11,9 @@ import xyz.alexcrea.cuanvil.gui.util.GuiGlobalActions;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashMap; import java.util.HashMap;
import java.util.Locale;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Consumer; import java.util.function.Consumer;
public abstract class MappedElementListConfigGui< T, S extends ElementMappedToListGui> extends ElementListConfigGui< T > { public abstract class MappedElementListConfigGui< T, S > extends ElementListConfigGui< T > {
protected final HashMap<T, S> elementGuiMap; protected final HashMap<T, S> elementGuiMap;
public MappedElementListConfigGui(@NotNull String title) { public MappedElementListConfigGui(@NotNull String title) {
@ -60,95 +57,48 @@ public abstract class MappedElementListConfigGui< T, S extends ElementMappedToLi
}, CustomAnvil.instance); }, CustomAnvil.instance);
} }
@Override
public void reloadValues() {
this.elementGuiMap.forEach((conflict, gui) -> gui.cleanUnused());
this.elementGuiMap.clear();
super.reloadValues();
}
@Override @Override
protected void updateGeneric(T generic, ItemStack usedItem) { protected void updateGeneric(T generic, ItemStack usedItem) {
S mapElement = this.elementGuiMap.get(generic); S element = this.elementGuiMap.get(generic);
GuiItem guiItem; GuiItem guiItem;
if (mapElement == null) { if (element == null) {
// Create new sub setting mapElement // Create new sub setting element
guiItem = new GuiItem(usedItem, CustomAnvil.instance); guiItem = new GuiItem(usedItem, CustomAnvil.instance);
mapElement = newInstanceOfGui(generic, guiItem);
guiItem.setAction(GuiGlobalActions.openGuiAction(mapElement.getMappedGui())); element = newElementRequested(generic, guiItem);
this.elementGuiMap.put(generic, element);
this.elementGuiMap.put(generic, mapElement);
addToPage(guiItem); addToPage(guiItem);
} else { } else {
// Replace item with the updated one // Replace item with the updated one
guiItem = mapElement.getParentItemForThisGui(); guiItem = findItemFromElement(generic, element);
guiItem.setItem(usedItem); guiItem.setItem(usedItem);
} }
mapElement.updateLocal(); updateElement(generic, element);
} }
protected abstract void updateElement(T generic, S element);
protected abstract S newElementRequested(T generic, GuiItem newItem);
protected abstract GuiItem findItemFromElement(T generic, S element);
@Override @Override
protected GuiItem findGuiItemForRemoval(T generic) { protected GuiItem findGuiItemForRemoval(T generic) {
S mapElement = this.elementGuiMap.get(generic); S element = this.elementGuiMap.get(generic);
if (mapElement == null) return null; if (element == null) return null;
this.elementGuiMap.remove(generic); this.elementGuiMap.remove(generic);
return mapElement.getParentItemForThisGui(); return findGuiItemForRemoval(generic, element);
} }
protected Consumer<String> prepareCreateItemConsumer(HumanEntity player){ protected abstract GuiItem findGuiItemForRemoval(T generic, S element);
AtomicReference<Consumer<String>> selfRef = new AtomicReference<>();
Consumer<String> selfCallback = (message) -> {
if (message == null) return;
// check permission protected abstract Consumer<String> prepareCreateItemConsumer(HumanEntity player);
if (!player.hasPermission(CustomAnvil.editConfigPermission)) {
player.sendMessage(GuiGlobalActions.NO_EDIT_PERM);
return;
}
message = message.toLowerCase(Locale.ROOT);
if ("cancel".equalsIgnoreCase(message)) {
player.sendMessage(genericDisplayedName()+" creation cancelled...");
show(player);
return;
}
message = message.replace(' ', '_');
// Try to find if it already exists in a for loop
// Not the most efficient on large number of conflict, but it should not run often.
for (T generic : getEveryDisplayableInstanceOfGeneric()) {
if (generic.toString().equalsIgnoreCase(message)) {
player.sendMessage("\u00A7cPlease enter a "+genericDisplayedName()+" name that do not already exist...");
// wait next message.
CustomAnvil.Companion.getChatListener().setListenedCallback(player, selfRef.get());
return;
}
}
T generic = createAndSaveNewEmptyGeneric(message);
updateValueForGeneric(generic, true);
// show the new conflict config to the player
this.elementGuiMap.get(generic).getMappedGui().show(player);
update();
};
selfRef.set(selfCallback);
return selfCallback;
}
protected abstract S newInstanceOfGui(T generic, GuiItem item);
protected abstract String genericDisplayedName(); protected abstract String genericDisplayedName();
protected abstract T createAndSaveNewEmptyGeneric(String name);
} }

View file

@ -0,0 +1,104 @@
package xyz.alexcrea.cuanvil.gui.config.list;
import com.github.stefvanschie.inventoryframework.gui.GuiItem;
import io.delilaheve.CustomAnvil;
import org.bukkit.entity.HumanEntity;
import org.jetbrains.annotations.NotNull;
import xyz.alexcrea.cuanvil.gui.util.GuiGlobalActions;
import java.util.Locale;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Consumer;
public abstract class MappedGuiListConfigGui< T, S extends ElementMappedToListGui> extends MappedElementListConfigGui< T, S > {
public MappedGuiListConfigGui(@NotNull String title) {
super(title);
}
@Override
public void reloadValues() {
this.elementGuiMap.forEach((conflict, gui) -> gui.cleanAndBeUnusable());
this.elementGuiMap.clear();
super.reloadValues();
}
@Override
protected S newElementRequested(T generic, GuiItem newItem) {
S element = newInstanceOfGui(generic, newItem);
newItem.setAction(GuiGlobalActions.openGuiAction(element.getMappedGui()));
return element;
}
@Override
protected GuiItem findItemFromElement(T generic, S element) {
return element.getParentItemForThisGui();
}
@Override
protected void updateElement(T generic, S element) {
element.updateLocal();
}
@Override
protected GuiItem findGuiItemForRemoval(T generic, S element) {
return element.getParentItemForThisGui();
}
@Override
protected Consumer<String> prepareCreateItemConsumer(HumanEntity player){
AtomicReference<Consumer<String>> selfRef = new AtomicReference<>();
Consumer<String> selfCallback = (message) -> {
if (message == null) return;
// check permission
if (!player.hasPermission(CustomAnvil.editConfigPermission)) {
player.sendMessage(GuiGlobalActions.NO_EDIT_PERM);
return;
}
message = message.toLowerCase(Locale.ROOT);
if ("cancel".equalsIgnoreCase(message)) {
player.sendMessage(genericDisplayedName()+" creation cancelled...");
show(player);
return;
}
message = message.replace(' ', '_');
// Try to find if it already exists in a for loop
// Not the most efficient on large number of conflict, but it should not run often.
for (T generic : getEveryDisplayableInstanceOfGeneric()) {
if (generic.toString().equalsIgnoreCase(message)) {
player.sendMessage("\u00A7cPlease enter a "+genericDisplayedName()+" name that do not already exist...");
// wait next message.
CustomAnvil.Companion.getChatListener().setListenedCallback(player, selfRef.get());
return;
}
}
T generic = createAndSaveNewEmptyGeneric(message);
updateValueForGeneric(generic, true);
// show the new conflict config to the player
this.elementGuiMap.get(generic).getMappedGui().show(player);
update();
};
selfRef.set(selfCallback);
return selfCallback;
}
protected abstract S newInstanceOfGui(T generic, GuiItem item);
protected abstract String genericDisplayedName();
protected abstract T createAndSaveNewEmptyGeneric(String name);
}

View file

@ -0,0 +1,95 @@
package xyz.alexcrea.cuanvil.gui.config.list;
import com.github.stefvanschie.inventoryframework.gui.GuiItem;
import io.delilaheve.CustomAnvil;
import org.bukkit.Material;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.jetbrains.annotations.NotNull;
import xyz.alexcrea.cuanvil.gui.config.settings.AbstractSettingGui;
import java.util.HashMap;
import java.util.List;
import java.util.function.Consumer;
public abstract class SettingGuiListConfigGui< T, S extends AbstractSettingGui.SettingGuiFactory> extends ElementListConfigGui< T >{
protected HashMap<T, GuiItem> guiItemMap;
protected HashMap<T, S> factoryMap;
public SettingGuiListConfigGui(@NotNull String title) {
super(title);
this.guiItemMap = new HashMap<>();
this.factoryMap = new HashMap<>();
}
@Override
protected GuiItem prepareCreateNewItem() {
ItemStack createItem = new ItemStack(Material.PAPER);
ItemMeta createMeta = createItem.getItemMeta();
createMeta.setDisplayName("\u00A7aCreate new " + genericDisplayedName());
createMeta.setLore(getCreateItemLore());
createItem.setItemMeta(createMeta);
return new GuiItem(createItem, getCreateClickConsumer(), CustomAnvil.instance);
}
@Override
public void updateValueForGeneric(T generic, boolean shouldUpdate) {
S factory = this.factoryMap.get(generic);
if(factory == null){
// Create new item & factory
factory = createFactory(generic);
GuiItem newItem = itemFromFactory(factory);
addToPage(newItem);
this.guiItemMap.put(generic, newItem);
this.factoryMap.put(generic, factory);
}else{
// Update old item
GuiItem oldItem = this.guiItemMap.get(generic);
GuiItem newItem = itemFromFactory(factory);
updateGuiItem(oldItem, newItem);
}
if(shouldUpdate){
update();
}
}
@Override
protected void reloadValues() {
this.guiItemMap.clear();
this.factoryMap.clear();
super.reloadValues();
}
private void updateGuiItem(GuiItem oldITem, GuiItem newItem){
oldITem.setItem(newItem.getItem());
oldITem.setProperties(newItem.getProperties());
oldITem.setVisible(newItem.isVisible());
}
@Override
protected GuiItem findGuiItemForRemoval(T generic) {
return this.guiItemMap.get(generic);
}
@Override // Not used
protected void updateGeneric(T generic, ItemStack usedItem) {}
@Override // Not used
protected ItemStack createItemForGeneric(T generic) {
return null;
}
protected abstract List<String> getCreateItemLore();
protected abstract Consumer<InventoryClickEvent> getCreateClickConsumer();
protected abstract String genericDisplayedName();
protected abstract S createFactory(T generic);
protected abstract GuiItem itemFromFactory(S factory);
}

View file

@ -1,4 +1,4 @@
package xyz.alexcrea.cuanvil.gui.config.settings.subsetting; package xyz.alexcrea.cuanvil.gui.config.list.elements;
import com.github.stefvanschie.inventoryframework.gui.GuiItem; import com.github.stefvanschie.inventoryframework.gui.GuiItem;
import com.github.stefvanschie.inventoryframework.pane.PatternPane; import com.github.stefvanschie.inventoryframework.pane.PatternPane;
@ -109,7 +109,7 @@ public class CustomRecipeSubSettingGui extends MappedToListSubSettingGui {
this.parent.removeGeneric(this.anvilRecipe); this.parent.removeGeneric(this.anvilRecipe);
// Remove self // Remove self
cleanUnused(); cleanAndBeUnusable();
// Update config file storage // Update config file storage
ConfigHolder.CUSTOM_RECIPE_HOLDER.getConfig().set(this.anvilRecipe.toString(), null); ConfigHolder.CUSTOM_RECIPE_HOLDER.getConfig().set(this.anvilRecipe.toString(), null);
@ -159,7 +159,7 @@ public class CustomRecipeSubSettingGui extends MappedToListSubSettingGui {
update(); update();
} }
public void cleanUnused() { public void cleanAndBeUnusable() {
for (HumanEntity viewer : getViewers()) { for (HumanEntity viewer : getViewers()) {
this.parent.show(viewer); this.parent.show(viewer);
} }

View file

@ -1,4 +1,4 @@
package xyz.alexcrea.cuanvil.gui.config.settings.subsetting; package xyz.alexcrea.cuanvil.gui.config.list.elements;
import com.github.stefvanschie.inventoryframework.gui.GuiItem; import com.github.stefvanschie.inventoryframework.gui.GuiItem;
import com.github.stefvanschie.inventoryframework.pane.PatternPane; import com.github.stefvanschie.inventoryframework.pane.PatternPane;
@ -126,7 +126,7 @@ public class EnchantConflictSubSettingGui extends MappedToListSubSettingGui impl
this.parent.removeGeneric(this.enchantConflict); this.parent.removeGeneric(this.enchantConflict);
// Remove self // Remove self
cleanUnused(); cleanAndBeUnusable();
// Update config file storage // Update config file storage
ConfigHolder.CONFLICT_HOLDER.getConfig().set(this.enchantConflict.toString(), null); ConfigHolder.CONFLICT_HOLDER.getConfig().set(this.enchantConflict.toString(), null);
@ -234,7 +234,7 @@ public class EnchantConflictSubSettingGui extends MappedToListSubSettingGui impl
} }
@Override @Override
public void cleanUnused() { public void cleanAndBeUnusable() {
for (HumanEntity viewer : getViewers()) { for (HumanEntity viewer : getViewers()) {
this.parent.show(viewer); this.parent.show(viewer);
} }

View file

@ -1,4 +1,4 @@
package xyz.alexcrea.cuanvil.gui.config.settings.subsetting; package xyz.alexcrea.cuanvil.gui.config.list.elements;
import com.github.stefvanschie.inventoryframework.gui.GuiItem; import com.github.stefvanschie.inventoryframework.gui.GuiItem;
import com.github.stefvanschie.inventoryframework.gui.type.util.Gui; import com.github.stefvanschie.inventoryframework.gui.type.util.Gui;