diff --git a/pom.xml b/pom.xml index eb2580c14..8f539fa74 100644 --- a/pom.xml +++ b/pom.xml @@ -76,6 +76,12 @@ 5.1.0 provided + + it.unimi.dsi + fastutil + 8.5.6 + provided + org.junit.jupiter diff --git a/src/main/java/com/wolfyscript/utilities/NamespacedKey.java b/src/main/java/com/wolfyscript/utilities/NamespacedKey.java index 6e58c013f..9545ca225 100644 --- a/src/main/java/com/wolfyscript/utilities/NamespacedKey.java +++ b/src/main/java/com/wolfyscript/utilities/NamespacedKey.java @@ -18,6 +18,12 @@ package com.wolfyscript.utilities; +import com.fasterxml.jackson.annotation.JsonIgnore; +import net.kyori.adventure.key.Key; +import net.kyori.adventure.key.Namespaced; +import org.intellij.lang.annotations.Pattern; +import org.intellij.lang.annotations.Subst; + /** * The NamespacedKey is used to manage and identify resources and prevent conflicts with for example plugins.
* It consists of a unique namespace and a key. (The same key can exist in different namespaces)
@@ -55,6 +61,10 @@ public interface NamespacedKey { String toString(String separator); + default net.kyori.adventure.key.Key toKyoriKey() { + return net.kyori.adventure.key.Key.key(toString(":")); + } + /** * Represents the key part of the NamespacedKey. * The idea behind this component is to make it easier to manage folders specified in the key and provide util methods for it.
diff --git a/src/main/java/com/wolfyscript/utilities/Platform.java b/src/main/java/com/wolfyscript/utilities/Platform.java new file mode 100644 index 000000000..028d64a8a --- /dev/null +++ b/src/main/java/com/wolfyscript/utilities/Platform.java @@ -0,0 +1,27 @@ +/* + * WolfyUtilities, APIs and Utilities for Minecraft Spigot plugins + * Copyright (C) 2021 WolfyScript + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.wolfyscript.utilities; + +public enum Platform { + + SPIGOT, + PAPER, + SPONGE + +} diff --git a/src/main/java/com/wolfyscript/utilities/common/WolfyCore.java b/src/main/java/com/wolfyscript/utilities/common/WolfyCore.java index 1aebe07ca..668045340 100644 --- a/src/main/java/com/wolfyscript/utilities/common/WolfyCore.java +++ b/src/main/java/com/wolfyscript/utilities/common/WolfyCore.java @@ -19,8 +19,11 @@ package com.wolfyscript.utilities.common; import com.fasterxml.jackson.databind.ObjectMapper; +import com.wolfyscript.utilities.Platform; import com.wolfyscript.utilities.common.chat.Chat; import com.wolfyscript.utilities.common.registry.Registries; +import net.kyori.adventure.audience.Audience; +import net.kyori.adventure.platform.AudienceProvider; import org.reflections.Reflections; /** @@ -38,4 +41,6 @@ public interface WolfyCore { Reflections getReflections(); Registries getRegistries(); + + Platform getPlatform(); } diff --git a/src/main/java/com/wolfyscript/utilities/common/WolfyUtils.java b/src/main/java/com/wolfyscript/utilities/common/WolfyUtils.java index 02eef6276..c6d21ce14 100644 --- a/src/main/java/com/wolfyscript/utilities/common/WolfyUtils.java +++ b/src/main/java/com/wolfyscript/utilities/common/WolfyUtils.java @@ -20,12 +20,14 @@ import com.fasterxml.jackson.annotation.JsonIncludeProperties; import com.wolfyscript.utilities.common.chat.Chat; +import com.wolfyscript.utilities.common.gui.GuiAPIManager; import com.wolfyscript.utilities.common.json.jackson.MapperUtil; import com.wolfyscript.utilities.common.registry.Registries; import java.util.logging.Logger; import com.wolfyscript.utilities.common.language.LanguageAPI; import java.io.File; +import java.util.regex.Pattern; /** * Represents a single API instance that is bound to a plugin or mod. @@ -68,6 +70,8 @@ public static boolean isProdEnv() { public abstract Identifiers getIdentifiers(); + public abstract GuiAPIManager getGUIManager(); + public Registries getRegistries() { return getCore().getRegistries(); } @@ -76,5 +80,7 @@ public MapperUtil getJacksonMapperUtil() { return mapperUtil; } + public abstract void exportResource(String resourcePath, File destination, boolean replace); + public abstract void exportResources(String resourceName, File dir, boolean replace, Pattern filePattern); } diff --git a/src/main/java/com/wolfyscript/utilities/common/adapters/Entity.java b/src/main/java/com/wolfyscript/utilities/common/adapters/Entity.java index e848b3e82..50cd26417 100644 --- a/src/main/java/com/wolfyscript/utilities/common/adapters/Entity.java +++ b/src/main/java/com/wolfyscript/utilities/common/adapters/Entity.java @@ -22,8 +22,12 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.UUID; + public interface Entity { + UUID uuid(); + @NotNull Location getLocation(); diff --git a/src/main/java/com/wolfyscript/utilities/common/adapters/ItemStack.java b/src/main/java/com/wolfyscript/utilities/common/adapters/ItemStack.java index 2e0fa5f08..8146a19b4 100644 --- a/src/main/java/com/wolfyscript/utilities/common/adapters/ItemStack.java +++ b/src/main/java/com/wolfyscript/utilities/common/adapters/ItemStack.java @@ -18,10 +18,33 @@ package com.wolfyscript.utilities.common.adapters; +import com.wolfyscript.utilities.NamespacedKey; +import com.wolfyscript.utilities.common.items.ItemStackConfig; + public interface ItemStack { - Item getItem(); + /** + * The id representing the item of this ItemStack.
+ * Usually e.g.
minecraft:<item_id>
+ * + * @return The id of the item. + */ + NamespacedKey getItem(); + /** + * The stack amount of this ItemStack. + * + * @return The stack amount. + */ int getAmount(); + /** + * Creates a snapshot of the whole ItemStack including the full NBT.
+ * This can be quite resource heavy!
+ * The snapshot can be simply written to json using the Json mapper of WolfyUtils. + * + * @return The snapshot ItemStack config of this ItemStack. + */ + ItemStackConfig snapshot(); + } diff --git a/src/main/java/com/wolfyscript/utilities/common/adapters/Items.java b/src/main/java/com/wolfyscript/utilities/common/adapters/Items.java index 03a2407b7..af31d8d8c 100644 --- a/src/main/java/com/wolfyscript/utilities/common/adapters/Items.java +++ b/src/main/java/com/wolfyscript/utilities/common/adapters/Items.java @@ -20,6 +20,6 @@ public interface Items { - Item getItem(String key); + } diff --git a/src/main/java/com/wolfyscript/utilities/common/gui/ButtonStateDefault.java b/src/main/java/com/wolfyscript/utilities/common/gui/ButtonStateDefault.java new file mode 100644 index 000000000..16da727a6 --- /dev/null +++ b/src/main/java/com/wolfyscript/utilities/common/gui/ButtonStateDefault.java @@ -0,0 +1,97 @@ +/* + * WolfyUtilities, APIs and Utilities for Minecraft Spigot plugins + * Copyright (C) 2021 WolfyScript + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.wolfyscript.utilities.common.gui; + +import com.google.common.base.Preconditions; +import com.wolfyscript.utilities.common.gui.callback.InteractionCallback; +import com.wolfyscript.utilities.common.gui.callback.RenderCallback; +import com.wolfyscript.utilities.common.gui.components.ButtonState; +import java.util.Objects; + +public class ButtonStateDefault implements ButtonState { + + private final String key; + private final InteractionCallback interactionCallback; + private final RenderCallback renderCallback; + + protected ButtonStateDefault(String key, InteractionCallback interactionCallback, RenderCallback renderCallback) { + this.key = key; + this.interactionCallback = interactionCallback; + this.renderCallback = renderCallback; + } + + @Override + public InteractionCallback interactCallback() { + return interactionCallback; + } + + @Override + public RenderCallback renderCallback() { + return renderCallback; + } + + @Override + public String key() { + return key; + } + + public static class Builder implements ButtonState.Builder { + + private String key; + private InteractionCallback interactionCallback; + private RenderCallback renderCallback; + + protected Builder(String ownerID) { + this.key = ownerID; + } + + @Override + public Builder subKey(String subKey) { + this.key += "." + subKey; + return this; + } + + @Override + public Builder key(String key) { + this.key = key; + return this; + } + + @Override + public Builder interact(InteractionCallback interactionCallback) { + this.interactionCallback = interactionCallback; + return this; + } + + @Override + public Builder render(RenderCallback renderCallback) { + this.renderCallback = renderCallback; + return null; + } + + @Override + public ButtonStateDefault create() { + Preconditions.checkNotNull(renderCallback, "Cannot create Component without a RenderCallback!"); + final var interactCallback = Objects.requireNonNullElseGet(this.interactionCallback, () -> (holder, details) -> InteractionResult.def()); + final var renderCallback = Objects.requireNonNullElseGet(this.renderCallback, () -> (holder) -> {}); + + return new ButtonStateDefault(key, interactCallback, renderCallback); + } + } + } diff --git a/src/main/java/com/wolfyscript/utilities/common/gui/GUIClickInteractionDetails.java b/src/main/java/com/wolfyscript/utilities/common/gui/ClickInteractionDetails.java similarity index 75% rename from src/main/java/com/wolfyscript/utilities/common/gui/GUIClickInteractionDetails.java rename to src/main/java/com/wolfyscript/utilities/common/gui/ClickInteractionDetails.java index 245bf92d9..b00ebd050 100644 --- a/src/main/java/com/wolfyscript/utilities/common/gui/GUIClickInteractionDetails.java +++ b/src/main/java/com/wolfyscript/utilities/common/gui/ClickInteractionDetails.java @@ -1,6 +1,6 @@ package com.wolfyscript.utilities.common.gui; -public interface GUIClickInteractionDetails extends GUIInteractionDetails { +public interface ClickInteractionDetails extends InteractionDetails { boolean isShift(); diff --git a/src/main/java/com/wolfyscript/utilities/common/gui/Component.java b/src/main/java/com/wolfyscript/utilities/common/gui/Component.java new file mode 100644 index 000000000..fc0c31374 --- /dev/null +++ b/src/main/java/com/wolfyscript/utilities/common/gui/Component.java @@ -0,0 +1,100 @@ +/* + * WolfyUtilities, APIs and Utilities for Minecraft Spigot plugins + * Copyright (C) 2021 WolfyScript + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.wolfyscript.utilities.common.gui; + +import com.fasterxml.jackson.annotation.JsonGetter; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.wolfyscript.utilities.Keyed; +import com.wolfyscript.utilities.NamespacedKey; +import com.wolfyscript.utilities.common.WolfyUtils; +import it.unimi.dsi.fastutil.ints.IntList; + +import java.util.function.Consumer; + +public interface Component extends Keyed { + + @JsonIgnore + @Override + NamespacedKey getNamespacedKey(); + + @JsonGetter("type") + default NamespacedKey type() { + return getNamespacedKey(); + } + + /** + * Gets the unique id (in context of the parent) of this component. + * + * @return The id of this component. + */ + String getID(); + + /** + * Gets the global WolfyUtils instance, this component belongs to. + * + * @return The WolfyUtils API instance. + */ + WolfyUtils getWolfyUtils(); + + /** + * The parent of this Component, or null if it is a root Component. + * + * @return The parent; or null if root Component. + */ + Component parent(); + + Component construct(GuiHolder holder, GuiViewManager viewManager); + + void remove(GuiHolder holder, GuiViewManager viewManager, RenderContext context); + + /** + * Gets the width of this Component in slot count. + * + * @return The width in slots. + */ + int width(); + + /** + * Gets the width of this Component in slot count. + * + * @return The height in slots. + */ + int height(); + + Position position(); + + default int offset() { + Component parent = parent(); + int totalOffset = 0; + while(parent != null && parent.position().type() != Position.Type.ABSOLUTE) { + totalOffset += parent.position().slot(); + parent = parent.parent(); + } + return totalOffset; + } + + default void executeForAllSlots(int positionSlot, Consumer slotFunction) { + for (int i = 0; i < height(); i++) { + for (int j = 0; j < width(); j++) { + slotFunction.accept(positionSlot + j + i * (9 - width())); + } + } + } + +} diff --git a/src/main/java/com/wolfyscript/utilities/common/gui/ComponentBuilder.java b/src/main/java/com/wolfyscript/utilities/common/gui/ComponentBuilder.java new file mode 100644 index 000000000..acf83586c --- /dev/null +++ b/src/main/java/com/wolfyscript/utilities/common/gui/ComponentBuilder.java @@ -0,0 +1,65 @@ +/* + * WolfyUtilities, APIs and Utilities for Minecraft Spigot plugins + * Copyright (C) 2021 WolfyScript + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.wolfyscript.utilities.common.gui; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; +import com.fasterxml.jackson.annotation.JsonTypeInfo; +import com.fasterxml.jackson.databind.annotation.JsonTypeIdResolver; +import com.fasterxml.jackson.databind.annotation.JsonTypeResolver; +import com.wolfyscript.utilities.Keyed; +import com.wolfyscript.utilities.NamespacedKey; +import com.wolfyscript.utilities.common.gui.signal.Signal; +import com.wolfyscript.utilities.json.KeyedTypeIdResolver; +import com.wolfyscript.utilities.json.KeyedTypeResolver; + +import java.util.List; +import java.util.Set; + + +@JsonTypeResolver(KeyedTypeResolver.class) +@JsonTypeIdResolver(KeyedTypeIdResolver.class) +@JsonTypeInfo(use = JsonTypeInfo.Id.CUSTOM, include = JsonTypeInfo.As.EXISTING_PROPERTY, property = "type") +@JsonPropertyOrder(value = { "type" }) +@JsonIgnoreProperties(ignoreUnknown = true) +public interface ComponentBuilder extends Keyed { + + @JsonIgnore + @Override + NamespacedKey getNamespacedKey(); + + default NamespacedKey getType() { + return getNamespacedKey(); + } + + String id(); + + Position position(); + + /** + * Gets the signals that this component builder uses inside the parent construction consumer. + * + * @return The signals used in this builder. + */ + Set> signals(); + + COMPONENT create(PARENT parent); + +} diff --git a/src/main/java/com/wolfyscript/utilities/common/gui/ComponentBuilderSettings.java b/src/main/java/com/wolfyscript/utilities/common/gui/ComponentBuilderSettings.java new file mode 100644 index 000000000..115a19d7e --- /dev/null +++ b/src/main/java/com/wolfyscript/utilities/common/gui/ComponentBuilderSettings.java @@ -0,0 +1,34 @@ +/* + * WolfyUtilities, APIs and Utilities for Minecraft Spigot plugins + * Copyright (C) 2021 WolfyScript + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.wolfyscript.utilities.common.gui; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.TYPE) +public @interface ComponentBuilderSettings { + + Class component(); + + Class> base(); + +} diff --git a/src/main/java/com/wolfyscript/utilities/common/gui/GUIDragInteractionDetails.java b/src/main/java/com/wolfyscript/utilities/common/gui/DragInteractionDetails.java similarity index 69% rename from src/main/java/com/wolfyscript/utilities/common/gui/GUIDragInteractionDetails.java rename to src/main/java/com/wolfyscript/utilities/common/gui/DragInteractionDetails.java index ba089c767..7000a5185 100644 --- a/src/main/java/com/wolfyscript/utilities/common/gui/GUIDragInteractionDetails.java +++ b/src/main/java/com/wolfyscript/utilities/common/gui/DragInteractionDetails.java @@ -2,7 +2,7 @@ import java.util.Set; -public interface GUIDragInteractionDetails extends GUIInteractionDetails { +public interface DragInteractionDetails extends InteractionDetails { Set getInventorySlots(); diff --git a/src/main/java/com/wolfyscript/utilities/common/gui/DynamicConstructor.java b/src/main/java/com/wolfyscript/utilities/common/gui/DynamicConstructor.java new file mode 100644 index 000000000..73e9c4022 --- /dev/null +++ b/src/main/java/com/wolfyscript/utilities/common/gui/DynamicConstructor.java @@ -0,0 +1,37 @@ +/* + * WolfyUtilities, APIs and Utilities for Minecraft Spigot plugins + * Copyright (C) 2021 WolfyScript + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.wolfyscript.utilities.common.gui; + +import com.wolfyscript.utilities.common.gui.signal.Signal; +import com.wolfyscript.utilities.common.gui.signal.Store; + +import java.util.function.Consumer; +import java.util.function.Supplier; + +public interface DynamicConstructor { + + GuiViewManager viewManager(); + + GuiHolder holder(); + + Signal signal(String key, Class type, Supplier defaultValueFunction); + + Store syncStore(String key, Class type, Supplier getValue, Consumer setValue); + +} diff --git a/src/main/java/com/wolfyscript/utilities/common/gui/GUIInteractionDetails.java b/src/main/java/com/wolfyscript/utilities/common/gui/GUIInteractionDetails.java deleted file mode 100644 index 7e43063b0..000000000 --- a/src/main/java/com/wolfyscript/utilities/common/gui/GUIInteractionDetails.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.wolfyscript.utilities.common.gui; - -public interface GUIInteractionDetails { - - boolean isCancelled(); - - ButtonInteractionResult.ResultType getResultType(); - -} diff --git a/src/main/java/com/wolfyscript/utilities/common/gui/GuiAPIManager.java b/src/main/java/com/wolfyscript/utilities/common/gui/GuiAPIManager.java new file mode 100644 index 000000000..91b8c7823 --- /dev/null +++ b/src/main/java/com/wolfyscript/utilities/common/gui/GuiAPIManager.java @@ -0,0 +1,82 @@ +/* + * WolfyUtilities, APIs and Utilities for Minecraft Spigot plugins + * Copyright (C) 2021 WolfyScript + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.wolfyscript.utilities.common.gui; + +import java.util.Optional; +import java.util.UUID; +import java.util.function.Consumer; +import java.util.stream.Stream; + +/** + * Handles the general GUI API and acts as an entry point to the whole creation of {@link Router}s and {@link GuiViewManager}s.
+ * It stores all the registered {@link Router}s and allows to register new clusters via builders.
+ * Additionally, it stores the {@link GuiViewManager}s that handle the views for players. + */ +public interface GuiAPIManager { + + /** + * Registers a new router under the given id.
+ * The builder consumer provides the newly constructed {@link RouterBuilder}, which can then be used inside that consumer.
+ * + * @param id The unique id of the router to register. + * @param routerBuilderConsumer The consumer that provides the new builder. + */ + void registerGui(String guiID, Consumer routerBuilderConsumer); + + /** + * Registers a new router that it loads from the specified gui data directory. + * The consumer function provides that newly constructed {@link RouterBuilder}, which can be used to manipulate the builder. + * + * @param id The unique id of the router to register. + * @param routerBuilderConsumer The function to manipulate the new builder. + */ + void registerGuiFromFiles(String guiID, Consumer routerBuilderConsumer); + + /** + * Gets the registered router with the specified id.
+ * + * @param id The id of the router. + * @return The registered router only if the id matches; otherwise empty Optional. + */ + Optional getGui(String id); + + /** + * Creates a new view for the specified viewers, with the specified cluster as its root.
+ * This gets the registered cluster using {@link #getGui(String)}. + * + * @param clusterId The id of the root cluster. + * @param viewers The viewers of this view. + * @return The newly created view. + */ + GuiViewManager createView(String guiId, UUID... viewers); + + /** + * Same as {@link #createView(String, UUID...)} and opens the entry menu right after the creation of the view. + * + * @param clusterID The id of the root cluster. + * @param viewers The viewers of this view. + * @return The newly created view. + */ + GuiViewManager createViewAndOpen(String guiID, UUID... viewers); + + Stream getViewManagersFor(UUID uuid); + + Stream getViewManagersFor(UUID uuid, String guiID); + +} diff --git a/src/main/java/com/wolfyscript/utilities/common/gui/GuiAPIManagerCommonImpl.java b/src/main/java/com/wolfyscript/utilities/common/gui/GuiAPIManagerCommonImpl.java new file mode 100644 index 000000000..9f4041665 --- /dev/null +++ b/src/main/java/com/wolfyscript/utilities/common/gui/GuiAPIManagerCommonImpl.java @@ -0,0 +1,53 @@ +/* + * WolfyUtilities, APIs and Utilities for Minecraft Spigot plugins + * Copyright (C) 2021 WolfyScript + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.wolfyscript.utilities.common.gui; + +import com.google.common.base.Preconditions; +import com.google.common.collect.BiMap; +import com.google.common.collect.HashBiMap; +import com.wolfyscript.utilities.common.WolfyUtils; +import java.util.Optional; +import java.util.UUID; + +public abstract class GuiAPIManagerCommonImpl implements GuiAPIManager { + + protected final WolfyUtils wolfyUtils; + private final BiMap clustersMap = HashBiMap.create(); + + public GuiAPIManagerCommonImpl(WolfyUtils wolfyUtils) { + this.wolfyUtils = wolfyUtils; + } + + protected void registerGui(String id, Router router) { + Preconditions.checkArgument(!clustersMap.containsKey(router.getID()), "A cluster with the id '" + router.getID() + "' is already registered!"); + clustersMap.put(id, router); + } + + @Override + public GuiViewManager createViewAndOpen(String guiId, UUID... players) { + GuiViewManager handler = createView(guiId, players); + handler.openNew(); + return handler; + } + + @Override + public Optional getGui(String id) { + return Optional.ofNullable(clustersMap.get(id)); + } +} diff --git a/src/main/java/com/wolfyscript/utilities/common/gui/GuiHolder.java b/src/main/java/com/wolfyscript/utilities/common/gui/GuiHolder.java new file mode 100644 index 000000000..994f37257 --- /dev/null +++ b/src/main/java/com/wolfyscript/utilities/common/gui/GuiHolder.java @@ -0,0 +1,31 @@ +/* + * WolfyUtilities, APIs and Utilities for Minecraft Spigot plugins + * Copyright (C) 2021 WolfyScript + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.wolfyscript.utilities.common.gui; + +import com.wolfyscript.utilities.common.adapters.Player; + +public interface GuiHolder { + + GuiViewManager getViewManager(); + + Player getPlayer(); + + Window getCurrentWindow(); + +} diff --git a/src/main/java/com/wolfyscript/utilities/common/gui/GuiHolderCommonImpl.java b/src/main/java/com/wolfyscript/utilities/common/gui/GuiHolderCommonImpl.java new file mode 100644 index 000000000..1718520f4 --- /dev/null +++ b/src/main/java/com/wolfyscript/utilities/common/gui/GuiHolderCommonImpl.java @@ -0,0 +1,40 @@ +/* + * WolfyUtilities, APIs and Utilities for Minecraft Spigot plugins + * Copyright (C) 2021 WolfyScript + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.wolfyscript.utilities.common.gui; + +public abstract class GuiHolderCommonImpl implements GuiHolder { + + protected final Window currentWindow; + protected final GuiViewManager viewManager; + + public GuiHolderCommonImpl(Window currentWindow, GuiViewManager viewManager) { + this.currentWindow = currentWindow; + this.viewManager = viewManager; + } + + @Override + public Window getCurrentWindow() { + return currentWindow; + } + + @Override + public GuiViewManager getViewManager() { + return viewManager; + } +} diff --git a/src/main/java/com/wolfyscript/utilities/common/gui/GuiViewManager.java b/src/main/java/com/wolfyscript/utilities/common/gui/GuiViewManager.java new file mode 100644 index 000000000..af31f0953 --- /dev/null +++ b/src/main/java/com/wolfyscript/utilities/common/gui/GuiViewManager.java @@ -0,0 +1,101 @@ +/* + * WolfyUtilities, APIs and Utilities for Minecraft Spigot plugins + * Copyright (C) 2021 WolfyScript + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.wolfyscript.utilities.common.gui; + +import com.wolfyscript.utilities.common.WolfyUtils; +import com.wolfyscript.utilities.common.gui.callback.TextInputCallback; +import com.wolfyscript.utilities.common.gui.callback.TextInputTabCompleteCallback; + +import java.util.Optional; +import java.util.Set; +import java.util.UUID; + +/** + * The GuiViewManager, as the name suggests, manages a view of the GUI for one or more players.
+ * It contains the custom Data object that stores all the required data of this view.
+ * + * The view is immutable, so you need to create a new view each time you need to add a viewer or change the root. + * + */ +public interface GuiViewManager { + + /** + * Opens a new menu under the specific path. + * When the component at the specified path cannot be rendered (is not a window) it'll use the entry of that component. + * + * @param path The path to the menu to open. + */ + void openNew(String... path); + + /** + * Opens the entry menu of this root cluster. + */ + void openNew(); + + /** + * Opens the currently active menu without updating the history.
+ * In case there is no active menu it opens the entry of the root cluster. + */ + void open(); + + /** + * Goes back to the previously opened menu and opens it. + */ + void openPrevious(); + + /** + * The router of this view manager. + * + * @return The root cluster of this view manager. + */ + Router getRouter(); + + /** + * Gets the currently active menu. + * + * @return The currently active menu. + */ + Optional getCurrentMenu(); + + /** + * Gets the viewers that are handled by this view manager. + * When using these UUIDS, make sure the associated player is actually online! + * + * @return A Set of the viewers, that are handled by this manager. + */ + Set getViewers(); + + /** + * The API instance this manager belongs to. + * + * @return The API instance of this manager. + */ + WolfyUtils getWolfyUtils(); + + Optional getRenderContext(UUID viewer); + + Optional textInputCallback(); + + void setTextInputCallback(TextInputCallback inputCallback); + + Optional textInputTabCompleteCallback(); + + void setTextInputTabCompleteCallback(TextInputTabCompleteCallback textInputTabCompleteCallback); + +} diff --git a/src/main/java/com/wolfyscript/utilities/common/gui/GuiViewManagerCommonImpl.java b/src/main/java/com/wolfyscript/utilities/common/gui/GuiViewManagerCommonImpl.java new file mode 100644 index 000000000..e8495b6be --- /dev/null +++ b/src/main/java/com/wolfyscript/utilities/common/gui/GuiViewManagerCommonImpl.java @@ -0,0 +1,103 @@ +/* + * WolfyUtilities, APIs and Utilities for Minecraft Spigot plugins + * Copyright (C) 2021 WolfyScript + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.wolfyscript.utilities.common.gui; + +import com.google.inject.Guice; +import com.google.inject.Injector; +import com.google.inject.TypeLiteral; +import com.wolfyscript.utilities.common.WolfyUtils; +import java.util.ArrayDeque; +import java.util.Deque; +import java.util.Optional; +import java.util.Set; +import java.util.UUID; + +public abstract class GuiViewManagerCommonImpl implements GuiViewManager { + + private final WolfyUtils wolfyUtils; + private final Router router; + private Window currentRoot; + private final Deque history; + private final Set viewers; + + protected GuiViewManagerCommonImpl(WolfyUtils wolfyUtils, Router router, Set viewers) { + this.wolfyUtils = wolfyUtils; + this.router = router; + + this.history = new ArrayDeque<>(); + this.viewers = viewers; + // Construct custom data instance + Injector injector = Guice.createInjector(binder -> { + binder.bind(WolfyUtils.class).toInstance(wolfyUtils); + binder.bind(Router.class).toInstance(router); + binder.bind(new TypeLiteral() { + }).toInstance(this); + binder.bind(new TypeLiteral>() { + }).toInstance(viewers); + }); + } + + @Override + public void openNew() { + openNew(new String[0]); + } + + @Override + public void open() { + if (history.isEmpty()) { + openNew(); + } else { + getCurrentMenu().ifPresent(window -> window.open(this)); + } + } + + @Override + public void openPrevious() { + history.poll(); // Remove active current menu + setCurrentRoot(history.peek()); + getCurrentMenu().ifPresent(previous -> { + // Do not add menu to history, as it is already available + previous.open(this); + }); + } + + public void setCurrentRoot(Window currentRoot) { + this.currentRoot = currentRoot; + } + + @Override + public Optional getCurrentMenu() { + return Optional.ofNullable(currentRoot); + } + + @Override + public WolfyUtils getWolfyUtils() { + return wolfyUtils; + } + + @Override + public Router getRouter() { + return router; + } + + @Override + public Set getViewers() { + return Set.copyOf(viewers); + } +} diff --git a/src/main/java/com/wolfyscript/utilities/common/gui/Interactable.java b/src/main/java/com/wolfyscript/utilities/common/gui/Interactable.java new file mode 100644 index 000000000..7e99ee643 --- /dev/null +++ b/src/main/java/com/wolfyscript/utilities/common/gui/Interactable.java @@ -0,0 +1,46 @@ +/* + * WolfyUtilities, APIs and Utilities for Minecraft Spigot plugins + * Copyright (C) 2021 WolfyScript + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.wolfyscript.utilities.common.gui; + +import com.wolfyscript.utilities.common.gui.callback.InteractionCallback; + +public interface Interactable { + + /** + * Called when an interaction occurs inside the Component.
+ * This may be called if a child Component is interacted with, for example a Button will cause this interaction to
+ * propagate from the root Cluster, down the Windows to the Button that caused the interaction to be called.
+ *
+ * For this behaviour any implementation must first call the parent interaction, before continuing.
+ * Only if there is no parent available (root Component) it continues, going back to the interaction cause.
+ * + * @param holder The holder that caused the interaction. + * @param interactionDetails The details about the interaction. + * @return The interaction result. + */ + InteractionResult interact(GuiHolder holder, InteractionDetails interactionDetails); + + /** + * Called whenever an interaction occurs.
+ * This propagates from the root Component to the Component that caused the interaction. + * + * @return The interaction callback + */ + InteractionCallback interactCallback(); +} diff --git a/src/main/java/com/wolfyscript/utilities/common/gui/InteractionDetails.java b/src/main/java/com/wolfyscript/utilities/common/gui/InteractionDetails.java new file mode 100644 index 000000000..79218c734 --- /dev/null +++ b/src/main/java/com/wolfyscript/utilities/common/gui/InteractionDetails.java @@ -0,0 +1,10 @@ +package com.wolfyscript.utilities.common.gui; + +public interface InteractionDetails { + + boolean isCancelled(); + + InteractionResult.ResultType getResultType(); + + +} diff --git a/src/main/java/com/wolfyscript/utilities/common/gui/ButtonInteractionResult.java b/src/main/java/com/wolfyscript/utilities/common/gui/InteractionResult.java similarity index 72% rename from src/main/java/com/wolfyscript/utilities/common/gui/ButtonInteractionResult.java rename to src/main/java/com/wolfyscript/utilities/common/gui/InteractionResult.java index b83dd7851..667bb3a20 100644 --- a/src/main/java/com/wolfyscript/utilities/common/gui/ButtonInteractionResult.java +++ b/src/main/java/com/wolfyscript/utilities/common/gui/InteractionResult.java @@ -1,14 +1,14 @@ package com.wolfyscript.utilities.common.gui; -public class ButtonInteractionResult { +public class InteractionResult { private ResultType type; - ButtonInteractionResult() { + InteractionResult() { type = ResultType.DEFAULT; } - ButtonInteractionResult(ResultType type) { + InteractionResult(ResultType type) { this.type = type; } @@ -28,18 +28,18 @@ public void setType(ResultType type) { this.type = type; } - public static ButtonInteractionResult cancel(boolean cancelled) { - ButtonInteractionResult result = new ButtonInteractionResult(); + public static InteractionResult cancel(boolean cancelled) { + InteractionResult result = new InteractionResult(); result.setCancelled(cancelled); return result; } - public static ButtonInteractionResult def() { - return new ButtonInteractionResult(); + public static InteractionResult def() { + return new InteractionResult(); } - public static ButtonInteractionResult type(ResultType type) { - return new ButtonInteractionResult(type); + public static InteractionResult type(ResultType type) { + return new InteractionResult(type); } public enum ResultType { diff --git a/src/main/java/com/wolfyscript/utilities/common/gui/NativeRendererModule.java b/src/main/java/com/wolfyscript/utilities/common/gui/NativeRendererModule.java new file mode 100644 index 000000000..5d750623e --- /dev/null +++ b/src/main/java/com/wolfyscript/utilities/common/gui/NativeRendererModule.java @@ -0,0 +1,29 @@ +/* + * WolfyUtilities, APIs and Utilities for Minecraft Spigot plugins + * Copyright (C) 2021 WolfyScript + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.wolfyscript.utilities.common.gui; + +import com.wolfyscript.utilities.common.items.ItemStackConfig; + +public interface NativeRendererModule { + + void renderStack(T_STACK stack); + + void renderStack(ItemStackConfig stackConfig); + +} diff --git a/src/main/java/com/wolfyscript/utilities/common/gui/Position.java b/src/main/java/com/wolfyscript/utilities/common/gui/Position.java new file mode 100644 index 000000000..567fbeb21 --- /dev/null +++ b/src/main/java/com/wolfyscript/utilities/common/gui/Position.java @@ -0,0 +1,108 @@ +/* + * WolfyUtilities, APIs and Utilities for Minecraft Spigot plugins + * Copyright (C) 2021 WolfyScript + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.wolfyscript.utilities.common.gui; + +import com.fasterxml.jackson.annotation.JsonAlias; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.core.JsonToken; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.wolfyscript.utilities.json.annotations.OptionalValueDeserializer; +import com.wolfyscript.utilities.json.annotations.OptionalValueSerializer; + +import java.io.IOException; + +@OptionalValueDeserializer(deserializer = Position.ValueDeserializer.class) +@OptionalValueSerializer(serializer = Position.ValueSerializer.class) +public class Position { + + private final Type type; + private final int slot; + + @JsonCreator + public Position(@JsonProperty("type") Type type, @JsonProperty("slot") int slot) { + this.type = type; + this.slot = slot; + } + + public Type type() { + return type; + } + + public int slot() { + return slot; + } + + public static Position relative(int slot) { + return new Position(Type.RELATIVE, slot); + } + + public static Position absolute(int slot) { + return new Position(Type.ABSOLUTE, slot); + } + + public enum Type { + /** + * Relative position with the parent component as the origin + */ + @JsonAlias("relative") + RELATIVE, + /** + * Absolute position with the Window as the origin + */ + @JsonAlias("absolute") + ABSOLUTE + } + + public static class ValueDeserializer extends com.wolfyscript.utilities.json.ValueDeserializer { + + public ValueDeserializer() { + super(Position.class); + } + + @Override + public Position deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException { + if (p.currentToken() == JsonToken.VALUE_NUMBER_INT) { + return Position.absolute(p.getIntValue()); + } + return Position.absolute(0); + } + } + + public static class ValueSerializer extends com.wolfyscript.utilities.json.ValueSerializer { + + public ValueSerializer() { + super(Position.class); + } + + @Override + public boolean serialize(Position targetObject, JsonGenerator generator, SerializerProvider provider) throws IOException { + if (targetObject.type() == Type.ABSOLUTE) { + generator.writeNumber(targetObject.slot()); + return true; + } + return false; + } + } + +} diff --git a/src/main/java/com/wolfyscript/utilities/common/gui/Positionable.java b/src/main/java/com/wolfyscript/utilities/common/gui/Positionable.java new file mode 100644 index 000000000..da853af5e --- /dev/null +++ b/src/main/java/com/wolfyscript/utilities/common/gui/Positionable.java @@ -0,0 +1,25 @@ +/* + * WolfyUtilities, APIs and Utilities for Minecraft Spigot plugins + * Copyright (C) 2021 WolfyScript + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.wolfyscript.utilities.common.gui; + +public interface Positionable { + + Position position(); + +} diff --git a/src/main/java/com/wolfyscript/utilities/common/gui/ReactiveRenderBuilder.java b/src/main/java/com/wolfyscript/utilities/common/gui/ReactiveRenderBuilder.java new file mode 100644 index 000000000..38de82c94 --- /dev/null +++ b/src/main/java/com/wolfyscript/utilities/common/gui/ReactiveRenderBuilder.java @@ -0,0 +1,35 @@ +/* + * WolfyUtilities, APIs and Utilities for Minecraft Spigot plugins + * Copyright (C) 2021 WolfyScript + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.wolfyscript.utilities.common.gui; + +import java.util.function.Consumer; + +public interface ReactiveRenderBuilder { + + > ReactiveResult render(String id, Class builderType, Consumer builderConsumer); + + > ReactiveResult renderAt(Position position, String id, Class builderType, Consumer builderConsumer); + + interface ReactiveResult { + + Component construct(); + + } + +} diff --git a/src/main/java/com/wolfyscript/utilities/common/gui/RenderContext.java b/src/main/java/com/wolfyscript/utilities/common/gui/RenderContext.java new file mode 100644 index 000000000..e87b4e327 --- /dev/null +++ b/src/main/java/com/wolfyscript/utilities/common/gui/RenderContext.java @@ -0,0 +1,54 @@ +/* + * WolfyUtilities, APIs and Utilities for Minecraft Spigot plugins + * Copyright (C) 2021 WolfyScript + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.wolfyscript.utilities.common.gui; + +import com.wolfyscript.utilities.common.items.ItemStackConfig; + +/** + * The data that contains all the information needed to render the Menu. + * + */ +public interface RenderContext { + + Component getCurrentComponent(); + + int currentOffset(); + + void setStack(int slot, ItemStackConfig stackConfig); + + void setNativeStack(int slot, Object nativeStack); + + default boolean checkIfSlotInBounds(int slot) { + int outerWidth; + int outerHeight; + if (getCurrentComponent().parent() != null) { + Component parent = getCurrentComponent().parent(); + outerWidth = parent.width(); + outerHeight = parent.height(); + } else { + outerWidth = 9; + outerHeight = 6; + } + if (slot >= 0 && slot < outerWidth * outerHeight) { + return true; + } + throw new IllegalArgumentException("Slot " + slot + " out of bounds! Must be in the range of [" + 0 + "..." + (outerWidth * outerHeight - 1) + "] !"); + } + +} diff --git a/src/main/java/com/wolfyscript/utilities/common/gui/Renderable.java b/src/main/java/com/wolfyscript/utilities/common/gui/Renderable.java new file mode 100644 index 000000000..5d0fe5740 --- /dev/null +++ b/src/main/java/com/wolfyscript/utilities/common/gui/Renderable.java @@ -0,0 +1,23 @@ +/* + * WolfyUtilities, APIs and Utilities for Minecraft Spigot plugins + * Copyright (C) 2021 WolfyScript + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.wolfyscript.utilities.common.gui; + +public interface Renderable { + +} diff --git a/src/main/java/com/wolfyscript/utilities/common/gui/Router.java b/src/main/java/com/wolfyscript/utilities/common/gui/Router.java new file mode 100644 index 000000000..2dec49d3f --- /dev/null +++ b/src/main/java/com/wolfyscript/utilities/common/gui/Router.java @@ -0,0 +1,56 @@ +/* + * WolfyUtilities, APIs and Utilities for Minecraft Spigot plugins + * Copyright (C) 2021 WolfyScript + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.wolfyscript.utilities.common.gui; + +import com.wolfyscript.utilities.common.WolfyUtils; +import java.util.Deque; +import java.util.Optional; +import java.util.UUID; + +/** + *

+ * The Cluster acts as a structure and root Component for Menus. + * It can have both other Clusters and Windows as children. + *

+ * The entry is used to define the default menu that is opened. + * + * @param The type of the data implementation. + */ +public interface Router extends Interactable { + + String getID(); + + WolfyUtils getWolfyUtils(); + + Router parent(); + + Optional getSubRoute(String routeID); + + Optional getWindow(); + + Window open(GuiViewManager viewManager, String... path); + + /** + * Opens this component for the specified view and player.
+ * + * @param viewManager The view manager to open. + * @param uuid The uuid to open the Window for. + */ + RenderContext createContext(GuiViewManager viewManager, Deque path, UUID uuid); +} diff --git a/src/main/java/com/wolfyscript/utilities/common/gui/RouterBuilder.java b/src/main/java/com/wolfyscript/utilities/common/gui/RouterBuilder.java new file mode 100644 index 000000000..d9f310c85 --- /dev/null +++ b/src/main/java/com/wolfyscript/utilities/common/gui/RouterBuilder.java @@ -0,0 +1,35 @@ +/* + * WolfyUtilities, APIs and Utilities for Minecraft Spigot plugins + * Copyright (C) 2021 WolfyScript + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.wolfyscript.utilities.common.gui; + +import com.wolfyscript.utilities.common.gui.callback.InteractionCallback; + +import java.util.function.Consumer; + +public interface RouterBuilder { + + RouterBuilder interact(InteractionCallback interactionCallback); + + RouterBuilder route(String path, Consumer subRouteBuilder); + + RouterBuilder window(Consumer windowBuilder); + + Router create(Router parent); + +} diff --git a/src/main/java/com/wolfyscript/utilities/common/gui/Signalable.java b/src/main/java/com/wolfyscript/utilities/common/gui/Signalable.java new file mode 100644 index 000000000..cdabb9ae0 --- /dev/null +++ b/src/main/java/com/wolfyscript/utilities/common/gui/Signalable.java @@ -0,0 +1,34 @@ +/* + * WolfyUtilities, APIs and Utilities for Minecraft Spigot plugins + * Copyright (C) 2021 WolfyScript + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.wolfyscript.utilities.common.gui; + +import com.wolfyscript.utilities.common.gui.signal.Signal; + +import java.util.Deque; +import java.util.Map; + +public interface Signalable { + + Map> getSignalValues(); + + Deque> updatedSignals(); + + void receiveUpdate(Signal signal); + +} diff --git a/src/main/java/com/wolfyscript/utilities/common/gui/SignalledObject.java b/src/main/java/com/wolfyscript/utilities/common/gui/SignalledObject.java new file mode 100644 index 000000000..4fd69f567 --- /dev/null +++ b/src/main/java/com/wolfyscript/utilities/common/gui/SignalledObject.java @@ -0,0 +1,7 @@ +package com.wolfyscript.utilities.common.gui; + +public interface SignalledObject { + + void update(GuiViewManager viewManager, GuiHolder guiHolder, RenderContext renderContext); + +} diff --git a/src/main/java/com/wolfyscript/utilities/common/gui/State.java b/src/main/java/com/wolfyscript/utilities/common/gui/State.java new file mode 100644 index 000000000..bcf7d8247 --- /dev/null +++ b/src/main/java/com/wolfyscript/utilities/common/gui/State.java @@ -0,0 +1,22 @@ +/* + * WolfyUtilities, APIs and Utilities for Minecraft Spigot plugins + * Copyright (C) 2021 WolfyScript + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.wolfyscript.utilities.common.gui; + +public interface State { +} diff --git a/src/main/java/com/wolfyscript/utilities/common/gui/StateSelector.java b/src/main/java/com/wolfyscript/utilities/common/gui/StateSelector.java new file mode 100644 index 000000000..e9a0c68af --- /dev/null +++ b/src/main/java/com/wolfyscript/utilities/common/gui/StateSelector.java @@ -0,0 +1,25 @@ +/* + * WolfyUtilities, APIs and Utilities for Minecraft Spigot plugins + * Copyright (C) 2021 WolfyScript + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.wolfyscript.utilities.common.gui; + +public interface StateSelector { + + int run(GuiHolder holder, Object data, Component component); + +} diff --git a/src/main/java/com/wolfyscript/utilities/common/gui/Window.java b/src/main/java/com/wolfyscript/utilities/common/gui/Window.java new file mode 100644 index 000000000..ab619ccc7 --- /dev/null +++ b/src/main/java/com/wolfyscript/utilities/common/gui/Window.java @@ -0,0 +1,146 @@ +/* + * WolfyUtilities, APIs and Utilities for Minecraft Spigot plugins + * Copyright (C) 2021 WolfyScript + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.wolfyscript.utilities.common.gui; + +import com.wolfyscript.utilities.common.WolfyUtils; +import java.util.Arrays; +import java.util.Optional; +import java.util.Set; +import java.util.UUID; +import java.util.function.Consumer; + +public interface Window extends Interactable, Renderable { + + /** + * Creates the context of this window. The context keeps track of the inventory + * and view for the rendering. + * + * @param viewManager The view manager to open. + * @param uuid The uuid to open the Window for. + */ + RenderContext createContext(GuiViewManager viewManager, UUID uuid); + + void open(GuiViewManager viewManager); + + Window construct(GuiHolder holder, GuiViewManager viewManager); + + void render(GuiHolder holder, GuiViewManager viewManager, RenderContext context); + + /** + * Gets the type that is configured for this Window.
+ * When this is empty, then {@link #getSize()} will return the specified size. + * + * @return The specified type; or empty Optional when no type is configured. + * @see #getSize() + */ + Optional getType(); + + /** + * Gets the size that is configured for this Window.
+ * + * When this is empty, then {@link #getType()} will return the specified type. + * + * @return The specified size: or empty Optional when no size is configured. + */ + Optional getSize(); + + /** + * Creates the title of this window for the specified holder. + * + * @param holder The holder to create the title for. + * @return The title component. + */ + net.kyori.adventure.text.Component createTitle(GuiHolder holder); + + /** + * The children of this Component; or an empty Set if there are no children. + * + * @return The child Components of this Component. + */ + Set childComponents(); + + /** + * Gets the child at the relative path from this Component.
+ * When the path is null or empty then it returns this Component instead. + * + * @param path The path to the child Component. + * @return The child at the specified path; or this Component when the path is null or empty. + */ + default Optional getChild(String... path) { + if (path == null || path.length == 0) return Optional.empty(); + return getChild(path[0]).flatMap(component -> { + if (component instanceof Window window) { + return window.getChild(Arrays.copyOfRange(path, 1, path.length)); + } + return Optional.empty(); + }); + } + + /** + * Gets the direct child Component, or an empty Optional when it wasn't found. + * + * @param id The id of the child Component. + * @return The child Component; or empty Component. + */ + Optional getChild(String id); + + /** + * Gets the unique id (in context of the parent) of this component. + * + * @return The id of this component. + */ + String getID(); + + /** + * Gets the global WolfyUtils instance, this component belongs to. + * + * @return The WolfyUtils API instance. + */ + WolfyUtils getWolfyUtils(); + + /** + * The parent of this Component, or null if it is a root Component. + * + * @return The parent; or null if root Component. + */ + Router router(); + + /** + * Gets the width of this Component in slot count. + * + * @return The width in slots. + */ + int width(); + + /** + * Gets the width of this Component in slot count. + * + * @return The height in slots. + */ + int height(); + + default void executeForAllSlots(int positionSlot, Consumer slotFunction) { + for (int i = 0; i < height(); i++) { + for (int j = 0; j < width(); j++) { + slotFunction.accept(positionSlot + j + i * (9 - width())); + } + } + } + +} diff --git a/src/main/java/com/wolfyscript/utilities/common/gui/WindowBuilder.java b/src/main/java/com/wolfyscript/utilities/common/gui/WindowBuilder.java new file mode 100644 index 000000000..e55653ecc --- /dev/null +++ b/src/main/java/com/wolfyscript/utilities/common/gui/WindowBuilder.java @@ -0,0 +1,148 @@ +/* + * WolfyUtilities, APIs and Utilities for Minecraft Spigot plugins + * Copyright (C) 2021 WolfyScript + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.wolfyscript.utilities.common.gui; + +import com.wolfyscript.utilities.common.gui.callback.InteractionCallback; +import com.wolfyscript.utilities.common.gui.functions.SerializableConsumer; +import com.wolfyscript.utilities.json.annotations.KeyedBaseType; +import java.util.function.Consumer; +import org.jetbrains.annotations.Nullable; + +/** + * Builder used to create Window Menus.
+ * + */ +@KeyedBaseType(baseType = ComponentBuilder.class) +public interface WindowBuilder { + + /** + * The size of the inventory.
+ * This only applies when the type is not specified.
+ * Either the type or size must be specified! + * + * @param size The size of the inventory. + * @return This builder to allow chaining the methods. + */ + WindowBuilder size(int size); + + /** + * The type of the inventory.
+ * When the type is specified the size is ignored.
+ * Either the type or size must be specified! + * + * @param type + * @return This builder to allow chaining the methods. + */ + WindowBuilder type(@Nullable WindowType type); + + /** + *

+ * The implementation may work different across platforms.
+ * On plain Spigot servers, the titles do not support all components inside inventory titles, like fonts.
+ * Paper fully supports all Components inside inventory titles. + *

+ * + * @return This builder to allow chaining the methods + */ + WindowBuilder title(String staticTitle); + + WindowBuilder interact(InteractionCallback interactionCallback); + + /** + * Specifies the constructor callback, that is called right before the component is created. + * + * @param render The consumer to configure the renderer + * @return This builder for chaining + */ + WindowBuilder construct(Consumer render); + + /** + *

+ * Initializes the specified component with the given id at the given slot.
+ * The component won't yet be constructed nor rendered! + *

+ * This is useful if the component has some static parts that are non-reactive.
+ * This is used when loading the components from the config files (.conf)
+ * They can then be extended and rendered inside the {@link #construct(Consumer)} callback. + *

+ *

+ *

+ * In case you need to have reactive components, create them inside the {@link #construct(Consumer)} callback. + *

+ * @param id The id of the component to render + * @param builderType The type of the builder to use + * @param builderConsumer The consumer to configure the builder + * @return This Builder for chaining + * @param The type of the component builder + */ + > WindowBuilder init(Position position, String id, Class builderType, SerializableConsumer builderConsumer); + + /** + *

+ * Renders the specified static component with the given id. + *

+ *

+ * Static components are constructed directly and are not recreated per {@link GuiViewManager}. + * Therefor they improve performance, as they are only created once.
+ * Static components cannot use signals! + *

+ *

+ * In case you need to have reactive components, create them inside the {@link #construct(Consumer)} callback. + *

+ * @param id The id of the component to render + * @param builderType The type of the builder to use + * @param builderConsumer The consumer to configure the builder + * @return This Builder for chaining + * @param The type of the component builder + */ + > WindowBuilder render(String id, Class builderType, SerializableConsumer builderConsumer); + + /** + *

+ * Initializes the specified component with the given id at the given slot, and renders it statically.
+ * It basically combines
+ * {@link #init(Position, String, Class, SerializableConsumer)} and
+ * {@link #render(String, Class, SerializableConsumer)}
+ * + *

+ * This is only really useful if you need to define positions of components in code.
+ * Usually you should use the config files (.conf), to specify slots. + *

+ *

+ *

+ * Static components are constructed directly and are not recreated per {@link GuiViewManager}. + * Therefor they improve performance, as they are only created once.
+ * Static components cannot use signals! + *

+ *

+ * In case you need to have reactive components, create them inside the {@link #construct(Consumer)} callback. + *

+ * + * @param position + * @param id + * @param builderType + * @param builderConsumer + * @return + * @param + */ + > WindowBuilder renderAt(Position position, String id, Class builderType, SerializableConsumer builderConsumer); + + Window create(Router parent); + +} diff --git a/src/main/java/com/wolfyscript/utilities/common/gui/WindowDynamicConstructor.java b/src/main/java/com/wolfyscript/utilities/common/gui/WindowDynamicConstructor.java new file mode 100644 index 000000000..ec0f5b79f --- /dev/null +++ b/src/main/java/com/wolfyscript/utilities/common/gui/WindowDynamicConstructor.java @@ -0,0 +1,122 @@ +/* + * WolfyUtilities, APIs and Utilities for Minecraft Spigot plugins + * Copyright (C) 2021 WolfyScript + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.wolfyscript.utilities.common.gui; + +import com.wolfyscript.utilities.common.gui.functions.SerializableConsumer; +import com.wolfyscript.utilities.common.gui.functions.SerializableFunction; +import com.wolfyscript.utilities.common.gui.functions.SerializableSupplier; +import com.wolfyscript.utilities.common.gui.signal.Signal; + +import java.util.function.Consumer; + +public interface WindowDynamicConstructor extends DynamicConstructor { + + /** + * Specify a dynamic custom title supplier that is used to update the title of the Inventory.
+ *

+ * Any signal used inside the supplier will cause it to update when the signal is updated. + *

+ * + * @param titleSupplier The supplier that provides the new title of the inventory + * @return This builder for chaining + */ + WindowDynamicConstructor title(SerializableSupplier titleSupplier); + + /** + * When no dynamic title is used (see {@link #title(SerializableSupplier)}), then this method can be used to + * create placeholder resolvers for the static title. The static title can be specified using {@link WindowBuilder#title(String)}. + *

+ * The title is updated whenever any of the specified signals are updated. + *

+ * + *

+ * The placeholder will be equal to the key of the signal.
+ * e.g.
+ *

createSignal("count", () -> 0)
will provide a placeholder
<count>
+ * + *

+ * + * @param signals The signals to use as placeholders + * @return This builder for chaining + */ + WindowDynamicConstructor titleSignals(Signal... signals); + + /** + *

+ * Constructs a reactive function to dynamically render components.
+ * This is only recommended for complex methods, like if switches are required.
+ * If a simple condition is enough {@link #renderWhen(SerializableSupplier, String, Class, SerializableConsumer)} should be used instead! + *

+ *

+ * The callback is updated whenever a signal used inside it is updated. + *

+ * + * @param reactiveFunction The function to run on signal updates. + * @return This builder for chaining. + */ + WindowDynamicConstructor reactive(SerializableFunction reactiveFunction); + + /** + *

+ * Renders the specified component whenever the condition is met.
+ * Any signal used inside the condition will cause it to update when the signal is updated. + *

+ *

+ * The specified component is constructed upon invocation of this method and simply rendered/removed whenever the condition changes.
+ * Further updates to the components need to be handled by using signals. + *

+ * + * @param condition The condition that is reactive to signals used inside it. + * @param id The id of the component to render. + * @param builderType The type of builder to use. + * @param builderConsumer The consumer to configure the builder. + * @param The type of the Component Builder + * @return This builder for chaining + */ + > WindowDynamicConstructor renderWhen(SerializableSupplier condition, String id, Class builderType, SerializableConsumer builderConsumer); + + , BI extends ComponentBuilder> WindowDynamicConstructor renderWhenElse(SerializableSupplier condition, Class builderValidType, Consumer builderValidConsumer, Class builderInvalidType, SerializableConsumer builderInvalidConsumer); + + /** + * + * + * @param slot + * @param id + * @param builderType + * @param builderConsumer + * @return + * @param + */ + > WindowDynamicConstructor position(Position position, String id, Class builderType, SerializableConsumer builderConsumer); + + /** + *

+ * Renders the specified component with the given id. + *

+ * + * @param id The id of the component to render + * @param builderType The type of the builder to use + * @param builderConsumer The consumer to configure the builder + * @param The type of the component builder + * @return This Builder for chaining + */ + > WindowDynamicConstructor render(String id, Class builderType, SerializableConsumer builderConsumer); + + > WindowDynamicConstructor renderAt(Position position, String id, Class builderType, SerializableConsumer builderConsumer); +} diff --git a/src/main/java/com/wolfyscript/utilities/common/gui/WindowType.java b/src/main/java/com/wolfyscript/utilities/common/gui/WindowType.java new file mode 100644 index 000000000..83c621c56 --- /dev/null +++ b/src/main/java/com/wolfyscript/utilities/common/gui/WindowType.java @@ -0,0 +1,28 @@ +/* + * WolfyUtilities, APIs and Utilities for Minecraft Spigot plugins + * Copyright (C) 2021 WolfyScript + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.wolfyscript.utilities.common.gui; + +public enum WindowType { + + CUSTOM, + DISPENSER, + DROPPER, + HOPPER + +} diff --git a/src/main/java/com/wolfyscript/utilities/common/gui/callback/InteractionCallback.java b/src/main/java/com/wolfyscript/utilities/common/gui/callback/InteractionCallback.java new file mode 100644 index 000000000..ccb78e1ce --- /dev/null +++ b/src/main/java/com/wolfyscript/utilities/common/gui/callback/InteractionCallback.java @@ -0,0 +1,30 @@ +/* + * WolfyUtilities, APIs and Utilities for Minecraft Spigot plugins + * Copyright (C) 2021 WolfyScript + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.wolfyscript.utilities.common.gui.callback; + +import com.wolfyscript.utilities.common.gui.GuiHolder; +import com.wolfyscript.utilities.common.gui.InteractionDetails; +import com.wolfyscript.utilities.common.gui.InteractionResult; + +@FunctionalInterface +public interface InteractionCallback { + + InteractionResult interact(GuiHolder holder, InteractionDetails details); + +} diff --git a/src/main/java/com/wolfyscript/utilities/common/gui/callback/RenderCallback.java b/src/main/java/com/wolfyscript/utilities/common/gui/callback/RenderCallback.java new file mode 100644 index 000000000..1b1c3b33a --- /dev/null +++ b/src/main/java/com/wolfyscript/utilities/common/gui/callback/RenderCallback.java @@ -0,0 +1,28 @@ +/* + * WolfyUtilities, APIs and Utilities for Minecraft Spigot plugins + * Copyright (C) 2021 WolfyScript + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.wolfyscript.utilities.common.gui.callback; + +import com.wolfyscript.utilities.common.gui.GuiHolder; + +@FunctionalInterface +public interface RenderCallback { + + void render(GuiHolder holder); + +} diff --git a/src/main/java/com/wolfyscript/utilities/common/gui/callback/TextInputCallback.java b/src/main/java/com/wolfyscript/utilities/common/gui/callback/TextInputCallback.java new file mode 100644 index 000000000..1a363069c --- /dev/null +++ b/src/main/java/com/wolfyscript/utilities/common/gui/callback/TextInputCallback.java @@ -0,0 +1,28 @@ +/* + * WolfyUtilities, APIs and Utilities for Minecraft Spigot plugins + * Copyright (C) 2021 WolfyScript + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.wolfyscript.utilities.common.gui.callback; + +import com.wolfyscript.utilities.common.adapters.Player; +import com.wolfyscript.utilities.common.gui.GuiViewManager; + +public interface TextInputCallback { + + boolean run(Player player, GuiViewManager viewManager, String input, String[] args); + +} diff --git a/src/main/java/com/wolfyscript/utilities/common/gui/callback/TextInputTabCompleteCallback.java b/src/main/java/com/wolfyscript/utilities/common/gui/callback/TextInputTabCompleteCallback.java new file mode 100644 index 000000000..3434290fb --- /dev/null +++ b/src/main/java/com/wolfyscript/utilities/common/gui/callback/TextInputTabCompleteCallback.java @@ -0,0 +1,30 @@ +/* + * WolfyUtilities, APIs and Utilities for Minecraft Spigot plugins + * Copyright (C) 2021 WolfyScript + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.wolfyscript.utilities.common.gui.callback; + +import com.wolfyscript.utilities.common.adapters.Player; +import com.wolfyscript.utilities.common.gui.GuiViewManager; + +import java.util.List; + +public interface TextInputTabCompleteCallback { + + List apply(Player player, GuiViewManager viewManager, String input, String[] args); + +} diff --git a/src/main/java/com/wolfyscript/utilities/common/gui/components/Button.java b/src/main/java/com/wolfyscript/utilities/common/gui/components/Button.java new file mode 100644 index 000000000..c663eaa1b --- /dev/null +++ b/src/main/java/com/wolfyscript/utilities/common/gui/components/Button.java @@ -0,0 +1,43 @@ +/* + * WolfyUtilities, APIs and Utilities for Minecraft Spigot plugins + * Copyright (C) 2021 WolfyScript + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.wolfyscript.utilities.common.gui.components; + +import com.wolfyscript.utilities.common.gui.Component; +import com.wolfyscript.utilities.common.gui.Interactable; +import com.wolfyscript.utilities.common.gui.Positionable; + +/** + * A simple button that has an icon (ItemStack) and an interaction callback. + * It always has a 1x1 size, because it occupies a single slot. + * + */ +public interface Button extends Component, Interactable, Positionable { + + @Override + default int width() { + return 1; + } + + @Override + default int height() { + return 1; + } + + ButtonIcon icon(); +} diff --git a/src/main/java/com/wolfyscript/utilities/common/gui/components/ButtonBuilder.java b/src/main/java/com/wolfyscript/utilities/common/gui/components/ButtonBuilder.java new file mode 100644 index 000000000..b0ad7772e --- /dev/null +++ b/src/main/java/com/wolfyscript/utilities/common/gui/components/ButtonBuilder.java @@ -0,0 +1,68 @@ +/* + * WolfyUtilities, APIs and Utilities for Minecraft Spigot plugins + * Copyright (C) 2021 WolfyScript + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.wolfyscript.utilities.common.gui.components; + +import com.wolfyscript.utilities.common.gui.*; +import com.wolfyscript.utilities.common.gui.callback.InteractionCallback; +import com.wolfyscript.utilities.common.gui.functions.SerializableSupplier; +import com.wolfyscript.utilities.common.gui.signal.Signal; +import com.wolfyscript.utilities.common.items.ItemStackConfig; +import net.kyori.adventure.sound.Sound; + +import java.util.Optional; +import java.util.function.Consumer; +import java.util.function.Function; + +/** + * Builder to create a {@link Button} instance. + * + */ +public interface ButtonBuilder extends ComponentBuilder { + + /** + * Creates a new {@link IconBuilder} to create the icon of the button. + * + * @param icon The consumer that provides the {@link IconBuilder} + * @return This builder instance for chaining. + */ + ButtonBuilder icon(Consumer icon); + + ButtonBuilder interact(InteractionCallback interactionCallback); + + ButtonBuilder sound(Function> soundFunction); + + Button create(Component parent); + + /** + * Provides methods to create an icon for Buttons. + * Dynamic icons are recreated each time the component is re-rendered, while static icons are just created once and then reused. + * By default, all icons are static to improve performance. + */ + interface IconBuilder { + + IconBuilder stack(ItemStackConfig stackConfig); + + IconBuilder stack(SerializableSupplier> stackConfigSupplier); + + IconBuilder updateOnSignals(Signal... signals); + + ButtonIcon create(); + } + +} diff --git a/src/main/java/com/wolfyscript/utilities/common/gui/components/ButtonIcon.java b/src/main/java/com/wolfyscript/utilities/common/gui/components/ButtonIcon.java new file mode 100644 index 000000000..6f538dfe8 --- /dev/null +++ b/src/main/java/com/wolfyscript/utilities/common/gui/components/ButtonIcon.java @@ -0,0 +1,31 @@ +/* + * WolfyUtilities, APIs and Utilities for Minecraft Spigot plugins + * Copyright (C) 2021 WolfyScript + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.wolfyscript.utilities.common.gui.components; + +import com.wolfyscript.utilities.common.items.ItemStackConfig; +import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver; + +public interface ButtonIcon { + + ItemStackConfig getStack(); + + TagResolver getResolvers(); + + +} diff --git a/src/main/java/com/wolfyscript/utilities/common/gui/components/ButtonState.java b/src/main/java/com/wolfyscript/utilities/common/gui/components/ButtonState.java new file mode 100644 index 000000000..f14f96fe1 --- /dev/null +++ b/src/main/java/com/wolfyscript/utilities/common/gui/components/ButtonState.java @@ -0,0 +1,91 @@ +/* + * WolfyUtilities, APIs and Utilities for Minecraft Spigot plugins + * Copyright (C) 2021 WolfyScript + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.wolfyscript.utilities.common.gui.components; + +import com.wolfyscript.utilities.common.gui.callback.InteractionCallback; +import com.wolfyscript.utilities.common.gui.callback.RenderCallback; +import com.wolfyscript.utilities.common.gui.StateSelector; + +/** + *

+ * The State represents a State of a Button, that handles the functionality of the Button.
+ * It provides several runtime callbacks that are called whenever an interaction or render request occurs. + *

+ *

+ * These States are used to draw the proper icons and textures of the GUI and handle the interactions and data manipulation. + *
+ * Buttons like ToggleButtons use two states, and can sync it to the provided state using the {@link StateSelector}. + *

+ */ +public interface ButtonState { + + /** + * The key of the state. This is mostly used for translations.
+ * By default, it is the same as the owner Component. + * But it can be different or a sub key from the owner key. + * + * @return The key of the state. + */ + String key(); + + /** + * Called whenever an interaction occurs.
+ * This propagates from the root Component to the Component that caused the interaction. + * + * @return The interaction callback + */ + InteractionCallback interactCallback(); + + /** + * Called each time the Component or a child Component is rendered in the GUI. + * + * + * @return + */ + RenderCallback renderCallback(); + + interface Builder { + + /** + * Specifies the sub key of the state relative to the owner key or previously specified key or subKey, separated by a dot ('.'). + * These keys are used as language keys to lookup translations in the lang files. + * + * @param subKey The sub key of this state. + * @return This Builder for chaining. + */ + Builder subKey(String subKey); + + /** + * Specifies the key of the state. + * These keys are used as language keys to lookup translations in the lang files. + * + * @param key The key of this state. + * @return This Builder for chaining. + */ + Builder key(String key); + + Builder interact(InteractionCallback interactionCallback); + + Builder render(RenderCallback renderCallback); + + S create(); + + } + +} diff --git a/src/main/java/com/wolfyscript/utilities/common/gui/components/ComponentCluster.java b/src/main/java/com/wolfyscript/utilities/common/gui/components/ComponentCluster.java new file mode 100644 index 000000000..9453b3b1c --- /dev/null +++ b/src/main/java/com/wolfyscript/utilities/common/gui/components/ComponentCluster.java @@ -0,0 +1,44 @@ +/* + * WolfyUtilities, APIs and Utilities for Minecraft Spigot plugins + * Copyright (C) 2021 WolfyScript + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.wolfyscript.utilities.common.gui.components; + +import com.wolfyscript.utilities.common.gui.Component; + +import java.util.Optional; +import java.util.Set; + +public interface ComponentCluster extends Component { + + /** + * The children of this Component; or an empty Set if there are no children. + * + * @return The child Components of this Component. + */ + Set childComponents(); + + /** + * Gets the direct child Component, or an empty Optional when it wasn't found. + * + * @param id The id of the child Component. + * @return The child Component; or empty Component. + */ + Optional getChild(String id); + + +} diff --git a/src/main/java/com/wolfyscript/utilities/common/gui/components/ComponentClusterBuilder.java b/src/main/java/com/wolfyscript/utilities/common/gui/components/ComponentClusterBuilder.java new file mode 100644 index 000000000..cd50c8849 --- /dev/null +++ b/src/main/java/com/wolfyscript/utilities/common/gui/components/ComponentClusterBuilder.java @@ -0,0 +1,33 @@ +/* + * WolfyUtilities, APIs and Utilities for Minecraft Spigot plugins + * Copyright (C) 2021 WolfyScript + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.wolfyscript.utilities.common.gui.components; + +import com.wolfyscript.utilities.common.gui.Component; +import com.wolfyscript.utilities.common.gui.ComponentBuilder; +import com.wolfyscript.utilities.common.gui.Position; + +import java.util.function.Consumer; + +public interface ComponentClusterBuilder extends ComponentBuilder { + + > ComponentClusterBuilder render(String id, Class builderType, Consumer builderConsumer); + + > ComponentClusterBuilder renderAt(Position position, String id, Class builderType, Consumer builderConsumer); + +} diff --git a/src/main/java/com/wolfyscript/utilities/common/gui/components/Icon.java b/src/main/java/com/wolfyscript/utilities/common/gui/components/Icon.java new file mode 100644 index 000000000..9b25ff2a5 --- /dev/null +++ b/src/main/java/com/wolfyscript/utilities/common/gui/components/Icon.java @@ -0,0 +1,28 @@ +/* + * WolfyUtilities, APIs and Utilities for Minecraft Spigot plugins + * Copyright (C) 2021 WolfyScript + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.wolfyscript.utilities.common.gui.components; + +import com.wolfyscript.utilities.common.gui.Component; +import com.wolfyscript.utilities.common.items.ItemStackConfig; + +public interface Icon extends Component { + + ItemStackConfig getItemStackConfig(); + +} diff --git a/src/main/java/com/wolfyscript/utilities/common/gui/components/StackInputSlot.java b/src/main/java/com/wolfyscript/utilities/common/gui/components/StackInputSlot.java new file mode 100644 index 000000000..addf34522 --- /dev/null +++ b/src/main/java/com/wolfyscript/utilities/common/gui/components/StackInputSlot.java @@ -0,0 +1,29 @@ +/* + * WolfyUtilities, APIs and Utilities for Minecraft Spigot plugins + * Copyright (C) 2021 WolfyScript + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.wolfyscript.utilities.common.gui.components; + +import com.wolfyscript.utilities.common.adapters.ItemStack; +import com.wolfyscript.utilities.common.gui.*; +import com.wolfyscript.utilities.common.gui.signal.Signal; + +public interface StackInputSlot extends Component, Interactable { + + Signal signal(); + +} diff --git a/src/main/java/com/wolfyscript/utilities/common/gui/components/StackInputSlotBuilder.java b/src/main/java/com/wolfyscript/utilities/common/gui/components/StackInputSlotBuilder.java new file mode 100644 index 000000000..f3fdb85c9 --- /dev/null +++ b/src/main/java/com/wolfyscript/utilities/common/gui/components/StackInputSlotBuilder.java @@ -0,0 +1,37 @@ +/* + * WolfyUtilities, APIs and Utilities for Minecraft Spigot plugins + * Copyright (C) 2021 WolfyScript + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.wolfyscript.utilities.common.gui.components; + +import com.wolfyscript.utilities.common.adapters.ItemStack; +import com.wolfyscript.utilities.common.gui.Component; +import com.wolfyscript.utilities.common.gui.ComponentBuilder; +import com.wolfyscript.utilities.common.gui.callback.InteractionCallback; +import com.wolfyscript.utilities.common.gui.signal.Signal; + +import java.util.function.Consumer; + +public interface StackInputSlotBuilder extends ComponentBuilder { + + StackInputSlotBuilder onValueChange(Consumer onValueChange); + + StackInputSlotBuilder value(Signal valueSignal); + + StackInputSlotBuilder interact(InteractionCallback interactionCallback); + +} diff --git a/src/main/java/com/wolfyscript/utilities/common/gui/functions/ReactiveConsumer.java b/src/main/java/com/wolfyscript/utilities/common/gui/functions/ReactiveConsumer.java new file mode 100644 index 000000000..b510170ea --- /dev/null +++ b/src/main/java/com/wolfyscript/utilities/common/gui/functions/ReactiveConsumer.java @@ -0,0 +1,71 @@ +/* + * WolfyUtilities, APIs and Utilities for Minecraft Spigot plugins + * Copyright (C) 2021 WolfyScript + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.wolfyscript.utilities.common.gui.functions; + +import com.wolfyscript.utilities.common.gui.signal.Signal; + +import java.util.Collection; +import java.util.Objects; +import java.util.function.Consumer; + +/** + * A wrapper Consumer that is linked to {@link Signal}s. + * + * @param + */ +public class ReactiveConsumer implements Consumer { + + private static int NEXT_ID = 0; + + private final int id; + private final Collection> signals; + private final SerializableConsumer consumer; + + public ReactiveConsumer(SerializableConsumer consumer) { + this.id = NEXT_ID++; + this.signals = consumer.getSignalsUsed(); + this.consumer = consumer; + } + + public int id() { + return id; + } + + public void accept(T value) { + consumer.accept(value); + } + + public Collection> signals() { + return signals; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + ReactiveConsumer that = (ReactiveConsumer) o; + return id == that.id; + } + + @Override + public int hashCode() { + return Objects.hash(id); + } + +} diff --git a/src/main/java/com/wolfyscript/utilities/common/gui/functions/ReactiveSupplier.java b/src/main/java/com/wolfyscript/utilities/common/gui/functions/ReactiveSupplier.java new file mode 100644 index 000000000..a25654354 --- /dev/null +++ b/src/main/java/com/wolfyscript/utilities/common/gui/functions/ReactiveSupplier.java @@ -0,0 +1,71 @@ +/* + * WolfyUtilities, APIs and Utilities for Minecraft Spigot plugins + * Copyright (C) 2021 WolfyScript + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.wolfyscript.utilities.common.gui.functions; + +import com.wolfyscript.utilities.common.gui.signal.Signal; + +import java.util.Collection; +import java.util.Objects; +import java.util.function.Supplier; + +/** + * A wrapper Supplier that is linked to {@link Signal}s. + * + * @param + */ +public class ReactiveSupplier implements Supplier { + + private static int NEXT_ID = 0; + + private final int id; + private final Collection> signals; + private final SerializableSupplier supplier; + + public ReactiveSupplier(SerializableSupplier supplier) { + this.id = NEXT_ID++; + this.signals = supplier.getSignalsUsed(); + this.supplier = supplier; + } + + public int id() { + return id; + } + + public T get() { + return supplier.get(); + } + + public Collection> signals() { + return signals; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + ReactiveSupplier that = (ReactiveSupplier) o; + return id == that.id; + } + + @Override + public int hashCode() { + return Objects.hash(id); + } + +} diff --git a/src/main/java/com/wolfyscript/utilities/common/gui/functions/SerializableConsumer.java b/src/main/java/com/wolfyscript/utilities/common/gui/functions/SerializableConsumer.java new file mode 100644 index 000000000..f9ccce54a --- /dev/null +++ b/src/main/java/com/wolfyscript/utilities/common/gui/functions/SerializableConsumer.java @@ -0,0 +1,24 @@ +/* + * WolfyUtilities, APIs and Utilities for Minecraft Spigot plugins + * Copyright (C) 2021 WolfyScript + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.wolfyscript.utilities.common.gui.functions; + +import java.util.function.Consumer; + +public interface SerializableConsumer extends Consumer, SignalledSerializable { +} diff --git a/src/main/java/com/wolfyscript/utilities/common/gui/functions/SerializableFunction.java b/src/main/java/com/wolfyscript/utilities/common/gui/functions/SerializableFunction.java new file mode 100644 index 000000000..0673462c8 --- /dev/null +++ b/src/main/java/com/wolfyscript/utilities/common/gui/functions/SerializableFunction.java @@ -0,0 +1,24 @@ +/* + * WolfyUtilities, APIs and Utilities for Minecraft Spigot plugins + * Copyright (C) 2021 WolfyScript + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.wolfyscript.utilities.common.gui.functions; + +import java.util.function.Function; + +public interface SerializableFunction extends Function, SignalledSerializable { +} diff --git a/src/main/java/com/wolfyscript/utilities/common/gui/functions/SerializableFunctionUtil.java b/src/main/java/com/wolfyscript/utilities/common/gui/functions/SerializableFunctionUtil.java new file mode 100644 index 000000000..dac394f19 --- /dev/null +++ b/src/main/java/com/wolfyscript/utilities/common/gui/functions/SerializableFunctionUtil.java @@ -0,0 +1,55 @@ +/* + * WolfyUtilities, APIs and Utilities for Minecraft Spigot plugins + * Copyright (C) 2021 WolfyScript + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.wolfyscript.utilities.common.gui.functions; + +import com.wolfyscript.utilities.common.gui.signal.Signal; + +import java.io.Serializable; +import java.lang.invoke.SerializedLambda; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +public class SerializableFunctionUtil { + + public static Collection> getUsedSignals(Serializable serializable) { + try { + // Using serialized lambda we have access to runtime information, such as which outer variables are captured and used inside the lambda. + // See: https://stackoverflow.com/a/35223119 + SerializedLambda s = getSerializedLambda(serializable); + List> signals = new ArrayList<>(s.getCapturedArgCount()); + for (int i = 0; i < s.getCapturedArgCount(); i++) { + if (s.getCapturedArg(i) instanceof Signal signal) { + signals.add(signal); + } + } + return signals; + } catch (Exception e) { + e.printStackTrace(); + } + return List.of(); + } + + private static SerializedLambda getSerializedLambda(Serializable lambda) throws Exception { + final Method method = lambda.getClass().getDeclaredMethod("writeReplace"); + method.setAccessible(true); + return (SerializedLambda) method.invoke(lambda); + } +} diff --git a/src/main/java/com/wolfyscript/utilities/common/gui/functions/SerializableRunnable.java b/src/main/java/com/wolfyscript/utilities/common/gui/functions/SerializableRunnable.java new file mode 100644 index 000000000..a773b8517 --- /dev/null +++ b/src/main/java/com/wolfyscript/utilities/common/gui/functions/SerializableRunnable.java @@ -0,0 +1,23 @@ +/* + * WolfyUtilities, APIs and Utilities for Minecraft Spigot plugins + * Copyright (C) 2021 WolfyScript + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.wolfyscript.utilities.common.gui.functions; + +public interface SerializableRunnable extends Runnable, SignalledSerializable { + +} diff --git a/src/main/java/com/wolfyscript/utilities/common/gui/functions/SerializableSupplier.java b/src/main/java/com/wolfyscript/utilities/common/gui/functions/SerializableSupplier.java new file mode 100644 index 000000000..c71c40a2d --- /dev/null +++ b/src/main/java/com/wolfyscript/utilities/common/gui/functions/SerializableSupplier.java @@ -0,0 +1,24 @@ +/* + * WolfyUtilities, APIs and Utilities for Minecraft Spigot plugins + * Copyright (C) 2021 WolfyScript + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.wolfyscript.utilities.common.gui.functions; + +import java.util.function.Supplier; + +public interface SerializableSupplier extends Supplier, SignalledSerializable { +} diff --git a/src/main/java/com/wolfyscript/utilities/common/gui/functions/SignalledSerializable.java b/src/main/java/com/wolfyscript/utilities/common/gui/functions/SignalledSerializable.java new file mode 100644 index 000000000..a979ddb11 --- /dev/null +++ b/src/main/java/com/wolfyscript/utilities/common/gui/functions/SignalledSerializable.java @@ -0,0 +1,35 @@ +/* + * WolfyUtilities, APIs and Utilities for Minecraft Spigot plugins + * Copyright (C) 2021 WolfyScript + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.wolfyscript.utilities.common.gui.functions; + +import com.wolfyscript.utilities.common.gui.signal.Signal; + +import java.io.Serializable; +import java.util.Collection; + +/** + * This represents an interface that is Serializable and contains information about the used {@link Signal}s inside of the closure. + */ +public interface SignalledSerializable extends Serializable { + + default Collection> getSignalsUsed() { + return SerializableFunctionUtil.getUsedSignals(this); + } + +} diff --git a/src/main/java/com/wolfyscript/utilities/common/gui/impl/AbstractComponentBuilderImpl.java b/src/main/java/com/wolfyscript/utilities/common/gui/impl/AbstractComponentBuilderImpl.java new file mode 100644 index 000000000..fca14744d --- /dev/null +++ b/src/main/java/com/wolfyscript/utilities/common/gui/impl/AbstractComponentBuilderImpl.java @@ -0,0 +1,68 @@ +package com.wolfyscript.utilities.common.gui.impl; + +import com.fasterxml.jackson.annotation.JsonAlias; +import com.fasterxml.jackson.annotation.JsonFormat; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.wolfyscript.utilities.NamespacedKey; +import com.wolfyscript.utilities.common.WolfyUtils; +import com.wolfyscript.utilities.common.gui.Component; +import com.wolfyscript.utilities.common.gui.ComponentBuilder; +import com.wolfyscript.utilities.common.gui.Position; +import com.wolfyscript.utilities.common.gui.signal.Signal; +import com.wolfyscript.utilities.json.annotations.KeyedBaseType; +import com.wolfyscript.utilities.json.annotations.OptionalValueDeserializer; +import it.unimi.dsi.fastutil.ints.IntList; + +import java.util.Collection; +import java.util.HashSet; +import java.util.Set; + +@KeyedBaseType(baseType = ComponentBuilder.class) +public abstract class AbstractComponentBuilderImpl implements ComponentBuilder { + + @JsonProperty("type") + private final NamespacedKey type; + private final String id; + @JsonProperty("position") + private final Position position; + @JsonIgnore + private final Set> signals = new HashSet<>(); + private final WolfyUtils wolfyUtils; + + protected AbstractComponentBuilderImpl(String id, WolfyUtils wolfyUtils, Position position) { + this.type = wolfyUtils.getIdentifiers().getNamespaced(getClass()); + this.id = id; + this.wolfyUtils = wolfyUtils; + this.position = position; + } + + @Override + public String id() { + return id; + } + + @Override + public Position position() { + return position; + } + + protected void addSignals(Collection> signals) { + this.signals.addAll(signals); + } + + @Override + public Set> signals() { + return signals; + } + + protected WolfyUtils getWolfyUtils() { + return wolfyUtils; + } + + @Override + public NamespacedKey getNamespacedKey() { + return type; + } + +} diff --git a/src/main/java/com/wolfyscript/utilities/common/gui/impl/AbstractComponentImpl.java b/src/main/java/com/wolfyscript/utilities/common/gui/impl/AbstractComponentImpl.java new file mode 100644 index 000000000..aba3e3309 --- /dev/null +++ b/src/main/java/com/wolfyscript/utilities/common/gui/impl/AbstractComponentImpl.java @@ -0,0 +1,82 @@ +package com.wolfyscript.utilities.common.gui.impl; + +import com.google.common.base.Preconditions; +import com.wolfyscript.utilities.KeyedStaticId; +import com.wolfyscript.utilities.NamespacedKey; +import com.wolfyscript.utilities.common.WolfyUtils; +import com.wolfyscript.utilities.common.gui.Component; +import com.wolfyscript.utilities.common.gui.Position; +import com.wolfyscript.utilities.common.gui.Positionable; +import com.wolfyscript.utilities.common.gui.SignalledObject; +import it.unimi.dsi.fastutil.ints.IntList; + +import java.util.Objects; + +/** + *

+ * Contains the common properties of all Components. + * It makes it easier to create custom components. + *

+ *

+ * Additional functionality should be implemented on a per-component basis without further inheritance, to make it easier to expand/change in the future. + * Instead, use interfaces (that are already there for the platform independent API) and implement them for each component. + * Duplicate code may occur, but it can be put into static methods. + *

+ */ +public abstract class AbstractComponentImpl implements Component, SignalledObject, Positionable { + + private final NamespacedKey type; + private final String internalID; + private final WolfyUtils wolfyUtils; + private final Component parent; + private final Position position; + + public AbstractComponentImpl(String internalID, WolfyUtils wolfyUtils, Component parent, Position position) { + Preconditions.checkNotNull(internalID); + Preconditions.checkNotNull(wolfyUtils); + this.type = wolfyUtils.getIdentifiers().getNamespaced(getClass()); + Preconditions.checkNotNull(type, "Missing type key! One must be provided to the Component using the annotation: %s", KeyedStaticId.class.getName()); + this.internalID = internalID; + this.wolfyUtils = wolfyUtils; + this.parent = parent; + this.position = position; + } + + @Override + public NamespacedKey getNamespacedKey() { + return type; + } + + @Override + public String getID() { + return internalID; + } + + @Override + public WolfyUtils getWolfyUtils() { + return wolfyUtils; + } + + @Override + public Component parent() { + return parent; + } + + @Override + public Position position() { + return position; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + AbstractComponentImpl that = (AbstractComponentImpl) o; + return Objects.equals(type, that.type) && Objects.equals(internalID, that.internalID); + } + + @Override + public int hashCode() { + return Objects.hash(type, internalID); + } +} diff --git a/src/main/java/com/wolfyscript/utilities/common/gui/signal/Signal.java b/src/main/java/com/wolfyscript/utilities/common/gui/signal/Signal.java new file mode 100644 index 000000000..df51c62fe --- /dev/null +++ b/src/main/java/com/wolfyscript/utilities/common/gui/signal/Signal.java @@ -0,0 +1,72 @@ +/* + * WolfyUtilities, APIs and Utilities for Minecraft Spigot plugins + * Copyright (C) 2021 WolfyScript + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.wolfyscript.utilities.common.gui.signal; + +import com.wolfyscript.utilities.common.gui.SignalledObject; + +import java.util.function.Function; + +/** + * Keeps track of value changes and updates Components listening to a Signal accordingly. + * Signals are shared across all children of the Component that creates the Signal, + * meaning that children can listen to that of the parent, but not the other way around! + * + * @param The value type this Signal holds. Can be any Object. + */ +public interface Signal { + + /** + * The key of this Signal. + * Must be unique in the path of the component, meaning no parent nor child can create a Signal with the same key! + * + * @return The key of this Signal. + */ + String key(); + + /** + * The type of the value that this signal tracks. + * + * @return The value type of this signal. + */ + Class valueType(); + + /** + * Sets the tracked value to a new value and causes a re-render. + * + * @param newValue The new value to apply. + */ + void set(V newValue); + + /** + * Gets the tracked value, then updates it, and causes a re-render. + * + * @param updateFunction The function to update the value. + */ + void update(Function updateFunction); + + /** + * Gets the current value. + * + * @return The current value. + */ + V get(); + + void linkTo(SignalledObject signalledObject); + +} diff --git a/src/main/java/com/wolfyscript/utilities/common/gui/signal/Store.java b/src/main/java/com/wolfyscript/utilities/common/gui/signal/Store.java new file mode 100644 index 000000000..66a2e932c --- /dev/null +++ b/src/main/java/com/wolfyscript/utilities/common/gui/signal/Store.java @@ -0,0 +1,26 @@ +/* + * WolfyUtilities, APIs and Utilities for Minecraft Spigot plugins + * Copyright (C) 2021 WolfyScript + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.wolfyscript.utilities.common.gui.signal; + +public interface Store extends Signal { + + + + +} diff --git a/src/main/java/com/wolfyscript/utilities/common/registry/Registries.java b/src/main/java/com/wolfyscript/utilities/common/registry/Registries.java index bb8063427..540d9c868 100644 --- a/src/main/java/com/wolfyscript/utilities/common/registry/Registries.java +++ b/src/main/java/com/wolfyscript/utilities/common/registry/Registries.java @@ -23,6 +23,7 @@ import com.wolfyscript.utilities.NamespacedKey; import com.wolfyscript.utilities.common.WolfyCore; import com.wolfyscript.utilities.common.WolfyUtils; +import com.wolfyscript.utilities.common.gui.Component; import com.wolfyscript.utilities.nbt.NBTTagConfig; import com.wolfyscript.utilities.eval.operator.Operator; import com.wolfyscript.utilities.eval.value_provider.ValueProvider; @@ -111,4 +112,8 @@ public TypeRegistry getOperators() { public TypeRegistry getNbtTagConfigs() { return nbtTagConfigs; } + + public abstract TypeRegistry getGuiComponents(); + + public abstract RegistryGUIComponentBuilders getGuiComponentBuilders(); } diff --git a/src/main/java/com/wolfyscript/utilities/common/registry/RegistryGUIComponentBuilders.java b/src/main/java/com/wolfyscript/utilities/common/registry/RegistryGUIComponentBuilders.java new file mode 100644 index 000000000..c84f44f7c --- /dev/null +++ b/src/main/java/com/wolfyscript/utilities/common/registry/RegistryGUIComponentBuilders.java @@ -0,0 +1,28 @@ +/* + * WolfyUtilities, APIs and Utilities for Minecraft Spigot plugins + * Copyright (C) 2021 WolfyScript + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.wolfyscript.utilities.common.registry; + +import com.wolfyscript.utilities.common.gui.Component; +import com.wolfyscript.utilities.common.gui.ComponentBuilder; + +public interface RegistryGUIComponentBuilders extends TypeRegistry> { + + Class> getFor(Class componentType); + +}