From 5f1dff949f3c921e351ae89e9c97c1c6e66dcfa9 Mon Sep 17 00:00:00 2001 From: Matthew Messinger Date: Tue, 28 Nov 2017 00:41:25 -0500 Subject: [PATCH 01/19] Add resource manager for data packs --- src/main/java/org/spongepowered/api/Game.java | 11 +++ .../java/org/spongepowered/api/Sponge.java | 7 ++ .../org/spongepowered/api/asset/Asset.java | 1 + .../org/spongepowered/api/asset/AssetId.java | 1 + .../spongepowered/api/asset/AssetManager.java | 9 ++ .../org/spongepowered/api/packs/Pack.java | 77 ++++++++++++++++ .../org/spongepowered/api/packs/Resource.java | 77 ++++++++++++++++ .../api/packs/ResourceManager.java | 90 +++++++++++++++++++ 8 files changed, 273 insertions(+) create mode 100644 src/main/java/org/spongepowered/api/packs/Pack.java create mode 100644 src/main/java/org/spongepowered/api/packs/Resource.java create mode 100644 src/main/java/org/spongepowered/api/packs/ResourceManager.java diff --git a/src/main/java/org/spongepowered/api/Game.java b/src/main/java/org/spongepowered/api/Game.java index 01513083e05..d6677c4ea78 100644 --- a/src/main/java/org/spongepowered/api/Game.java +++ b/src/main/java/org/spongepowered/api/Game.java @@ -32,6 +32,7 @@ import org.spongepowered.api.event.CauseStackManager; import org.spongepowered.api.event.EventManager; import org.spongepowered.api.network.ChannelRegistrar; +import org.spongepowered.api.packs.ResourceManager; import org.spongepowered.api.plugin.PluginManager; import org.spongepowered.api.registry.GameRegistry; import org.spongepowered.api.scheduler.Scheduler; @@ -173,10 +174,20 @@ default EventManager getEventManager() { * * @return The asset manager */ + @Deprecated default AssetManager getAssetManager() { return Sponge.getAssetManager(); } + /** + * Gets the {@link ResourceManager}. + * + * @return The resource manager + */ + default ResourceManager getResourceManager() { + return Sponge.getResourceManager(); + } + /** * Gets the {@link ConfigManager} used to load and manage configuration files * for plugins. diff --git a/src/main/java/org/spongepowered/api/Sponge.java b/src/main/java/org/spongepowered/api/Sponge.java index d3dda07a04d..43795847912 100644 --- a/src/main/java/org/spongepowered/api/Sponge.java +++ b/src/main/java/org/spongepowered/api/Sponge.java @@ -35,6 +35,7 @@ import org.spongepowered.api.event.CauseStackManager; import org.spongepowered.api.event.EventManager; import org.spongepowered.api.network.ChannelRegistrar; +import org.spongepowered.api.packs.ResourceManager; import org.spongepowered.api.plugin.PluginManager; import org.spongepowered.api.registry.GameRegistry; import org.spongepowered.api.scheduler.Scheduler; @@ -57,6 +58,7 @@ public final class Sponge { @Inject private static PluginManager pluginManager; @Inject private static EventManager eventManager; @Inject private static AssetManager assetManager; + @Inject private static ResourceManager resourceManager; @Inject private static ConfigManager configManager; @Inject private static ServiceManager serviceManager; @Inject private static ChannelRegistrar channelRegistrar; @@ -133,10 +135,15 @@ public static EventManager getEventManager() { * * @return The asset manager instance */ + @Deprecated public static AssetManager getAssetManager() { return check(assetManager); } + public static ResourceManager getResourceManager() { + return check(resourceManager); + } + /** * Gets the {@link ConfigManager} used to load and manage configuration files * for plugins. diff --git a/src/main/java/org/spongepowered/api/asset/Asset.java b/src/main/java/org/spongepowered/api/asset/Asset.java index 81100b59cca..80923f204fb 100644 --- a/src/main/java/org/spongepowered/api/asset/Asset.java +++ b/src/main/java/org/spongepowered/api/asset/Asset.java @@ -41,6 +41,7 @@ /** * Represents an {@link Asset} within Sponge that belongs to a {@link Plugin}. */ +@Deprecated public interface Asset { /** diff --git a/src/main/java/org/spongepowered/api/asset/AssetId.java b/src/main/java/org/spongepowered/api/asset/AssetId.java index 94511e1bdfd..919c936feaf 100644 --- a/src/main/java/org/spongepowered/api/asset/AssetId.java +++ b/src/main/java/org/spongepowered/api/asset/AssetId.java @@ -34,6 +34,7 @@ /** * Provides an injection for {@link Asset}s in plugins. */ +@Deprecated @BindingAnnotation @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.FIELD, ElementType.PARAMETER}) diff --git a/src/main/java/org/spongepowered/api/asset/AssetManager.java b/src/main/java/org/spongepowered/api/asset/AssetManager.java index 0d55f2d5b2b..7ce2b7a22a5 100644 --- a/src/main/java/org/spongepowered/api/asset/AssetManager.java +++ b/src/main/java/org/spongepowered/api/asset/AssetManager.java @@ -24,6 +24,7 @@ */ package org.spongepowered.api.asset; +import org.spongepowered.api.packs.ResourceManager; import org.spongepowered.plugin.PluginContainer; import java.util.Optional; @@ -32,7 +33,15 @@ * The AssetManager offers a convenient way to easily retrieve resources from * Sponge {@link PluginContainer plugins}. The asset manager will attempt to find the * asset of the specified name at: assets/<plugin_id> + * + * @deprecated The asset manager was unable to provide assets which are not on + * the classpath. Additionally, it was limited to providing the URL to an + * asset, which might not have been useful in some situations. + * + *

Use the more powerful {@link ResourceManager} instead. It allows you to + * add resources from local files as well as on-the-fly generation.

*/ +@Deprecated public interface AssetManager { /** diff --git a/src/main/java/org/spongepowered/api/packs/Pack.java b/src/main/java/org/spongepowered/api/packs/Pack.java new file mode 100644 index 00000000000..c8795f797a0 --- /dev/null +++ b/src/main/java/org/spongepowered/api/packs/Pack.java @@ -0,0 +1,77 @@ +/* + * This file is part of SpongeAPI, licensed under the MIT License (MIT). + * + * Copyright (c) SpongePowered + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.spongepowered.api.packs; + +import org.spongepowered.api.Nameable; +import org.spongepowered.api.data.DataView; +import org.spongepowered.api.event.cause.Cause; + +import java.util.Collection; +import java.util.Optional; + +/** + * A pack can contain several {@link Resource Resources}. + */ +public interface Pack extends Nameable { + + /** + * Gets the metadata of this pack. The {@link DataView} represented is of + * the pack.json file in the pack root. If the pack does not contain a + * pack.json, {@link Optional#empty()} is returned. + * + * @return The metadata if it exists + */ + Optional getMetadata(); + + /** + * Gets all the resources loaded from this pack. If the pack is not + * currently active, this list will be empty. Depending on the pack + * implementation, the contents of the collection may not reflect what the + * pack contains. + * + *

If the pack is lazy-initialized, it is possible for the collection to + * be empty.

+ * + * @return List of loaded resources + */ + Collection getLoadedResources(); + + /** + * Gets a resource from this pack if it exists. No other packs will be + * queried. + * + * @param path The domain named path + * @return The resource + */ + Optional getResource(String path); + + /** + * Called when the resource manager reloads. This should be used to clean + * up any stray resources so a fresh start can be made. + * + * @param cause The cause of the reload + */ + void onReload(Cause cause); +} diff --git a/src/main/java/org/spongepowered/api/packs/Resource.java b/src/main/java/org/spongepowered/api/packs/Resource.java new file mode 100644 index 00000000000..9ad933090f8 --- /dev/null +++ b/src/main/java/org/spongepowered/api/packs/Resource.java @@ -0,0 +1,77 @@ +/* + * This file is part of SpongeAPI, licensed under the MIT License (MIT). + * + * Copyright (c) SpongePowered + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.spongepowered.api.packs; + +import org.spongepowered.api.CatalogType; +import org.spongepowered.api.data.DataView; + +import java.io.InputStream; +import java.util.Optional; + +/** + * A resource can represent any kind of loaded data. It can be a file on the filesystem, a network location, or + * even generated at runtime. Use {@link #getInputStream()} to load the data held by a resource. + */ +public interface Resource { + + /** + * Gets the path of this resource. The path follows the same rules as a + * catalog identifier. + * + * @return The path + * @see CatalogType#getId() + */ + String getPath(); + + /** + * Gets the {@link Pack} which owns this resource. + * + * @return The parent pack. + */ + Pack getPack(); + + /** + * Gets the metadata for this resource. + * + *

The metadata file has the same name as this resource, but has + * {@code .mcmeta} appended to the end.

+ * + *

For example: the metadata for the resource + * {@code minecraft:textures/blocks/water_flow.png} would be located at + * {@code minecraft:textures/blocks/water_flow.png.mcmeta}

+ * + * @return The metadata or {@link Optional#empty() empty} if it doesn't exist. + * @see Minecraft Wiki/Resource Packs + */ + Optional getMetadata(); + + /** + * Returns a new {@link InputStream} of this resource. + * + * @return A new input stream + */ + InputStream getInputStream(); + +} diff --git a/src/main/java/org/spongepowered/api/packs/ResourceManager.java b/src/main/java/org/spongepowered/api/packs/ResourceManager.java new file mode 100644 index 00000000000..e2afe992f1e --- /dev/null +++ b/src/main/java/org/spongepowered/api/packs/ResourceManager.java @@ -0,0 +1,90 @@ +/* + * This file is part of SpongeAPI, licensed under the MIT License (MIT). + * + * Copyright (c) SpongePowered + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.spongepowered.api.packs; + +import org.spongepowered.api.event.cause.Cause; + +import java.util.Collection; +import java.util.List; +import java.util.Optional; + +/** + * The resource manager is in charge of loading {@link Resource Resources} and + * {@link Pack Data Packs}. On the client, there can also be resource packs. + * + * Packs are stacked on top of each other, so they will override and replace + * resources in packs which are a lower priority. + */ +public interface ResourceManager { + + /** + * Returns a mutable list of active packs. Active packs are loaded and + * determine which resources to use. The order of this list determines + * priority, which decides which resource {@link #getResource} will return. + * + *

Add, remove, and rearrange items in this list to change the priority + * of the packs. Changes will take effect after {@link #reload()} + * is called.

+ * + *

Note: the default pack will always have the lowest priority. + * Afterwards are packs provided by plugins. They will be applied whether + * this list is empty or not.

+ * + * @return The list of active packs + */ + List getActivePacks(); + + /** + * Returns a collection of available packs. An available pack is not + * currently loaded and must be made active in order to load resources. + * + * @return A collection of available packs. + */ + Collection getAvailablePacks(); + + /** + * Gets a loaded resource at the given path, or {@link Optional#empty()} + * if it does not exist. + * + *

A path should be prefixed with a domain name. If one is not provided, + * {@code minecraft} will be used instead. For example, {@code minecraft:}

+ * + *

In the pack, the path will point to a resource. The resource should + * be located roughly at {@code /$assets/domain/$path}

+ * + * TODO use CatalogKey (SpongeAPI#1655) + * + * @param path The path, including domain, to the resource + * @return The resource + */ + Optional getResource(String path); + + /** + * Reloads the resources from packs found in {@link #getActivePacks()}. + * + * @param cause The cause of the reload + */ + void reload(Cause cause); +} From b11f9e32d10c2f792f1fcf3147aa1350e10159f9 Mon Sep 17 00:00:00 2001 From: Matthew Messinger Date: Thu, 16 Apr 2020 18:08:19 -0400 Subject: [PATCH 02/19] Add packs --- .../org/spongepowered/api/CatalogTypes.java | 3 + .../java/org/spongepowered/api/Engine.java | 16 ++ src/main/java/org/spongepowered/api/Game.java | 21 -- .../java/org/spongepowered/api/Sponge.java | 18 -- .../org/spongepowered/api/asset/Asset.java | 217 ------------------ .../spongepowered/api/asset/AssetManager.java | 68 ------ .../api/event/resource/PackEvent.java | 14 ++ .../org/spongepowered/api/packs/Pack.java | 77 ------- .../org/spongepowered/api/packs/Resource.java | 77 ------- .../api/packs/ResourceManager.java | 90 -------- .../spongepowered/api/resource/Resource.java | 132 +++++++++++ .../api/resource/ResourceManager.java | 96 ++++++++ .../api/resource/ResourcePath.java | 112 +++++++++ .../spongepowered/api/resource/pack/Pack.java | 135 +++++++++++ .../api/resource/pack/PackDiscoverer.java | 50 ++++ .../api/resource/pack/PackInfo.java | 47 ++++ .../api/resource/pack/PackList.java | 41 ++++ .../api/resource/pack/PackType.java | 33 +++ .../api/resource/pack/PackTypes.java | 44 ++++ .../api/resource/pack/PackVersion.java | 43 ++++ .../api/resource/pack/package-info.java | 26 +++ .../api/{asset => resource}/package-info.java | 2 +- .../AssetId.java => util/CloseableList.java} | 30 +-- 23 files changed, 804 insertions(+), 588 deletions(-) delete mode 100644 src/main/java/org/spongepowered/api/asset/AssetManager.java create mode 100644 src/main/java/org/spongepowered/api/event/resource/PackEvent.java delete mode 100644 src/main/java/org/spongepowered/api/packs/Pack.java delete mode 100644 src/main/java/org/spongepowered/api/packs/Resource.java delete mode 100644 src/main/java/org/spongepowered/api/packs/ResourceManager.java create mode 100644 src/main/java/org/spongepowered/api/resource/Resource.java create mode 100644 src/main/java/org/spongepowered/api/resource/ResourceManager.java create mode 100644 src/main/java/org/spongepowered/api/resource/ResourcePath.java create mode 100644 src/main/java/org/spongepowered/api/resource/pack/Pack.java create mode 100644 src/main/java/org/spongepowered/api/resource/pack/PackDiscoverer.java create mode 100644 src/main/java/org/spongepowered/api/resource/pack/PackInfo.java create mode 100644 src/main/java/org/spongepowered/api/resource/pack/PackList.java create mode 100644 src/main/java/org/spongepowered/api/resource/pack/PackType.java create mode 100644 src/main/java/org/spongepowered/api/resource/pack/PackTypes.java create mode 100644 src/main/java/org/spongepowered/api/resource/pack/PackVersion.java create mode 100644 src/main/java/org/spongepowered/api/resource/pack/package-info.java rename src/main/java/org/spongepowered/api/{asset => resource}/package-info.java (97%) rename src/main/java/org/spongepowered/api/{asset/AssetId.java => util/CloseableList.java} (67%) diff --git a/src/main/java/org/spongepowered/api/CatalogTypes.java b/src/main/java/org/spongepowered/api/CatalogTypes.java index 263a5a4531c..3a5ed891f03 100644 --- a/src/main/java/org/spongepowered/api/CatalogTypes.java +++ b/src/main/java/org/spongepowered/api/CatalogTypes.java @@ -63,6 +63,7 @@ import org.spongepowered.api.item.recipe.crafting.CraftingRecipe; import org.spongepowered.api.registry.CatalogRegistry; import org.spongepowered.api.registry.GameRegistry; +import org.spongepowered.api.resource.pack.PackType; import org.spongepowered.api.scoreboard.CollisionRule; import org.spongepowered.api.scoreboard.Visibility; import org.spongepowered.api.scoreboard.criteria.Criterion; @@ -211,6 +212,8 @@ public final class CatalogTypes { public static final Class OBJECTIVE_DISPLAY_MODE = ObjectiveDisplayMode.class; + public static final Class PACK_TYPE = PackType.class; + public static final Class PANDA_GENE = PandaGene.class; public static final Class PARROT_TYPE = ParrotType.class; diff --git a/src/main/java/org/spongepowered/api/Engine.java b/src/main/java/org/spongepowered/api/Engine.java index 9e2cf5df526..277dbb20c3e 100644 --- a/src/main/java/org/spongepowered/api/Engine.java +++ b/src/main/java/org/spongepowered/api/Engine.java @@ -24,6 +24,8 @@ */ package org.spongepowered.api; +import org.spongepowered.api.resource.ResourceManager; +import org.spongepowered.api.resource.pack.PackList; import org.spongepowered.api.scheduler.Scheduler; /** @@ -31,6 +33,20 @@ */ public interface Engine { + /** + * Gets the {@link PackList} instance of this engine. + * + * @return + */ + PackList getPackList(); + + /** + * Gets the {@link ResourceManager} for this engine. + * + * @return The resource manager + */ + ResourceManager getResourceManager(); + /** * Gets the {@link Scheduler} used to schedule sync tasks on this {@link Engine}. * diff --git a/src/main/java/org/spongepowered/api/Game.java b/src/main/java/org/spongepowered/api/Game.java index d6677c4ea78..1dec81d0954 100644 --- a/src/main/java/org/spongepowered/api/Game.java +++ b/src/main/java/org/spongepowered/api/Game.java @@ -24,7 +24,6 @@ */ package org.spongepowered.api; -import org.spongepowered.api.asset.AssetManager; import org.spongepowered.api.config.ConfigManager; import org.spongepowered.api.data.DataManager; import org.spongepowered.api.data.persistence.DataBuilder; @@ -32,7 +31,6 @@ import org.spongepowered.api.event.CauseStackManager; import org.spongepowered.api.event.EventManager; import org.spongepowered.api.network.ChannelRegistrar; -import org.spongepowered.api.packs.ResourceManager; import org.spongepowered.api.plugin.PluginManager; import org.spongepowered.api.registry.GameRegistry; import org.spongepowered.api.scheduler.Scheduler; @@ -169,25 +167,6 @@ default EventManager getEventManager() { return Sponge.getEventManager(); } - /** - * Gets the {@link AssetManager}. - * - * @return The asset manager - */ - @Deprecated - default AssetManager getAssetManager() { - return Sponge.getAssetManager(); - } - - /** - * Gets the {@link ResourceManager}. - * - * @return The resource manager - */ - default ResourceManager getResourceManager() { - return Sponge.getResourceManager(); - } - /** * Gets the {@link ConfigManager} used to load and manage configuration files * for plugins. diff --git a/src/main/java/org/spongepowered/api/Sponge.java b/src/main/java/org/spongepowered/api/Sponge.java index 43795847912..4660156b250 100644 --- a/src/main/java/org/spongepowered/api/Sponge.java +++ b/src/main/java/org/spongepowered/api/Sponge.java @@ -28,14 +28,12 @@ import com.google.inject.Inject; import org.checkerframework.checker.nullness.qual.Nullable; -import org.spongepowered.api.asset.AssetManager; import org.spongepowered.api.command.manager.CommandManager; import org.spongepowered.api.config.ConfigManager; import org.spongepowered.api.data.DataManager; import org.spongepowered.api.event.CauseStackManager; import org.spongepowered.api.event.EventManager; import org.spongepowered.api.network.ChannelRegistrar; -import org.spongepowered.api.packs.ResourceManager; import org.spongepowered.api.plugin.PluginManager; import org.spongepowered.api.registry.GameRegistry; import org.spongepowered.api.scheduler.Scheduler; @@ -57,8 +55,6 @@ public final class Sponge { @Inject private static DataManager dataManager; @Inject private static PluginManager pluginManager; @Inject private static EventManager eventManager; - @Inject private static AssetManager assetManager; - @Inject private static ResourceManager resourceManager; @Inject private static ConfigManager configManager; @Inject private static ServiceManager serviceManager; @Inject private static ChannelRegistrar channelRegistrar; @@ -130,20 +126,6 @@ public static EventManager getEventManager() { return check(eventManager); } - /** - * Gets the {@link AssetManager} instance. - * - * @return The asset manager instance - */ - @Deprecated - public static AssetManager getAssetManager() { - return check(assetManager); - } - - public static ResourceManager getResourceManager() { - return check(resourceManager); - } - /** * Gets the {@link ConfigManager} used to load and manage configuration files * for plugins. diff --git a/src/main/java/org/spongepowered/api/asset/Asset.java b/src/main/java/org/spongepowered/api/asset/Asset.java index 80923f204fb..e69de29bb2d 100644 --- a/src/main/java/org/spongepowered/api/asset/Asset.java +++ b/src/main/java/org/spongepowered/api/asset/Asset.java @@ -1,217 +0,0 @@ -/* - * This file is part of SpongeAPI, licensed under the MIT License (MIT). - * - * Copyright (c) SpongePowered - * Copyright (c) contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package org.spongepowered.api.asset; - -import static com.google.common.base.Preconditions.checkNotNull; - -import com.google.common.io.Resources; -import org.spongepowered.plugin.PluginContainer; - -import java.io.IOException; -import java.io.InputStream; -import java.net.URL; -import java.nio.charset.Charset; -import java.nio.charset.StandardCharsets; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.List; - -/** - * Represents an {@link Asset} within Sponge that belongs to a {@link Plugin}. - */ -@Deprecated -public interface Asset { - - /** - * The default {@link Charset} that is used for reading {@link Asset}s. - */ - Charset DEFAULT_CHARSET = StandardCharsets.UTF_8; - - /** - * Returns the original {@link PluginContainer plugin} owner of this Asset. - * - * @return Original owner of asset - */ - PluginContainer getOwner(); - - /** - * Returns the {@link URL} to this Asset. - * - * @return URL to asset - */ - URL getUrl(); - - /** - * Copies this Asset to the specified 'output' {@link Path}. - * - * @param output Path to copy to - * @throws IOException If any file exception is thrown - */ - default void copyToFile(Path output) throws IOException { - this.copyToFile(output, false); - } - - /** - * Copies this Asset to the specified 'output' {@link Path}. - * - * @param output Path to copy to - * @param overwrite If the file should be overwritten if it exists - * @throws IOException File exception - */ - default void copyToFile(Path output, boolean overwrite) throws IOException { - this.copyToFile(output, overwrite, true); - } - - /** - * Copies this Asset to the specified 'output' {@link Path}. - * - * @param output Path to copy to - * @param overwrite If the file should be overwritten if it exists - * @param onlyIfAbsent If the file should only be copied if absent - * @throws IOException File exception - */ - default void copyToFile(Path output, boolean overwrite, boolean onlyIfAbsent) throws IOException { - checkNotNull(output, "output"); - if (Files.exists(output)) { - if (overwrite) { - Files.delete(output); - } else if (onlyIfAbsent) { - return; - } - } - try (InputStream in = this.getUrl().openStream()) { - Files.copy(in, output); - } - } - - /** - * Copies this Asset to the specified 'outputDirectory' {@link Path}. - * - * @param outputDirectory The directory to copy to - * @throws IOException If any file exception is thrown - */ - default void copyToDirectory(Path outputDirectory) throws IOException { - this.copyToDirectory(outputDirectory, false); - } - - /** - * Copies this Asset to the specified 'outputDirectory' {@link Path}. - * - * @param outputDirectory The directory to copy to - * @param overwrite If the file should be overwritten if it exists - * @throws IOException File exception - */ - default void copyToDirectory(Path outputDirectory, boolean overwrite) throws IOException { - this.copyToDirectory(outputDirectory, overwrite, true); - } - - /** - * Copies this Asset to the specified 'outputDirectory' {@link Path}. - * - * @param outputDirectory The directory to copy to - * @param overwrite If the file should be overwritten if it exists - * @param onlyIfAbsent If the file should only be copied if absent - * @throws IOException File exception - */ - default void copyToDirectory(Path outputDirectory, boolean overwrite, boolean onlyIfAbsent) throws IOException { - checkNotNull(outputDirectory, "outputDirectory"); - Files.createDirectories(outputDirectory); - this.copyToFile(outputDirectory.resolve(this.getFileName()), overwrite, onlyIfAbsent); - } - - /** - * Returns the the last portion of the Asset URL, e.g. the file name. - * - * @return The file name - */ - default String getFileName() { - String path = getUrl().getPath(); - //We don't need to worry about file system specific file separators as we are dealing with a substring of URL - int end = path.lastIndexOf('/'); - if (end < 0) { - return path; - } - - return path.substring(end + 1); - } - - /** - * Reads this Asset in it's entirety as a {@link String} and returns the - * result. - * - * @return String representation of Asset - * @throws IOException If any file exception is thrown - */ - default String readString() throws IOException { - return readString(DEFAULT_CHARSET); - } - - /** - * Reads this Asset in it's entirety as a {@link String} and returns the - * result. - * - * @param charset The charset to read the asset with - * @return String representation of Asset - * @throws IOException If any file exception is thrown - */ - default String readString(Charset charset) throws IOException { - checkNotNull(charset, "charset"); - return Resources.toString(getUrl(), charset); - } - - /** - * Reads all lines from the asset and returns the result. - * - * @return The lines read from the asset - * @throws IOException If any file exception is thrown - */ - default List readLines() throws IOException { - return readLines(DEFAULT_CHARSET); - } - - /** - * Reads all lines from the asset and returns the result. - * - * @param charset The charset to read the asset with - * @return An immutable list of the lines read from the asset - * @throws IOException If any file exception is thrown - */ - default List readLines(Charset charset) throws IOException { - checkNotNull(charset, "charset"); - return Resources.asCharSource(getUrl(), charset).readLines(); - } - - /** - * Reads this Asset in it's entirety as a byte array and returns the - * result. - * - * @return Byte array representation of Asset - * @throws IOException If any file exception is thrown - */ - default byte[] readBytes() throws IOException { - return Resources.toByteArray(getUrl()); - } - -} diff --git a/src/main/java/org/spongepowered/api/asset/AssetManager.java b/src/main/java/org/spongepowered/api/asset/AssetManager.java deleted file mode 100644 index 7ce2b7a22a5..00000000000 --- a/src/main/java/org/spongepowered/api/asset/AssetManager.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * This file is part of SpongeAPI, licensed under the MIT License (MIT). - * - * Copyright (c) SpongePowered - * Copyright (c) contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package org.spongepowered.api.asset; - -import org.spongepowered.api.packs.ResourceManager; -import org.spongepowered.plugin.PluginContainer; - -import java.util.Optional; - -/** - * The AssetManager offers a convenient way to easily retrieve resources from - * Sponge {@link PluginContainer plugins}. The asset manager will attempt to find the - * asset of the specified name at: assets/<plugin_id> - * - * @deprecated The asset manager was unable to provide assets which are not on - * the classpath. Additionally, it was limited to providing the URL to an - * asset, which might not have been useful in some situations. - * - *

Use the more powerful {@link ResourceManager} instead. It allows you to - * add resources from local files as well as on-the-fly generation.

- */ -@Deprecated -public interface AssetManager { - - /** - * Returns the {@link Asset} of the specified name for the specified - * {@link PluginContainer plugin} instance. - * - * @param plugin Plugin instance - * @param name Name of resource to retrieve - * @return Asset if present, empty otherwise - */ - Optional getAsset(PluginContainer plugin, String name); - - /** - * Returns the {@link Asset} of the specified name within the domain of the - * implementation. This method will typically call - * {@link #getAsset(PluginContainer, String)} using a dummy - * {@link PluginContainer} for the SpongeAPI implementation. - * - * @param name Name of resource to retrieve - * @return Asset if present, empty otherwise - */ - Optional getAsset(String name); - -} diff --git a/src/main/java/org/spongepowered/api/event/resource/PackEvent.java b/src/main/java/org/spongepowered/api/event/resource/PackEvent.java new file mode 100644 index 00000000000..a2f24c61ade --- /dev/null +++ b/src/main/java/org/spongepowered/api/event/resource/PackEvent.java @@ -0,0 +1,14 @@ +package org.spongepowered.api.event.resource; + +import org.spongepowered.api.event.Event; +import org.spongepowered.api.resource.pack.Pack; +import org.spongepowered.api.resource.pack.PackList; + +/** + * Base {@link Pack} event. + */ +public interface PackEvent extends Event { + + PackList getPackList(); + +} diff --git a/src/main/java/org/spongepowered/api/packs/Pack.java b/src/main/java/org/spongepowered/api/packs/Pack.java deleted file mode 100644 index c8795f797a0..00000000000 --- a/src/main/java/org/spongepowered/api/packs/Pack.java +++ /dev/null @@ -1,77 +0,0 @@ -/* - * This file is part of SpongeAPI, licensed under the MIT License (MIT). - * - * Copyright (c) SpongePowered - * Copyright (c) contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package org.spongepowered.api.packs; - -import org.spongepowered.api.Nameable; -import org.spongepowered.api.data.DataView; -import org.spongepowered.api.event.cause.Cause; - -import java.util.Collection; -import java.util.Optional; - -/** - * A pack can contain several {@link Resource Resources}. - */ -public interface Pack extends Nameable { - - /** - * Gets the metadata of this pack. The {@link DataView} represented is of - * the pack.json file in the pack root. If the pack does not contain a - * pack.json, {@link Optional#empty()} is returned. - * - * @return The metadata if it exists - */ - Optional getMetadata(); - - /** - * Gets all the resources loaded from this pack. If the pack is not - * currently active, this list will be empty. Depending on the pack - * implementation, the contents of the collection may not reflect what the - * pack contains. - * - *

If the pack is lazy-initialized, it is possible for the collection to - * be empty.

- * - * @return List of loaded resources - */ - Collection getLoadedResources(); - - /** - * Gets a resource from this pack if it exists. No other packs will be - * queried. - * - * @param path The domain named path - * @return The resource - */ - Optional getResource(String path); - - /** - * Called when the resource manager reloads. This should be used to clean - * up any stray resources so a fresh start can be made. - * - * @param cause The cause of the reload - */ - void onReload(Cause cause); -} diff --git a/src/main/java/org/spongepowered/api/packs/Resource.java b/src/main/java/org/spongepowered/api/packs/Resource.java deleted file mode 100644 index 9ad933090f8..00000000000 --- a/src/main/java/org/spongepowered/api/packs/Resource.java +++ /dev/null @@ -1,77 +0,0 @@ -/* - * This file is part of SpongeAPI, licensed under the MIT License (MIT). - * - * Copyright (c) SpongePowered - * Copyright (c) contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package org.spongepowered.api.packs; - -import org.spongepowered.api.CatalogType; -import org.spongepowered.api.data.DataView; - -import java.io.InputStream; -import java.util.Optional; - -/** - * A resource can represent any kind of loaded data. It can be a file on the filesystem, a network location, or - * even generated at runtime. Use {@link #getInputStream()} to load the data held by a resource. - */ -public interface Resource { - - /** - * Gets the path of this resource. The path follows the same rules as a - * catalog identifier. - * - * @return The path - * @see CatalogType#getId() - */ - String getPath(); - - /** - * Gets the {@link Pack} which owns this resource. - * - * @return The parent pack. - */ - Pack getPack(); - - /** - * Gets the metadata for this resource. - * - *

The metadata file has the same name as this resource, but has - * {@code .mcmeta} appended to the end.

- * - *

For example: the metadata for the resource - * {@code minecraft:textures/blocks/water_flow.png} would be located at - * {@code minecraft:textures/blocks/water_flow.png.mcmeta}

- * - * @return The metadata or {@link Optional#empty() empty} if it doesn't exist. - * @see
Minecraft Wiki/Resource Packs - */ - Optional getMetadata(); - - /** - * Returns a new {@link InputStream} of this resource. - * - * @return A new input stream - */ - InputStream getInputStream(); - -} diff --git a/src/main/java/org/spongepowered/api/packs/ResourceManager.java b/src/main/java/org/spongepowered/api/packs/ResourceManager.java deleted file mode 100644 index e2afe992f1e..00000000000 --- a/src/main/java/org/spongepowered/api/packs/ResourceManager.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * This file is part of SpongeAPI, licensed under the MIT License (MIT). - * - * Copyright (c) SpongePowered - * Copyright (c) contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package org.spongepowered.api.packs; - -import org.spongepowered.api.event.cause.Cause; - -import java.util.Collection; -import java.util.List; -import java.util.Optional; - -/** - * The resource manager is in charge of loading {@link Resource Resources} and - * {@link Pack Data Packs}. On the client, there can also be resource packs. - * - * Packs are stacked on top of each other, so they will override and replace - * resources in packs which are a lower priority. - */ -public interface ResourceManager { - - /** - * Returns a mutable list of active packs. Active packs are loaded and - * determine which resources to use. The order of this list determines - * priority, which decides which resource {@link #getResource} will return. - * - *

Add, remove, and rearrange items in this list to change the priority - * of the packs. Changes will take effect after {@link #reload()} - * is called.

- * - *

Note: the default pack will always have the lowest priority. - * Afterwards are packs provided by plugins. They will be applied whether - * this list is empty or not.

- * - * @return The list of active packs - */ - List getActivePacks(); - - /** - * Returns a collection of available packs. An available pack is not - * currently loaded and must be made active in order to load resources. - * - * @return A collection of available packs. - */ - Collection getAvailablePacks(); - - /** - * Gets a loaded resource at the given path, or {@link Optional#empty()} - * if it does not exist. - * - *

A path should be prefixed with a domain name. If one is not provided, - * {@code minecraft} will be used instead. For example, {@code minecraft:}

- * - *

In the pack, the path will point to a resource. The resource should - * be located roughly at {@code /$assets/domain/$path}

- * - * TODO use CatalogKey (SpongeAPI#1655) - * - * @param path The path, including domain, to the resource - * @return The resource - */ - Optional getResource(String path); - - /** - * Reloads the resources from packs found in {@link #getActivePacks()}. - * - * @param cause The cause of the reload - */ - void reload(Cause cause); -} diff --git a/src/main/java/org/spongepowered/api/resource/Resource.java b/src/main/java/org/spongepowered/api/resource/Resource.java new file mode 100644 index 00000000000..173deff6c07 --- /dev/null +++ b/src/main/java/org/spongepowered/api/resource/Resource.java @@ -0,0 +1,132 @@ +/* + * This file is part of SpongeAPI, licensed under the MIT License (MIT). + * + * Copyright (c) SpongePowered + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.spongepowered.api.resource; + +import org.spongepowered.api.data.persistence.DataFormat; +import org.spongepowered.api.data.persistence.DataFormats; +import org.spongepowered.api.data.persistence.DataView; +import org.spongepowered.api.resource.pack.PackInfo; +import org.spongepowered.api.resource.pack.PackList; + +import java.io.BufferedReader; +import java.io.Closeable; +import java.io.IOException; +import java.io.InputStream; +import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; +import java.util.Optional; +import java.util.stream.Stream; + +/** + * A resource can represent any kind of loaded data. It can be a file on the filesystem, a network location, or + * even generated at runtime. Use {@link #getInputStream()} to load the data held by a resource. + */ +public interface Resource extends Closeable { + + /** + * Gets the path of this resource. + * + * @return The path + */ + ResourcePath getPath(); + + /** + * Gets the name of the {@link PackInfo pack} which owns this resource. To + * get the instance, feed the returned value to + * {@link PackList#get(String)}. + * + * @return The parent pack. + * @see PackList#get(String) + */ + String getPack(); + + /** + * Returns the {@link InputStream} of this resource. Multiple calls to this + * method will not return a new object. To get a new object, get a new + * resource. + * + * @return The input stream + */ + InputStream getInputStream(); + + /** + * Gets the metadata for this resource. + * + * @return The metadata or {@link Optional#empty() empty} if it doesn't exist. + */ + Optional getMetadata(String name) throws IOException; + + /** + * Creates a new {@link BufferedReader} from this resource's InputStream. + * + * @param charset The charset to use, usually utf-8 + * @return The BufferedReader + */ + BufferedReader newBufferedReader(Charset charset); + + /** + * Reads the resource as text. + * + * @param charset The charset of the text, usually utf-8 + * @return The text of the resource + * @throws IOException If an I/O error occurs + * @see StandardCharsets + */ + String readString(Charset charset) throws IOException; + + /** + * Reads all the toBytes from this resource and returns them in a byte array. + * + * @return The toBytes of the resource + * @throws IOException If an I/O error occurs + */ + byte[] readBytes() throws IOException; + + /** + * Reads the resource and returns a {@link DataView} which corresponds to + * the appropriate {@link DataFormat}. + * + * @param format The data format to use + * @return The data view + * @throws IOException If an I/O error occurs + * @see DataFormats + */ + DataView readDataView(DataFormat format) throws IOException; + + /** + * Reads the resource as text and returns a stream of readLines. + * + *

Just like {@link BufferedReader#lines()}, the stream will wrap any + * {@link IOException} thrown in an {@link java.io.UncheckedIOException}. + *

+ * + * @param charset The charset of the text, usually utf-8 + * @return A stream of readLines of the resource + * @see StandardCharsets + * @see BufferedReader#lines() + */ + Stream lines(Charset charset); + +} diff --git a/src/main/java/org/spongepowered/api/resource/ResourceManager.java b/src/main/java/org/spongepowered/api/resource/ResourceManager.java new file mode 100644 index 00000000000..6ad6496921d --- /dev/null +++ b/src/main/java/org/spongepowered/api/resource/ResourceManager.java @@ -0,0 +1,96 @@ +/* + * This file is part of SpongeAPI, licensed under the MIT License (MIT). + * + * Copyright (c) SpongePowered + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.spongepowered.api.resource; + +import org.spongepowered.api.resource.pack.Pack; +import org.spongepowered.api.util.CloseableList; + +import java.io.Closeable; +import java.io.IOException; +import java.util.Collection; +import java.util.function.Predicate; + +/** + * The resource manager is in charge of loading {@link Resource Resources} and + * {@link Pack Data Packs}. On the client, there can also be resource packs. + *

+ * Packs are stacked on top of each other, so they will override and replace + * resources in packs which are a lower priority. + */ +public interface ResourceManager { + + /** + * Gets a loaded {@link Resource resource} at the given path, or throws an + * exception if it doesn't exist. + * + *

Resource implements {@link Closeable}, so remember to close it. Example:

+ * + *
+     *     try (Resource res = resourceManager.load(path)) {
+     *         InputStream in = res.getInputStream();
+     *     }
+     * 
+ * + * @param path The path to the resource + * @return The resource + * @throws IOException If the resource could not be read + * @throws java.io.FileNotFoundException If the file does not exist + */ + Resource load(ResourcePath path) throws IOException; + + /** + * Gets all loaded {@link Resource resources} at the given path from all + * loaded {@link Pack packs}. + * + *

+ * All the resources in the list need to be closed. To assist in this, you + * can wrap the entire list inside a try-with-resources block. Example:

+ * + *
+     *     try (CloseableList<Resource> resources = resourceManager.loadAll(path)) {
+     *         for (Resource res : resources) {
+     *             InputStream in = res.getInputStream();
+     *         }
+     *     }
+     * 
+ * + * @param path The path to the resource + * @return The list of all resources at the path + * @throws IOException If a resource could not be read + * @throws java.io.FileNotFoundException If there are no resources at the path + */ + CloseableList loadAll(ResourcePath path) throws IOException; + + /** + * Finds all the {@link ResourcePath resource paths} from all namespaces + * with the given path prefix and matches the filter {@link Predicate}. + * + * @param pathPrefix The prefix of the paths + * @param pathFilter The filter all paths must pass + * @return The list of matching paths + */ + Collection find(String pathPrefix, Predicate pathFilter); + +} diff --git a/src/main/java/org/spongepowered/api/resource/ResourcePath.java b/src/main/java/org/spongepowered/api/resource/ResourcePath.java new file mode 100644 index 00000000000..3b6f084da57 --- /dev/null +++ b/src/main/java/org/spongepowered/api/resource/ResourcePath.java @@ -0,0 +1,112 @@ +/* + * This file is part of SpongeAPI, licensed under the MIT License (MIT). + * + * Copyright (c) SpongePowered + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.spongepowered.api.resource; + +import org.spongepowered.api.Sponge; +import org.spongepowered.api.plugin.PluginContainer; +import org.spongepowered.api.util.ResettableBuilder; + +import java.util.Collection; +import java.util.List; + +public interface ResourcePath extends Comparable { + + String SEPARATOR = "/"; + + /** + * Creates a new {@link Builder} for creating {@link ResourcePath}s. The builder + * can be used for creating keys based on {@link PluginContainer}s, {@link Object}s + * of plugins, and {@link String} namespaces. + * + * @return The new builder instance + */ + static Builder builder() { + return Sponge.getRegistry().getBuilderRegistry().provideBuilder(Builder.class); + } + + /** + * Creates a catalog key. + * + * @param namespace The namespace + * @param value The value + * @return A new catalog key + */ + static ResourcePath of(final String namespace, final String value) { + return builder().namespace(namespace).path(value).build(); + } + + /** + * Creates a catalog key + * + * @param container The container + * @param value The value + * @return A new catalog key + */ + static ResourcePath of(final PluginContainer container, final String value) { + return builder().namespace(container).path(value).build(); + } + + /** + * Resolves a catalog key from a string. + * + *

If no namespace is found in {@code string} then + * {@link org.spongepowered.api.CatalogKey#MINECRAFT_NAMESPACE} will be the namespace.

+ * + * @param value The value + * @return A new catalog key + */ + static ResourcePath resolve(final String value) { + return builder().path(value).build(); + } + + String getNamespace(); + + String getPath(); + + List getPathParts(); + + ResourcePath getParent(); + + ResourcePath resolve(String... children); + + default Builder copy() { + return builder().namespace(this.getNamespace()).path(this.getPath()); + } + + interface Builder extends ResettableBuilder { + + Builder namespace(String namespace); + + Builder namespace(PluginContainer container); + + Builder path(String path); + + Builder paths(String... paths); + + Builder paths(Collection paths); + + ResourcePath build(); + } +} diff --git a/src/main/java/org/spongepowered/api/resource/pack/Pack.java b/src/main/java/org/spongepowered/api/resource/pack/Pack.java new file mode 100644 index 00000000000..f806883cc19 --- /dev/null +++ b/src/main/java/org/spongepowered/api/resource/pack/Pack.java @@ -0,0 +1,135 @@ +/* + * This file is part of SpongeAPI, licensed under the MIT License (MIT). + * + * Copyright (c) SpongePowered + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.spongepowered.api.resource.pack; + +import org.spongepowered.api.Sponge; +import org.spongepowered.api.data.persistence.DataView; +import org.spongepowered.api.plugin.PluginContainer; +import org.spongepowered.api.resource.Resource; +import org.spongepowered.api.resource.ResourcePath; +import org.spongepowered.api.util.Nameable; + +import java.io.Closeable; +import java.io.IOException; +import java.io.InputStream; +import java.nio.file.Path; +import java.util.Collection; +import java.util.Optional; +import java.util.Set; +import java.util.function.Predicate; +import java.util.function.Supplier; + +/** + * A resource pack or data pack can contain several {@link Resource resources}. + * A pack con contain both assets and data. + * + * @see
Minecraft Wiki/Resource Packs + */ +public interface Pack extends Nameable, Closeable { + + /** + * Creates a new pack from a file. The pack's name will be the file's name. + * + * @param path The path to the file to turn into a pack + * @return The supplier to create a new pack. + */ + static Supplier fromPath(Path path) { + return Sponge.getRegistry().getFactoryRegistry().provideFactory(Factory.class).fromPath(path); + } + + /** + * Creates a new pack from a plugin's source. + * + * @param pluginContainer The plugin + * @return The supplier to create a new pack + * @see PluginContainer#getSource() + */ + static Supplier fromPlugin(PluginContainer pluginContainer) { + return Sponge.getRegistry().getFactoryRegistry().provideFactory(Factory.class).fromPlugin(pluginContainer); + } + + /** + * Gets a resource from this pack if it exists. No other packs will be + * queried. + * + * @param type The type of pack to query + * @param path The domain named path + * @return The resource + * @see PackTypes + */ + InputStream openStream(PackType type, ResourcePath path) throws IOException; + + /** + * Finds all the {@link ResourcePath}s in this pack matching the + * prefix and filter, and within the given depth. + * + * @param type The type of pack resource to find + * @param prefix The prefix of the path + * @param depth The depth to search + * @param filter The filter every path must match + * @return A collection of matching paths + * @see PackTypes + */ + Collection find(PackType type, String prefix, int depth, Predicate filter); + + /** + * Tests if this pack contains an entry at the given {@link ResourcePath}. + * + * @param type The pack type to query + * @param path The resource path + * @return True if it exists, false if it does not + * @see PackTypes + */ + boolean exists(PackType type, ResourcePath path); + + /** + * Gets the namespaces known by this pack. + *

+ * TODO: Does this need to be exposed? + * + * @param type The pack type to query + * @return The set of namespaces + * @see PackTypes + */ + Set getNamespaces(PackType type); + + /** + * Gets the metadata of this pack. The {@link DataView} represented is of + * the pack.json file in the pack root. If the pack does not contain a + * pack.json, {@link Optional#empty()} is returned. + * + * @param name The name of the metadata section + * @return The metadata if it exists + */ + Optional getMetadata(String name) throws IOException; + + interface Factory { + + Supplier fromPath(Path path); + + Supplier fromPlugin(PluginContainer pluginContainer); + + } +} diff --git a/src/main/java/org/spongepowered/api/resource/pack/PackDiscoverer.java b/src/main/java/org/spongepowered/api/resource/pack/PackDiscoverer.java new file mode 100644 index 00000000000..3751423a968 --- /dev/null +++ b/src/main/java/org/spongepowered/api/resource/pack/PackDiscoverer.java @@ -0,0 +1,50 @@ +/* + * This file is part of SpongeAPI, licensed under the MIT License (MIT). + * + * Copyright (c) SpongePowered + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.spongepowered.api.resource.pack; + +import java.util.Map; +import java.util.Optional; +import java.util.function.Supplier; + +public interface PackDiscoverer { + + void populate(Map packInfos, PackInfoFactory factory); + + @FunctionalInterface + interface PackInfoFactory { + /** + * Creates a new {@link PackInfo} from the given arguments. If the pack + * does not have valid metadata, an empty optional is returned. + * + * @param name The name of the pack. + * @param forced Whether the pack should always be loaded + * @param pack The supplier for the pack + * @param priority The priority, first or last + * @return The new pack info definition + */ + Optional createPackInfo(String name, boolean forced, Supplier pack, PackInfo.Priority priority); + } + +} diff --git a/src/main/java/org/spongepowered/api/resource/pack/PackInfo.java b/src/main/java/org/spongepowered/api/resource/pack/PackInfo.java new file mode 100644 index 00000000000..c388d07bceb --- /dev/null +++ b/src/main/java/org/spongepowered/api/resource/pack/PackInfo.java @@ -0,0 +1,47 @@ +/* + * This file is part of SpongeAPI, licensed under the MIT License (MIT). + * + * Copyright (c) SpongePowered + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.spongepowered.api.resource.pack; + +import org.spongepowered.api.text.Text; +import org.spongepowered.api.util.Nameable; + +public interface PackInfo extends Nameable { + + Text getDisplayName(boolean enabled); + + PackVersion getVersion(); + + Pack getPack(); + + boolean isForced(); + + boolean isLocked(); + + Priority getPriority(); + + enum Priority { + FIRST, LAST + } +} diff --git a/src/main/java/org/spongepowered/api/resource/pack/PackList.java b/src/main/java/org/spongepowered/api/resource/pack/PackList.java new file mode 100644 index 00000000000..b87adb93d7c --- /dev/null +++ b/src/main/java/org/spongepowered/api/resource/pack/PackList.java @@ -0,0 +1,41 @@ +/* + * This file is part of SpongeAPI, licensed under the MIT License (MIT). + * + * Copyright (c) SpongePowered + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.spongepowered.api.resource.pack; + +import java.util.Collection; +import java.util.Optional; + +public interface PackList { + + Collection all(); + + Collection disabled(); + + Collection enabled(); + + Optional get(String name); + + void addPackDiscoverer(PackDiscoverer discoverer); +} diff --git a/src/main/java/org/spongepowered/api/resource/pack/PackType.java b/src/main/java/org/spongepowered/api/resource/pack/PackType.java new file mode 100644 index 00000000000..92cc2885040 --- /dev/null +++ b/src/main/java/org/spongepowered/api/resource/pack/PackType.java @@ -0,0 +1,33 @@ +/* + * This file is part of SpongeAPI, licensed under the MIT License (MIT). + * + * Copyright (c) SpongePowered + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.spongepowered.api.resource.pack; + +import org.spongepowered.api.CatalogType; +import org.spongepowered.api.util.annotation.CatalogedBy; + +@CatalogedBy(PackTypes.class) +public interface PackType extends CatalogType { + +} diff --git a/src/main/java/org/spongepowered/api/resource/pack/PackTypes.java b/src/main/java/org/spongepowered/api/resource/pack/PackTypes.java new file mode 100644 index 00000000000..fa1f26b3540 --- /dev/null +++ b/src/main/java/org/spongepowered/api/resource/pack/PackTypes.java @@ -0,0 +1,44 @@ +/* + * This file is part of SpongeAPI, licensed under the MIT License (MIT). + * + * Copyright (c) SpongePowered + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.spongepowered.api.resource.pack; + +import org.spongepowered.api.Sponge; + +import java.util.function.Supplier; + +public final class PackTypes { + + // SORTFIELDS:ON + + public static final Supplier CLIENT_RESOURCES = Sponge.getRegistry().getCatalogRegistry().provideSupplier(PackType.class, "CLIENT_RESOURCES"); + + public static final Supplier SERVER_DATA = Sponge.getRegistry().getCatalogRegistry().provideSupplier(PackType.class, "SERVER_DATA"); + + // SORTFIELDS:OFF + + private PackTypes() { + } + +} diff --git a/src/main/java/org/spongepowered/api/resource/pack/PackVersion.java b/src/main/java/org/spongepowered/api/resource/pack/PackVersion.java new file mode 100644 index 00000000000..ac59a6f93b7 --- /dev/null +++ b/src/main/java/org/spongepowered/api/resource/pack/PackVersion.java @@ -0,0 +1,43 @@ +/* + * This file is part of SpongeAPI, licensed under the MIT License (MIT). + * + * Copyright (c) SpongePowered + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.spongepowered.api.resource.pack; + +import org.spongepowered.api.Sponge; +import org.spongepowered.api.util.ResettableBuilder; + +public interface PackVersion { + + boolean isCompatible(); + + static PackVersion of(int version) { + return Sponge.getRegistry().getBuilderRegistry().provideBuilder(Builder.class).version(version).build(); + } + + interface Builder extends ResettableBuilder { + Builder version(int version); + + PackVersion build(); + } +} diff --git a/src/main/java/org/spongepowered/api/resource/pack/package-info.java b/src/main/java/org/spongepowered/api/resource/pack/package-info.java new file mode 100644 index 00000000000..6a63a729bd2 --- /dev/null +++ b/src/main/java/org/spongepowered/api/resource/pack/package-info.java @@ -0,0 +1,26 @@ +/* + * This file is part of SpongeAPI, licensed under the MIT License (MIT). + * + * Copyright (c) SpongePowered + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +@org.checkerframework.framework.qual.DefaultQualifier(org.checkerframework.checker.nullness.qual.NonNull.class) +package org.spongepowered.api.resource.pack; diff --git a/src/main/java/org/spongepowered/api/asset/package-info.java b/src/main/java/org/spongepowered/api/resource/package-info.java similarity index 97% rename from src/main/java/org/spongepowered/api/asset/package-info.java rename to src/main/java/org/spongepowered/api/resource/package-info.java index bbc2a752e3c..27a32ffe7a9 100644 --- a/src/main/java/org/spongepowered/api/asset/package-info.java +++ b/src/main/java/org/spongepowered/api/resource/package-info.java @@ -23,4 +23,4 @@ * THE SOFTWARE. */ @org.checkerframework.framework.qual.DefaultQualifier(org.checkerframework.checker.nullness.qual.NonNull.class) -package org.spongepowered.api.asset; +package org.spongepowered.api.resource; diff --git a/src/main/java/org/spongepowered/api/asset/AssetId.java b/src/main/java/org/spongepowered/api/util/CloseableList.java similarity index 67% rename from src/main/java/org/spongepowered/api/asset/AssetId.java rename to src/main/java/org/spongepowered/api/util/CloseableList.java index 919c936feaf..fe119bae21f 100644 --- a/src/main/java/org/spongepowered/api/asset/AssetId.java +++ b/src/main/java/org/spongepowered/api/util/CloseableList.java @@ -22,30 +22,22 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -package org.spongepowered.api.asset; +package org.spongepowered.api.util; -import com.google.inject.BindingAnnotation; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; +import java.io.Closeable; +import java.util.List; /** - * Provides an injection for {@link Asset}s in plugins. + * A list, containing closeable elements. All elements can be closed by calling + * {@link #close()}. + * + * @param The closeable type */ -@Deprecated -@BindingAnnotation -@Retention(RetentionPolicy.RUNTIME) -@Target({ElementType.FIELD, ElementType.PARAMETER}) -public @interface AssetId { +public interface CloseableList extends List, Closeable { /** - * The path to the {@link Asset} in the asset folder of the plugin. - * - * @return The path to the asset - * @see AssetManager#getAsset(String) + * Quietly closes all elements in this list. */ - String value(); - + @Override + void close(); } From a501fae0b0553265189fa1b7b0b51ada1739d238 Mon Sep 17 00:00:00 2001 From: Matthew Messinger Date: Sun, 28 Jun 2020 17:52:13 -0400 Subject: [PATCH 03/19] Updates to resources I did most of this a few months ago. I don't remember all the specifics. --- .../api/event/resource/PackEvent.java | 57 ++++++ .../api/event/resource/ResourceEvent.java | 74 +++++++ .../resource/ReloadableResourceManager.java | 46 +++++ .../spongepowered/api/resource/Resource.java | 12 +- .../api/resource/ResourceManager.java | 15 +- .../api/resource/ResourcePath.java | 93 ++++++++- .../api/resource/ResourcePathException.java | 42 ++++ .../api/resource/ResourceReloadListener.java | 181 ++++++++++++++++++ .../api/resource/meta/MetaParseException.java | 40 ++++ .../api/resource/meta/MetaSection.java | 38 ++++ .../api/resource/meta/MetaSections.java | 40 ++++ .../api/resource/meta/PackMeta.java | 34 ++++ .../api/resource/pack/MutablePackList.java | 30 +++ .../spongepowered/api/resource/pack/Pack.java | 14 +- .../api/resource/pack/PackInfo.java | 24 +++ .../api/resource/pack/PackList.java | 1 - .../api/resource/pack/PackVersion.java | 15 +- 17 files changed, 724 insertions(+), 32 deletions(-) create mode 100644 src/main/java/org/spongepowered/api/event/resource/ResourceEvent.java create mode 100644 src/main/java/org/spongepowered/api/resource/ReloadableResourceManager.java create mode 100644 src/main/java/org/spongepowered/api/resource/ResourcePathException.java create mode 100644 src/main/java/org/spongepowered/api/resource/ResourceReloadListener.java create mode 100644 src/main/java/org/spongepowered/api/resource/meta/MetaParseException.java create mode 100644 src/main/java/org/spongepowered/api/resource/meta/MetaSection.java create mode 100644 src/main/java/org/spongepowered/api/resource/meta/MetaSections.java create mode 100644 src/main/java/org/spongepowered/api/resource/meta/PackMeta.java create mode 100644 src/main/java/org/spongepowered/api/resource/pack/MutablePackList.java diff --git a/src/main/java/org/spongepowered/api/event/resource/PackEvent.java b/src/main/java/org/spongepowered/api/event/resource/PackEvent.java index a2f24c61ade..1c7da114d5f 100644 --- a/src/main/java/org/spongepowered/api/event/resource/PackEvent.java +++ b/src/main/java/org/spongepowered/api/event/resource/PackEvent.java @@ -1,7 +1,33 @@ +/* + * This file is part of SpongeAPI, licensed under the MIT License (MIT). + * + * Copyright (c) SpongePowered + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ package org.spongepowered.api.event.resource; import org.spongepowered.api.event.Event; +import org.spongepowered.api.resource.pack.MutablePackList; import org.spongepowered.api.resource.pack.Pack; +import org.spongepowered.api.resource.pack.PackDiscoverer; import org.spongepowered.api.resource.pack.PackList; /** @@ -9,6 +35,37 @@ */ public interface PackEvent extends Event { + /** + * Gets the relevant {@link PackList} for this event. + * + * @return The pack list + */ PackList getPackList(); + /** + * Event for registering {@link PackDiscoverer}s. It is fired sometime during init. + */ + interface RegisterPackDiscoverer extends PackEvent { + + /** + * {@inheritDoc} + *

Returns a {@link MutablePackList} to expose methods for adding listeners.

+ * @return The pack list + */ + @Override + MutablePackList getPackList(); + + /** + * Register event for client resources. + */ + interface Client extends RegisterPackDiscoverer { + } + + /** + * Register event for server data. + */ + interface Server extends RegisterPackDiscoverer { + } + } + } diff --git a/src/main/java/org/spongepowered/api/event/resource/ResourceEvent.java b/src/main/java/org/spongepowered/api/event/resource/ResourceEvent.java new file mode 100644 index 00000000000..42b3c2f2d16 --- /dev/null +++ b/src/main/java/org/spongepowered/api/event/resource/ResourceEvent.java @@ -0,0 +1,74 @@ +/* + * This file is part of SpongeAPI, licensed under the MIT License (MIT). + * + * Copyright (c) SpongePowered + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.spongepowered.api.event.resource; + +import org.spongepowered.api.event.Event; +import org.spongepowered.api.resource.ReloadableResourceManager; +import org.spongepowered.api.resource.ResourceReloadListener; +import org.spongepowered.api.resource.Resource; +import org.spongepowered.api.resource.ResourceManager; + +/** + * Base event for {@link Resource}s. + */ +public interface ResourceEvent extends Event { + + /** + * Gets the relevant {@link ResourceManager} for this event. + * + * @return The resource manager + */ + ResourceManager getResourceManager(); + + /** + * Event for registering {@link ResourceReloadListener reload listeners} to the + * {@link ResourceManager}. It is fired sometime during init. + */ + interface RegisterReloadListener extends ResourceEvent { + + /** + * {@inheritDoc} + * + *

The type is a {@link ReloadableResourceManager} to expose methods + * to add reload listeners

+ * + * @return The reloadable resource manager + */ + @Override + ReloadableResourceManager getResourceManager(); + + /** + * Register event for client resources. + */ + interface Client extends RegisterReloadListener { + } + + /** + * Register event for server data. + */ + interface Server extends RegisterReloadListener { + } + } +} diff --git a/src/main/java/org/spongepowered/api/resource/ReloadableResourceManager.java b/src/main/java/org/spongepowered/api/resource/ReloadableResourceManager.java new file mode 100644 index 00000000000..ca8462b92e8 --- /dev/null +++ b/src/main/java/org/spongepowered/api/resource/ReloadableResourceManager.java @@ -0,0 +1,46 @@ +/* + * This file is part of SpongeAPI, licensed under the MIT License (MIT). + * + * Copyright (c) SpongePowered + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.spongepowered.api.resource; + +import org.spongepowered.api.event.resource.ResourceEvent; + +/** + * A {@link ResourceManager} that supports being reloaded. Listeners can be + * added to load assets asynchronously when this happens. + * + *

To register listeners, add them during the + * {@link ResourceEvent.RegisterReloadListener} event.

+ */ +public interface ReloadableResourceManager extends ResourceManager { + + /** + * Adds a reload listener to the resource manager. + * + * @param listener The listener + * @see ResourceReloadListener + */ + void addReloadListener(ResourceReloadListener listener); + +} diff --git a/src/main/java/org/spongepowered/api/resource/Resource.java b/src/main/java/org/spongepowered/api/resource/Resource.java index 173deff6c07..c256db3d9a7 100644 --- a/src/main/java/org/spongepowered/api/resource/Resource.java +++ b/src/main/java/org/spongepowered/api/resource/Resource.java @@ -27,6 +27,8 @@ import org.spongepowered.api.data.persistence.DataFormat; import org.spongepowered.api.data.persistence.DataFormats; import org.spongepowered.api.data.persistence.DataView; +import org.spongepowered.api.resource.meta.MetaSection; +import org.spongepowered.api.resource.meta.MetaSections; import org.spongepowered.api.resource.pack.PackInfo; import org.spongepowered.api.resource.pack.PackList; @@ -71,12 +73,20 @@ public interface Resource extends Closeable { */ InputStream getInputStream(); + /** + * Checks whether this resource has metadata or not. + * + * @return True if this resource has metadata, false otherwise + */ + boolean hasMetadata(); + /** * Gets the metadata for this resource. * * @return The metadata or {@link Optional#empty() empty} if it doesn't exist. + * @see MetaSections */ - Optional getMetadata(String name) throws IOException; + Optional getMetadata(MetaSection name); /** * Creates a new {@link BufferedReader} from this resource's InputStream. diff --git a/src/main/java/org/spongepowered/api/resource/ResourceManager.java b/src/main/java/org/spongepowered/api/resource/ResourceManager.java index 6ad6496921d..994990a5629 100644 --- a/src/main/java/org/spongepowered/api/resource/ResourceManager.java +++ b/src/main/java/org/spongepowered/api/resource/ResourceManager.java @@ -33,16 +33,15 @@ import java.util.function.Predicate; /** - * The resource manager is in charge of loading {@link Resource Resources} and - * {@link Pack Data Packs}. On the client, there can also be resource packs. - *

- * Packs are stacked on top of each other, so they will override and replace - * resources in packs which are a lower priority. + * The resource manager is in charge of loading {@link Resource Resources}. + * + *

Packs are stacked on top of each other, so they will override and replace + * resources in packs which are a lower priority.

*/ public interface ResourceManager { /** - * Gets a loaded {@link Resource resource} at the given path, or throws an + * Loads the {@link Resource resource} at the given path, or throws an * exception if it doesn't exist. * *

Resource implements {@link Closeable}, so remember to close it. Example:

@@ -61,8 +60,8 @@ public interface ResourceManager { Resource load(ResourcePath path) throws IOException; /** - * Gets all loaded {@link Resource resources} at the given path from all - * loaded {@link Pack packs}. + * Loads all the {@link Resource resources} at the given path from all + * active {@link Pack packs}. * *

* All the resources in the list need to be closed. To assist in this, you diff --git a/src/main/java/org/spongepowered/api/resource/ResourcePath.java b/src/main/java/org/spongepowered/api/resource/ResourcePath.java index 3b6f084da57..b36cc970574 100644 --- a/src/main/java/org/spongepowered/api/resource/ResourcePath.java +++ b/src/main/java/org/spongepowered/api/resource/ResourcePath.java @@ -69,31 +69,106 @@ static ResourcePath of(final PluginContainer container, final String value) { } /** - * Resolves a catalog key from a string. + * Parses a path from a string. * *

If no namespace is found in {@code string} then - * {@link org.spongepowered.api.CatalogKey#MINECRAFT_NAMESPACE} will be the namespace.

+ * {@code minecraft} will be the namespace.

* * @param value The value * @return A new catalog key */ - static ResourcePath resolve(final String value) { + static ResourcePath parse(final String value) { return builder().path(value).build(); } + /** + * Gets the namespace portion of this resource path. + * + * @return The namespace + */ String getNamespace(); + /** + * Gets the path portion of this resource path. + * + * @return The path + */ String getPath(); + // resolution methods + + /** + * Resolves this resource path's parent. + * + * @return The parent path + * @throws ResourcePathException If the parent normalizes to null + */ + ResourcePath getParent() throws ResourcePathException; + + /** + * Resolves a single file as a child of this path. + * + * @param child The child path's name + * @return The resolved path + * @throws ResourcePathException If the path is invalid or could not be normalized + * @see #resolve(String...) + */ + default ResourcePath resolve(String child) throws ResourcePathException { + return resolve(new String[]{child}); + } + + /** + * Resolves a path from the current location using the specified children. + * + * @param children The children paths + * @return The resolved path + * @throws ResourcePathException If the path is invalid or could not be normalized + */ + ResourcePath resolve(String... children) throws ResourcePathException; + + /** + * @param sibling The sibling's name + * @return The sibling resource path + * @throws ResourcePathException If the path is invalid or could not be normalized + */ + ResourcePath resolveSibling(String sibling) throws ResourcePathException; + + // path utility methods + + /** + * Gets all the parts of this path. i.e. the full path split by {@link #SEPARATOR}. + * + * @return The path parts + */ List getPathParts(); - ResourcePath getParent(); + /** + * Gets the parent of this path or root if it is root. + * + * @return The parent path + */ + String getParentPath(); + + /** + * Gets the name of the file without any parent elements. + * + * @return The file name + */ + String getName(); - ResourcePath resolve(String... children); + /** + * Gets the base name of the file without any parent elements or extensions. + * + * @return The base file name + */ + String getBaseName(); - default Builder copy() { - return builder().namespace(this.getNamespace()).path(this.getPath()); - } + /** + * Gets the extension of the file if any. If the file has no extension, an empty string is returned. + * + * @return The file extension + */ + String getExtension(); interface Builder extends ResettableBuilder { @@ -107,6 +182,6 @@ interface Builder extends ResettableBuilder { Builder paths(Collection paths); - ResourcePath build(); + ResourcePath build() throws ResourcePathException; } } diff --git a/src/main/java/org/spongepowered/api/resource/ResourcePathException.java b/src/main/java/org/spongepowered/api/resource/ResourcePathException.java new file mode 100644 index 00000000000..1346591fb54 --- /dev/null +++ b/src/main/java/org/spongepowered/api/resource/ResourcePathException.java @@ -0,0 +1,42 @@ +/* + * This file is part of SpongeAPI, licensed under the MIT License (MIT). + * + * Copyright (c) SpongePowered + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.spongepowered.api.resource; + +/** + * An exception thrown when a {@link ResourcePath} could not be created. + */ +public class ResourcePathException extends RuntimeException { + public ResourcePathException(String message) { + super(message); + } + + public ResourcePathException(Throwable e) { + super(e); + } + + public ResourcePathException(String message, Throwable e) { + super(message, e); + } +} diff --git a/src/main/java/org/spongepowered/api/resource/ResourceReloadListener.java b/src/main/java/org/spongepowered/api/resource/ResourceReloadListener.java new file mode 100644 index 00000000000..4397f69d6c9 --- /dev/null +++ b/src/main/java/org/spongepowered/api/resource/ResourceReloadListener.java @@ -0,0 +1,181 @@ +/* + * This file is part of SpongeAPI, licensed under the MIT License (MIT). + * + * Copyright (c) SpongePowered + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.spongepowered.api.resource; + +import org.spongepowered.api.Sponge; +import org.spongepowered.api.data.persistence.DataView; + +import java.util.Map; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.Executor; + +/** + * A low level async reload listener. + * + *

There are two stages when reloading resources. The first is done asynchronously, so keep + * that in mind when interacting with game objects. The second is done synchronously on the game thread. This stage will + * not execute until all listeners have completed their first stage.

+ * + *

In most circumstances, you should prefer to create a more specific use-case instance using the factory instead of + * implementing this interface directly.

+ * + *

Example usage:

+ * + *
+ *     public class MyAsyncReloadListener implements ReloadListener {
+ *         public CompletableFuture<Void> onReload(ReloadStage stage, ResourceManager manager, Executor workExecutor, Executor gameExecutor) {
+ *             return CompletableFuture
+ *                 // create a future in the work stage
+ *                 .supplyAsync(() -> {
+ *                     // load things async in work executor
+ *                     return things;
+ *                 }, workExecutor)
+ *                 // wait for other listeners to complete the work stage.
+ *                 .thenCompose(stage::markComplete)
+ *                 // create a future in the game stage
+ *                 .thenAcceptAsync(thing -> {
+ *                      // apply things sync in game executor
+ *                 }, gameExecutor);
+ *         }
+ *     }
+ * 
+ */ +public interface ResourceReloadListener { + + static Factory factory() { + return Sponge.getRegistry().getFactoryRegistry().provideFactory(Factory.class); + } + + /** + * Reloads the resource manager asynchronously. + * + * @param stage The reload stage, use when done with async + * @param manager The resource manager + * @param workExecutor The async work executor + * @param gameExecutor The sync game executor + * @return A completable future of the work being done + */ + CompletableFuture onReload(AsyncStage stage, ResourceManager manager, Executor workExecutor, Executor gameExecutor); + + /** + * The stage object used to notify that the listener's async stage is complete. + */ + interface AsyncStage { + + /** + * Marks this async stage as complete and waits for the other listeners to complete. + * + * @param result The result object + * @param The type of the result + * @return The future + */ + CompletableFuture markComplete(T result); + } + + interface Factory { + /** + * Creates a simple reload listener that reloads resources on the main thread. + * + * @param listener The listener implementation + * @return The listener + */ + ResourceReloadListener simple(SimpleReloadListener listener); + + /** + * Creates a prepared reload listener that loads resources in the work thread and apply them in the main + * thread. + * + * @param listener The listener implementation + * @param The type of resource to be prepared + * @return The listener + */ + ResourceReloadListener prepared(PreparedReloadListener listener); + + /** + * Creates a data tree reload listener that loads every json file in a folder from each namespace. + * + * @param path The path of the folder to load + * @param listener The listener implementation + * @return The listener + */ + ResourceReloadListener dataTree(String path, DataTreeReloadListener listener); + } + + /** + * Reload listener for resources that need to be loaded and applied on the + * main thread. + * + *

This listener may cause longer reload times.

+ */ + interface SimpleReloadListener { + /** + * Called in the game executor to reload resources. + * + * @param manager The resource manager + */ + void onReload(ResourceManager manager); + } + + /** + * Reload listener for resources that take time to create, but need to be + * applied on the main thread. + * + * @param The type of the processed resource + */ + interface PreparedReloadListener { + /** + * Prepares the resources on the work thread. + * + * @param manager The resource manager + * @return The prepared object + */ + T prepare(ResourceManager manager); + + /** + * Applies the resources on the main thread. + * + * @param object The prepared object + * @param manager The resource manager + */ + void apply(T object, ResourceManager manager); + } + + /** + * Reload listener for a tree of json files. Resources from all namespaces + * are loaded. + * + *

Json files are loaded on the work thread and applied in the main + * thread.

+ */ + interface DataTreeReloadListener { + /** + * Applies the data in the game executor. + * + * @param dataTree The mapping of paths to json objects + * @param manager The resource manager + */ + void apply(Map dataTree, ResourceManager manager); + } +} diff --git a/src/main/java/org/spongepowered/api/resource/meta/MetaParseException.java b/src/main/java/org/spongepowered/api/resource/meta/MetaParseException.java new file mode 100644 index 00000000000..7ffc99a46a3 --- /dev/null +++ b/src/main/java/org/spongepowered/api/resource/meta/MetaParseException.java @@ -0,0 +1,40 @@ +/* + * This file is part of SpongeAPI, licensed under the MIT License (MIT). + * + * Copyright (c) SpongePowered + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.spongepowered.api.resource.meta; + +public class MetaParseException extends RuntimeException { + + public MetaParseException(String message) { + super(message); + } + + public MetaParseException(String message, Throwable t) { + super(message, t); + } + + public MetaParseException(Throwable t) { + super(t); + } +} diff --git a/src/main/java/org/spongepowered/api/resource/meta/MetaSection.java b/src/main/java/org/spongepowered/api/resource/meta/MetaSection.java new file mode 100644 index 00000000000..b369c2c77b8 --- /dev/null +++ b/src/main/java/org/spongepowered/api/resource/meta/MetaSection.java @@ -0,0 +1,38 @@ +/* + * This file is part of SpongeAPI, licensed under the MIT License (MIT). + * + * Copyright (c) SpongePowered + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.spongepowered.api.resource.meta; + +import org.spongepowered.api.CatalogType; +import org.spongepowered.api.data.persistence.DataQuery; +import org.spongepowered.api.data.persistence.DataView; +import org.spongepowered.api.util.annotation.CatalogedBy; + +@CatalogedBy(MetaSections.class) +public interface MetaSection extends CatalogType { + + DataQuery getQuery(); + + T deserialize(DataView data) throws MetaParseException; +} diff --git a/src/main/java/org/spongepowered/api/resource/meta/MetaSections.java b/src/main/java/org/spongepowered/api/resource/meta/MetaSections.java new file mode 100644 index 00000000000..84d5b8ac826 --- /dev/null +++ b/src/main/java/org/spongepowered/api/resource/meta/MetaSections.java @@ -0,0 +1,40 @@ +/* + * This file is part of SpongeAPI, licensed under the MIT License (MIT). + * + * Copyright (c) SpongePowered + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.spongepowered.api.resource.meta; + +import org.spongepowered.api.Sponge; + +import java.util.function.Supplier; + +public class MetaSections { + + // SORTFIELDS:ON + + private static final Supplier> PACK = Sponge.getRegistry().getCatalogRegistry().provideSupplier(MetaSection.class, "pack/pack"); + + // SORTFIELDS:OFF + + private MetaSections() {} +} diff --git a/src/main/java/org/spongepowered/api/resource/meta/PackMeta.java b/src/main/java/org/spongepowered/api/resource/meta/PackMeta.java new file mode 100644 index 00000000000..57f07d6ca4f --- /dev/null +++ b/src/main/java/org/spongepowered/api/resource/meta/PackMeta.java @@ -0,0 +1,34 @@ +/* + * This file is part of SpongeAPI, licensed under the MIT License (MIT). + * + * Copyright (c) SpongePowered + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.spongepowered.api.resource.meta; + +import org.spongepowered.api.text.Text; + +public interface PackMeta { + + Text getDescription(); + + int getPackFormat(); +} diff --git a/src/main/java/org/spongepowered/api/resource/pack/MutablePackList.java b/src/main/java/org/spongepowered/api/resource/pack/MutablePackList.java new file mode 100644 index 00000000000..83db6aab34a --- /dev/null +++ b/src/main/java/org/spongepowered/api/resource/pack/MutablePackList.java @@ -0,0 +1,30 @@ +/* + * This file is part of SpongeAPI, licensed under the MIT License (MIT). + * + * Copyright (c) SpongePowered + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.spongepowered.api.resource.pack; + +public interface MutablePackList extends PackList { + + void addPackDiscoverer(PackDiscoverer discoverer); +} diff --git a/src/main/java/org/spongepowered/api/resource/pack/Pack.java b/src/main/java/org/spongepowered/api/resource/pack/Pack.java index f806883cc19..95d6e2d8d92 100644 --- a/src/main/java/org/spongepowered/api/resource/pack/Pack.java +++ b/src/main/java/org/spongepowered/api/resource/pack/Pack.java @@ -25,10 +25,11 @@ package org.spongepowered.api.resource.pack; import org.spongepowered.api.Sponge; -import org.spongepowered.api.data.persistence.DataView; import org.spongepowered.api.plugin.PluginContainer; import org.spongepowered.api.resource.Resource; import org.spongepowered.api.resource.ResourcePath; +import org.spongepowered.api.resource.meta.MetaParseException; +import org.spongepowered.api.resource.meta.MetaSection; import org.spongepowered.api.util.Nameable; import java.io.Closeable; @@ -116,14 +117,15 @@ static Supplier fromPlugin(PluginContainer pluginContainer) { Set getNamespaces(PackType type); /** - * Gets the metadata of this pack. The {@link DataView} represented is of - * the pack.json file in the pack root. If the pack does not contain a - * pack.json, {@link Optional#empty()} is returned. + * Gets the metadata of this pack. The {@link MetaSection} deserializes a + * section of the pack.mcmeta file in the pack root. If the pack.mcmeta + * does not contain the query defined in the section, {@link Optional#empty()} is returned. * - * @param name The name of the metadata section + * @param section The name metadata section type * @return The metadata if it exists + * @throws MetaParseException If the metadata could not be parsed */ - Optional getMetadata(String name) throws IOException; + Optional getMetadata(MetaSection section) throws MetaParseException; interface Factory { diff --git a/src/main/java/org/spongepowered/api/resource/pack/PackInfo.java b/src/main/java/org/spongepowered/api/resource/pack/PackInfo.java index c388d07bceb..d3e1de8d088 100644 --- a/src/main/java/org/spongepowered/api/resource/pack/PackInfo.java +++ b/src/main/java/org/spongepowered/api/resource/pack/PackInfo.java @@ -33,12 +33,36 @@ public interface PackInfo extends Nameable { PackVersion getVersion(); + /** + * Gets the pack associated with this pack info. + * + *

The returned pack may be a new instance or cached, depending on the + * implementation.

+ * + * @return The pack + */ Pack getPack(); + /** + * Gets whether this pack is forced to be enabled at all times. + * + * @return True if forced enabled, false if disable-able + */ boolean isForced(); + /** + * Gets whether this pack is order locked on top or bottom. + * + * @return True if order locked, false if order-able + * @see #getPriority() + */ boolean isLocked(); + /** + * Gets the priority of this pack, first or last. + * + * @return The priority + */ Priority getPriority(); enum Priority { diff --git a/src/main/java/org/spongepowered/api/resource/pack/PackList.java b/src/main/java/org/spongepowered/api/resource/pack/PackList.java index b87adb93d7c..5f369dcab4d 100644 --- a/src/main/java/org/spongepowered/api/resource/pack/PackList.java +++ b/src/main/java/org/spongepowered/api/resource/pack/PackList.java @@ -37,5 +37,4 @@ public interface PackList { Optional get(String name); - void addPackDiscoverer(PackDiscoverer discoverer); } diff --git a/src/main/java/org/spongepowered/api/resource/pack/PackVersion.java b/src/main/java/org/spongepowered/api/resource/pack/PackVersion.java index ac59a6f93b7..5396906574c 100644 --- a/src/main/java/org/spongepowered/api/resource/pack/PackVersion.java +++ b/src/main/java/org/spongepowered/api/resource/pack/PackVersion.java @@ -25,19 +25,20 @@ package org.spongepowered.api.resource.pack; import org.spongepowered.api.Sponge; -import org.spongepowered.api.util.ResettableBuilder; public interface PackVersion { - boolean isCompatible(); + boolean isOlder(); + + boolean isCurrent(); + + boolean isNewer(); static PackVersion of(int version) { - return Sponge.getRegistry().getBuilderRegistry().provideBuilder(Builder.class).version(version).build(); + return Sponge.getRegistry().getFactoryRegistry().provideFactory(Factory.class).getCompatibility(version); } - interface Builder extends ResettableBuilder { - Builder version(int version); - - PackVersion build(); + interface Factory { + PackVersion getCompatibility(int version); } } From aef251bc0eb65c00c16f88b7f653f89573b37371 Mon Sep 17 00:00:00 2001 From: Matthew Messinger Date: Sun, 28 Jun 2020 18:29:27 -0400 Subject: [PATCH 04/19] Remove leftover empty file from rebase --- src/main/java/org/spongepowered/api/asset/Asset.java | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 src/main/java/org/spongepowered/api/asset/Asset.java diff --git a/src/main/java/org/spongepowered/api/asset/Asset.java b/src/main/java/org/spongepowered/api/asset/Asset.java deleted file mode 100644 index e69de29bb2d..00000000000 From ce9b75c52172b3084b768631b853fb3e54325810 Mon Sep 17 00:00:00 2001 From: Matthew Messinger Date: Sun, 28 Jun 2020 18:32:34 -0400 Subject: [PATCH 05/19] Fix compile errors related to PluginContainer --- .../java/org/spongepowered/api/resource/ResourcePath.java | 2 +- src/main/java/org/spongepowered/api/resource/pack/Pack.java | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/spongepowered/api/resource/ResourcePath.java b/src/main/java/org/spongepowered/api/resource/ResourcePath.java index b36cc970574..0c54e381cbe 100644 --- a/src/main/java/org/spongepowered/api/resource/ResourcePath.java +++ b/src/main/java/org/spongepowered/api/resource/ResourcePath.java @@ -25,8 +25,8 @@ package org.spongepowered.api.resource; import org.spongepowered.api.Sponge; -import org.spongepowered.api.plugin.PluginContainer; import org.spongepowered.api.util.ResettableBuilder; +import org.spongepowered.plugin.PluginContainer; import java.util.Collection; import java.util.List; diff --git a/src/main/java/org/spongepowered/api/resource/pack/Pack.java b/src/main/java/org/spongepowered/api/resource/pack/Pack.java index 95d6e2d8d92..6c9616b74df 100644 --- a/src/main/java/org/spongepowered/api/resource/pack/Pack.java +++ b/src/main/java/org/spongepowered/api/resource/pack/Pack.java @@ -25,12 +25,12 @@ package org.spongepowered.api.resource.pack; import org.spongepowered.api.Sponge; -import org.spongepowered.api.plugin.PluginContainer; import org.spongepowered.api.resource.Resource; import org.spongepowered.api.resource.ResourcePath; import org.spongepowered.api.resource.meta.MetaParseException; import org.spongepowered.api.resource.meta.MetaSection; import org.spongepowered.api.util.Nameable; +import org.spongepowered.plugin.PluginContainer; import java.io.Closeable; import java.io.IOException; @@ -65,7 +65,7 @@ static Supplier fromPath(Path path) { * * @param pluginContainer The plugin * @return The supplier to create a new pack - * @see PluginContainer#getSource() + * @see PluginContainer#getFile() */ static Supplier fromPlugin(PluginContainer pluginContainer) { return Sponge.getRegistry().getFactoryRegistry().provideFactory(Factory.class).fromPlugin(pluginContainer); From ab05474114532bdf82c39dd376e0339cc13037de Mon Sep 17 00:00:00 2001 From: Matthew Messinger Date: Sun, 28 Jun 2020 19:37:02 -0400 Subject: [PATCH 06/19] Add some missing javadocs --- .../org/spongepowered/api/CatalogTypes.java | 3 ++ .../spongepowered/api/resource/Resource.java | 9 ++-- .../api/resource/ResourceManager.java | 9 ++++ .../api/resource/meta/MetaSection.java | 19 ++++++++ .../api/resource/meta/PackMeta.java | 13 +++++ .../api/resource/meta/package-info.java | 26 ++++++++++ .../api/resource/pack/PackInfo.java | 47 ++++++++++++++----- .../spongepowered/api/util/CloseableList.java | 8 ++++ 8 files changed, 118 insertions(+), 16 deletions(-) create mode 100644 src/main/java/org/spongepowered/api/resource/meta/package-info.java diff --git a/src/main/java/org/spongepowered/api/CatalogTypes.java b/src/main/java/org/spongepowered/api/CatalogTypes.java index 3a5ed891f03..50c19604d1f 100644 --- a/src/main/java/org/spongepowered/api/CatalogTypes.java +++ b/src/main/java/org/spongepowered/api/CatalogTypes.java @@ -63,6 +63,7 @@ import org.spongepowered.api.item.recipe.crafting.CraftingRecipe; import org.spongepowered.api.registry.CatalogRegistry; import org.spongepowered.api.registry.GameRegistry; +import org.spongepowered.api.resource.meta.MetaSection; import org.spongepowered.api.resource.pack.PackType; import org.spongepowered.api.scoreboard.CollisionRule; import org.spongepowered.api.scoreboard.Visibility; @@ -204,6 +205,8 @@ public final class CatalogTypes { public static final Class LLAMA_TYPE = LlamaType.class; + public static final Class META_SECTION = MetaSection.class; + public static final Class MOOSHROOM_TYPE = MooshroomType.class; public static final Class MUSIC_DISC = MusicDisc.class; diff --git a/src/main/java/org/spongepowered/api/resource/Resource.java b/src/main/java/org/spongepowered/api/resource/Resource.java index c256db3d9a7..da303ab7491 100644 --- a/src/main/java/org/spongepowered/api/resource/Resource.java +++ b/src/main/java/org/spongepowered/api/resource/Resource.java @@ -81,15 +81,16 @@ public interface Resource extends Closeable { boolean hasMetadata(); /** - * Gets the metadata for this resource. + * Gets the specified metadata section for this resource. * + * @param section The section serializer * @return The metadata or {@link Optional#empty() empty} if it doesn't exist. * @see MetaSections */ - Optional getMetadata(MetaSection name); + Optional getMetadata(MetaSection section); /** - * Creates a new {@link BufferedReader} from this resource's InputStream. + * Creates a new {@link BufferedReader} from this resource's {@link InputStream}. * * @param charset The charset to use, usually utf-8 * @return The BufferedReader @@ -126,7 +127,7 @@ public interface Resource extends Closeable { DataView readDataView(DataFormat format) throws IOException; /** - * Reads the resource as text and returns a stream of readLines. + * Reads the resource as text and returns a stream of lines. * *

Just like {@link BufferedReader#lines()}, the stream will wrap any * {@link IOException} thrown in an {@link java.io.UncheckedIOException}. diff --git a/src/main/java/org/spongepowered/api/resource/ResourceManager.java b/src/main/java/org/spongepowered/api/resource/ResourceManager.java index 994990a5629..f9513685c63 100644 --- a/src/main/java/org/spongepowered/api/resource/ResourceManager.java +++ b/src/main/java/org/spongepowered/api/resource/ResourceManager.java @@ -75,6 +75,15 @@ public interface ResourceManager { * } * * + *

You can also use the forEach method, which will automatically close + * the list.

+ * + *
+     *     resourceManager.loadAll(path).forEach(res -> {
+     *         InputStream in = res.getInputStream();
+     *     }
+     * 
+ * * @param path The path to the resource * @return The list of all resources at the path * @throws IOException If a resource could not be read diff --git a/src/main/java/org/spongepowered/api/resource/meta/MetaSection.java b/src/main/java/org/spongepowered/api/resource/meta/MetaSection.java index b369c2c77b8..453762e2866 100644 --- a/src/main/java/org/spongepowered/api/resource/meta/MetaSection.java +++ b/src/main/java/org/spongepowered/api/resource/meta/MetaSection.java @@ -29,10 +29,29 @@ import org.spongepowered.api.data.persistence.DataView; import org.spongepowered.api.util.annotation.CatalogedBy; +/** + * A meta section is a well-known resource meta object. Meta is typically + * stored in a file with the resource and {@code .mcmeta} appended to the name. + * The file contains a json object with each key associated with a section. + * + * @param The object type + */ @CatalogedBy(MetaSections.class) public interface MetaSection extends CatalogType { + /** + * Gets the query of the key containing the meta section. + * + * @return The query of the key + */ DataQuery getQuery(); + /** + * Deserializes the metadata section to an object representing its data. + * + * @param data The data result of the query + * @return The object representation + * @throws MetaParseException If the metadata could not be parsed + */ T deserialize(DataView data) throws MetaParseException; } diff --git a/src/main/java/org/spongepowered/api/resource/meta/PackMeta.java b/src/main/java/org/spongepowered/api/resource/meta/PackMeta.java index 57f07d6ca4f..92e934b8f45 100644 --- a/src/main/java/org/spongepowered/api/resource/meta/PackMeta.java +++ b/src/main/java/org/spongepowered/api/resource/meta/PackMeta.java @@ -26,9 +26,22 @@ import org.spongepowered.api.text.Text; +/** + * Metadata for a pack. It contains description and a pack format. + */ public interface PackMeta { + /** + * Gets the description of the pack. + * + * @return The description + */ Text getDescription(); + /** + * Gets the format version of the pack. + * + * @return The format version + */ int getPackFormat(); } diff --git a/src/main/java/org/spongepowered/api/resource/meta/package-info.java b/src/main/java/org/spongepowered/api/resource/meta/package-info.java new file mode 100644 index 00000000000..3e6ae770b1f --- /dev/null +++ b/src/main/java/org/spongepowered/api/resource/meta/package-info.java @@ -0,0 +1,26 @@ +/* + * This file is part of SpongeAPI, licensed under the MIT License (MIT). + * + * Copyright (c) SpongePowered + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +@org.checkerframework.framework.qual.DefaultQualifier(org.checkerframework.checker.nullness.qual.NonNull.class) +package org.spongepowered.api.resource.meta; diff --git a/src/main/java/org/spongepowered/api/resource/pack/PackInfo.java b/src/main/java/org/spongepowered/api/resource/pack/PackInfo.java index d3e1de8d088..4647b387c4f 100644 --- a/src/main/java/org/spongepowered/api/resource/pack/PackInfo.java +++ b/src/main/java/org/spongepowered/api/resource/pack/PackInfo.java @@ -24,17 +24,18 @@ */ package org.spongepowered.api.resource.pack; +import org.spongepowered.api.resource.meta.PackMeta; import org.spongepowered.api.text.Text; import org.spongepowered.api.util.Nameable; +/** + * Holds informational data about a {@link Pack}. It also functions as a + * factory to create a new instance. + */ public interface PackInfo extends Nameable { - Text getDisplayName(boolean enabled); - - PackVersion getVersion(); - /** - * Gets the pack associated with this pack info. + * Creates the pack associated with this pack info. * *

The returned pack may be a new instance or cached, depending on the * implementation.

@@ -44,19 +45,26 @@ public interface PackInfo extends Nameable { Pack getPack(); /** - * Gets whether this pack is forced to be enabled at all times. + * Gets the title of the pack. * - * @return True if forced enabled, false if disable-able + * @return The title */ - boolean isForced(); + Text getTitle(); /** - * Gets whether this pack is order locked on top or bottom. + * Gets the description of the pack. * - * @return True if order locked, false if order-able - * @see #getPriority() + * @return The description + * @see PackMeta#getDescription() */ - boolean isLocked(); + Text getDescription(); + + /** + * Gets the version compatibility of the pack. + * + * @return The version compatibility + */ + PackVersion getVersion(); /** * Gets the priority of this pack, first or last. @@ -65,6 +73,21 @@ public interface PackInfo extends Nameable { */ Priority getPriority(); + /** + * Gets whether this pack is forced to be enabled at all times. + * + * @return True if forced enabled, false if disable-able + */ + boolean isForced(); + + /** + * Gets whether this pack is order locked on top or bottom. + * + * @return True if order locked, false if order-able + * @see #getPriority() + */ + boolean isLocked(); + enum Priority { FIRST, LAST } diff --git a/src/main/java/org/spongepowered/api/util/CloseableList.java b/src/main/java/org/spongepowered/api/util/CloseableList.java index fe119bae21f..99f9f3871bf 100644 --- a/src/main/java/org/spongepowered/api/util/CloseableList.java +++ b/src/main/java/org/spongepowered/api/util/CloseableList.java @@ -26,6 +26,7 @@ import java.io.Closeable; import java.util.List; +import java.util.function.Consumer; /** * A list, containing closeable elements. All elements can be closed by calling @@ -40,4 +41,11 @@ public interface CloseableList extends List, Closeable { */ @Override void close(); + + @Override + default void forEach(Consumer action) { + try (CloseableList c = this) { + List.super.forEach(action); + } + } } From 8fd8d3858ff7f7ebdb76039993715e0d23c56735 Mon Sep 17 00:00:00 2001 From: Matthew Messinger Date: Sun, 28 Jun 2020 22:03:14 -0400 Subject: [PATCH 07/19] Convert PackVersion to a standard catalog type --- .../org/spongepowered/api/CatalogTypes.java | 3 ++ .../api/resource/pack/PackVersion.java | 29 +++++++++---------- .../api/resource/pack/PackVersions.java | 22 ++++++++++++++ 3 files changed, 39 insertions(+), 15 deletions(-) create mode 100644 src/main/java/org/spongepowered/api/resource/pack/PackVersions.java diff --git a/src/main/java/org/spongepowered/api/CatalogTypes.java b/src/main/java/org/spongepowered/api/CatalogTypes.java index 50c19604d1f..de15dea1841 100644 --- a/src/main/java/org/spongepowered/api/CatalogTypes.java +++ b/src/main/java/org/spongepowered/api/CatalogTypes.java @@ -65,6 +65,7 @@ import org.spongepowered.api.registry.GameRegistry; import org.spongepowered.api.resource.meta.MetaSection; import org.spongepowered.api.resource.pack.PackType; +import org.spongepowered.api.resource.pack.PackVersion; import org.spongepowered.api.scoreboard.CollisionRule; import org.spongepowered.api.scoreboard.Visibility; import org.spongepowered.api.scoreboard.criteria.Criterion; @@ -217,6 +218,8 @@ public final class CatalogTypes { public static final Class PACK_TYPE = PackType.class; + public static final Class PACK_VERSION = PackVersion.class; + public static final Class PANDA_GENE = PandaGene.class; public static final Class PARROT_TYPE = ParrotType.class; diff --git a/src/main/java/org/spongepowered/api/resource/pack/PackVersion.java b/src/main/java/org/spongepowered/api/resource/pack/PackVersion.java index 5396906574c..d84ee5bca5c 100644 --- a/src/main/java/org/spongepowered/api/resource/pack/PackVersion.java +++ b/src/main/java/org/spongepowered/api/resource/pack/PackVersion.java @@ -24,21 +24,20 @@ */ package org.spongepowered.api.resource.pack; -import org.spongepowered.api.Sponge; +import org.spongepowered.api.NamedCatalogType; +import org.spongepowered.api.util.annotation.CatalogedBy; -public interface PackVersion { - - boolean isOlder(); - - boolean isCurrent(); - - boolean isNewer(); - - static PackVersion of(int version) { - return Sponge.getRegistry().getFactoryRegistry().provideFactory(Factory.class).getCompatibility(version); - } +/** + * A minimal version identifier. The only indication of the version is whether + * it is current, newer or older. + */ +@CatalogedBy(PackVersions.class) +public interface PackVersion extends NamedCatalogType { - interface Factory { - PackVersion getCompatibility(int version); - } + /** + * Gets whether this version is {@link PackVersions#COMPATIBLE compatible}. + * + * @return True if is compatible, false if not + */ + boolean isCompatible(); } diff --git a/src/main/java/org/spongepowered/api/resource/pack/PackVersions.java b/src/main/java/org/spongepowered/api/resource/pack/PackVersions.java new file mode 100644 index 00000000000..bb4c583a22a --- /dev/null +++ b/src/main/java/org/spongepowered/api/resource/pack/PackVersions.java @@ -0,0 +1,22 @@ +package org.spongepowered.api.resource.pack; + +import org.spongepowered.api.Sponge; + +import java.util.function.Supplier; + +public class PackVersions { + + // SORTFIELDS:ON + + public static final Supplier COMPATIBLE = Sponge.getRegistry().getCatalogRegistry().provideSupplier(PackVersion.class, "COMPATIBLE"); + + public static final Supplier TOO_NEW = Sponge.getRegistry().getCatalogRegistry().provideSupplier(PackVersion.class, "TOO_NEW"); + + public static final Supplier TOO_OLD = Sponge.getRegistry().getCatalogRegistry().provideSupplier(PackVersion.class, "TOO_OLD"); + + // SORTFIELDS:OFF + + private PackVersions() { + } + +} From 65391e3b493f12e599ca2ea3bdcac79d4152e88c Mon Sep 17 00:00:00 2001 From: Matthew Messinger Date: Sun, 28 Jun 2020 22:04:45 -0400 Subject: [PATCH 08/19] More edits to javadocs --- .../spongepowered/api/resource/Resource.java | 13 +++-- .../api/resource/ResourceManager.java | 9 ++-- .../api/resource/ResourcePath.java | 47 +++++++++++++------ .../api/resource/ResourceReloadListener.java | 22 +++++---- .../api/resource/meta/PackMeta.java | 2 +- .../api/resource/pack/MutablePackList.java | 8 ++++ .../spongepowered/api/resource/pack/Pack.java | 9 ++-- .../api/resource/pack/PackDiscoverer.java | 9 ++++ .../api/resource/pack/PackList.java | 27 +++++++++++ .../api/resource/pack/PackType.java | 8 +++- 10 files changed, 116 insertions(+), 38 deletions(-) diff --git a/src/main/java/org/spongepowered/api/resource/Resource.java b/src/main/java/org/spongepowered/api/resource/Resource.java index da303ab7491..12e9de815b2 100644 --- a/src/main/java/org/spongepowered/api/resource/Resource.java +++ b/src/main/java/org/spongepowered/api/resource/Resource.java @@ -42,8 +42,9 @@ import java.util.stream.Stream; /** - * A resource can represent any kind of loaded data. It can be a file on the filesystem, a network location, or - * even generated at runtime. Use {@link #getInputStream()} to load the data held by a resource. + * A resource can represent any kind of loaded data. It can be a file on the + * filesystem, a network location, or even generated at runtime. Use + * {@link #getInputStream()} to load the data held by a resource. */ public interface Resource extends Closeable { @@ -81,16 +82,18 @@ public interface Resource extends Closeable { boolean hasMetadata(); /** - * Gets the specified metadata section for this resource. + * Gets the specified metadata section for this resource or + * {@link Optional#empty()} if it has no metadata. * * @param section The section serializer - * @return The metadata or {@link Optional#empty() empty} if it doesn't exist. + * @return The metadata or empty if it doesn't exist * @see MetaSections */ Optional getMetadata(MetaSection section); /** - * Creates a new {@link BufferedReader} from this resource's {@link InputStream}. + * Creates a new {@link BufferedReader} from this resource's + * {@link InputStream}. * * @param charset The charset to use, usually utf-8 * @return The BufferedReader diff --git a/src/main/java/org/spongepowered/api/resource/ResourceManager.java b/src/main/java/org/spongepowered/api/resource/ResourceManager.java index f9513685c63..83c9aaed774 100644 --- a/src/main/java/org/spongepowered/api/resource/ResourceManager.java +++ b/src/main/java/org/spongepowered/api/resource/ResourceManager.java @@ -28,6 +28,7 @@ import org.spongepowered.api.util.CloseableList; import java.io.Closeable; +import java.io.FileNotFoundException; import java.io.IOException; import java.util.Collection; import java.util.function.Predicate; @@ -44,7 +45,9 @@ public interface ResourceManager { * Loads the {@link Resource resource} at the given path, or throws an * exception if it doesn't exist. * - *

Resource implements {@link Closeable}, so remember to close it. Example:

+ *

Resource implements {@link Closeable}, so remember to close it.

+ * + *

Example:

* *
      *     try (Resource res = resourceManager.load(path)) {
@@ -86,8 +89,8 @@ public interface ResourceManager {
      *
      * @param path The path to the resource
      * @return The list of all resources at the path
-     * @throws IOException                   If a resource could not be read
-     * @throws java.io.FileNotFoundException If there are no resources at the path
+     * @throws IOException           If a resource could not be read
+     * @throws FileNotFoundException If there are no resources at the path
      */
     CloseableList loadAll(ResourcePath path) throws IOException;
 
diff --git a/src/main/java/org/spongepowered/api/resource/ResourcePath.java b/src/main/java/org/spongepowered/api/resource/ResourcePath.java
index 0c54e381cbe..da50cf045b1 100644
--- a/src/main/java/org/spongepowered/api/resource/ResourcePath.java
+++ b/src/main/java/org/spongepowered/api/resource/ResourcePath.java
@@ -31,14 +31,19 @@
 import java.util.Collection;
 import java.util.List;
 
+/**
+ * A namespaced path object used to get {@link Resource}s from the
+ * {@link ResourceManager}.
+ */
 public interface ResourcePath extends Comparable {
 
+    /**
+     * The path separator string.
+     */
     String SEPARATOR = "/";
 
     /**
-     * Creates a new {@link Builder} for creating {@link ResourcePath}s. The builder
-     * can be used for creating keys based on {@link PluginContainer}s, {@link Object}s
-     * of plugins, and {@link String} namespaces.
+     * Creates a new {@link Builder} for creating {@link ResourcePath}s.
      *
      * @return The new builder instance
      */
@@ -47,22 +52,22 @@ static Builder builder() {
     }
 
     /**
-     * Creates a catalog key.
+     * Creates a resource path.
      *
      * @param namespace The namespace
      * @param value     The value
-     * @return A new catalog key
+     * @return A new resource path
      */
     static ResourcePath of(final String namespace, final String value) {
         return builder().namespace(namespace).path(value).build();
     }
 
     /**
-     * Creates a catalog key
+     * Creates a resource path.
      *
      * @param container The container
      * @param value     The value
-     * @return A new catalog key
+     * @return A new resource path
      */
     static ResourcePath of(final PluginContainer container, final String value) {
         return builder().namespace(container).path(value).build();
@@ -71,11 +76,11 @@ static ResourcePath of(final PluginContainer container, final String value) {
     /**
      * Parses a path from a string.
      *
-     * 

If no namespace is found in {@code string} then + *

If no namespace is found in {@code value} then * {@code minecraft} will be the namespace.

* * @param value The value - * @return A new catalog key + * @return A new resource path */ static ResourcePath parse(final String value) { return builder().path(value).build(); @@ -110,7 +115,8 @@ static ResourcePath parse(final String value) { * * @param child The child path's name * @return The resolved path - * @throws ResourcePathException If the path is invalid or could not be normalized + * @throws ResourcePathException If the path is invalid or could not be + * normalized * @see #resolve(String...) */ default ResourcePath resolve(String child) throws ResourcePathException { @@ -122,28 +128,31 @@ default ResourcePath resolve(String child) throws ResourcePathException { * * @param children The children paths * @return The resolved path - * @throws ResourcePathException If the path is invalid or could not be normalized + * @throws ResourcePathException If the path is invalid or could not be + * normalized */ ResourcePath resolve(String... children) throws ResourcePathException; /** * @param sibling The sibling's name * @return The sibling resource path - * @throws ResourcePathException If the path is invalid or could not be normalized + * @throws ResourcePathException If the path is invalid or could not be + * normalized */ ResourcePath resolveSibling(String sibling) throws ResourcePathException; // path utility methods /** - * Gets all the parts of this path. i.e. the full path split by {@link #SEPARATOR}. + * Gets all the parts of this path. i.e. the full path split by + * {@link #SEPARATOR}. The result list is unmodifiable. * * @return The path parts */ List getPathParts(); /** - * Gets the parent of this path or root if it is root. + * Gets the parent of this path or root if this is root. * * @return The parent path */ @@ -164,12 +173,20 @@ default ResourcePath resolve(String child) throws ResourcePathException { String getBaseName(); /** - * Gets the extension of the file if any. If the file has no extension, an empty string is returned. + * Gets the extension of the file if any. If the file has no extension, an + * empty string is returned. * * @return The file extension */ String getExtension(); + /** + * Gets the string representation of this path as {@code "namspace:path"} + * + * @return The string representation + */ + String toString(); + interface Builder extends ResettableBuilder { Builder namespace(String namespace); diff --git a/src/main/java/org/spongepowered/api/resource/ResourceReloadListener.java b/src/main/java/org/spongepowered/api/resource/ResourceReloadListener.java index 4397f69d6c9..a9127020bbe 100644 --- a/src/main/java/org/spongepowered/api/resource/ResourceReloadListener.java +++ b/src/main/java/org/spongepowered/api/resource/ResourceReloadListener.java @@ -34,12 +34,14 @@ /** * A low level async reload listener. * - *

There are two stages when reloading resources. The first is done asynchronously, so keep - * that in mind when interacting with game objects. The second is done synchronously on the game thread. This stage will - * not execute until all listeners have completed their first stage.

+ *

There are two stages when reloading resources. The first is done + * asynchronously, so keep that in mind when interacting with game objects. The + * second is done synchronously on the game thread. This stage will not execute + * until all listeners have completed their first stage.

* - *

In most circumstances, you should prefer to create a more specific use-case instance using the factory instead of - * implementing this interface directly.

+ *

In most circumstances, you should prefer to create a more specific + * use-case instance using the factory instead of implementing this interface + * directly.

* *

Example usage:

* @@ -96,7 +98,8 @@ interface AsyncStage { interface Factory { /** - * Creates a simple reload listener that reloads resources on the main thread. + * Creates a simple reload listener that reloads resources on the game + * thread. * * @param listener The listener implementation * @return The listener @@ -104,8 +107,8 @@ interface Factory { ResourceReloadListener simple(SimpleReloadListener listener); /** - * Creates a prepared reload listener that loads resources in the work thread and apply them in the main - * thread. + * Creates a prepared reload listener that loads resources in the work + * thread and apply them in the game thread. * * @param listener The listener implementation * @param The type of resource to be prepared @@ -114,7 +117,8 @@ interface Factory { ResourceReloadListener prepared(PreparedReloadListener listener); /** - * Creates a data tree reload listener that loads every json file in a folder from each namespace. + * Creates a data tree reload listener that loads every json file in a + * folder from each namespace. * * @param path The path of the folder to load * @param listener The listener implementation diff --git a/src/main/java/org/spongepowered/api/resource/meta/PackMeta.java b/src/main/java/org/spongepowered/api/resource/meta/PackMeta.java index 92e934b8f45..338aa3ba1ab 100644 --- a/src/main/java/org/spongepowered/api/resource/meta/PackMeta.java +++ b/src/main/java/org/spongepowered/api/resource/meta/PackMeta.java @@ -27,7 +27,7 @@ import org.spongepowered.api.text.Text; /** - * Metadata for a pack. It contains description and a pack format. + * Metadata for a pack. It contains the description and pack format. */ public interface PackMeta { diff --git a/src/main/java/org/spongepowered/api/resource/pack/MutablePackList.java b/src/main/java/org/spongepowered/api/resource/pack/MutablePackList.java index 83db6aab34a..5dd4b946220 100644 --- a/src/main/java/org/spongepowered/api/resource/pack/MutablePackList.java +++ b/src/main/java/org/spongepowered/api/resource/pack/MutablePackList.java @@ -24,7 +24,15 @@ */ package org.spongepowered.api.resource.pack; +/** + * A {@link PackList} which can have {@link PackDiscoverer}s added to it. + */ public interface MutablePackList extends PackList { + /** + * Adds a {@link PackDiscoverer} to the list. + * + * @param discoverer The discoverer + */ void addPackDiscoverer(PackDiscoverer discoverer); } diff --git a/src/main/java/org/spongepowered/api/resource/pack/Pack.java b/src/main/java/org/spongepowered/api/resource/pack/Pack.java index 6c9616b74df..911e81a0d14 100644 --- a/src/main/java/org/spongepowered/api/resource/pack/Pack.java +++ b/src/main/java/org/spongepowered/api/resource/pack/Pack.java @@ -44,9 +44,11 @@ /** * A resource pack or data pack can contain several {@link Resource resources}. - * A pack con contain both assets and data. + * A pack can contain both assets and data. * - * @see Minecraft Wiki/Resource Packs + * @see + * Minecraft Wiki/Resource Packs + * */ public interface Pack extends Nameable, Closeable { @@ -119,7 +121,8 @@ static Supplier fromPlugin(PluginContainer pluginContainer) { /** * Gets the metadata of this pack. The {@link MetaSection} deserializes a * section of the pack.mcmeta file in the pack root. If the pack.mcmeta - * does not contain the query defined in the section, {@link Optional#empty()} is returned. + * does not contain the query defined in the section, + * {@link Optional#empty()} is returned. * * @param section The name metadata section type * @return The metadata if it exists diff --git a/src/main/java/org/spongepowered/api/resource/pack/PackDiscoverer.java b/src/main/java/org/spongepowered/api/resource/pack/PackDiscoverer.java index 3751423a968..b4b4230ad15 100644 --- a/src/main/java/org/spongepowered/api/resource/pack/PackDiscoverer.java +++ b/src/main/java/org/spongepowered/api/resource/pack/PackDiscoverer.java @@ -28,8 +28,17 @@ import java.util.Optional; import java.util.function.Supplier; +/** + * A pack discoverer will populate the {@link PackList} with {@link PackInfo}s + * and provide it a supplier to create a new {@link Pack}. + */ public interface PackDiscoverer { + /** + * Populates the {@link PackList} with discovered {@link Pack}s. + * + * @param packInfos A map containing all the packs + */ void populate(Map packInfos, PackInfoFactory factory); @FunctionalInterface diff --git a/src/main/java/org/spongepowered/api/resource/pack/PackList.java b/src/main/java/org/spongepowered/api/resource/pack/PackList.java index 5f369dcab4d..d962c0fb7aa 100644 --- a/src/main/java/org/spongepowered/api/resource/pack/PackList.java +++ b/src/main/java/org/spongepowered/api/resource/pack/PackList.java @@ -27,14 +27,41 @@ import java.util.Collection; import java.util.Optional; +/** + * The pack list keeps track of all the known {@link PackInfo}s and their + * status. + */ public interface PackList { + /** + * Gets the collection of all the known {@link PackInfo}s. The result is + * immutable. To add more packs, register a {@link PackDiscoverer}. + * + * @return All the packs + */ Collection all(); + /** + * Gets the collection of {@link PackInfo}s which are not enabled. + * + * @return The disabled packs + */ Collection disabled(); + /** + * Gets the collection of {@link PackInfo}s which are enabled. + * + * @return The enabled packs + */ Collection enabled(); + /** + * Gets a {@link PackInfo} with the given name. If none exists, + * {@link Optional#empty()} is returned. + * + * @param name The name of the pack + * @return The pack info + */ Optional get(String name); } diff --git a/src/main/java/org/spongepowered/api/resource/pack/PackType.java b/src/main/java/org/spongepowered/api/resource/pack/PackType.java index 92cc2885040..038512feb1e 100644 --- a/src/main/java/org/spongepowered/api/resource/pack/PackType.java +++ b/src/main/java/org/spongepowered/api/resource/pack/PackType.java @@ -24,10 +24,14 @@ */ package org.spongepowered.api.resource.pack; -import org.spongepowered.api.CatalogType; +import org.spongepowered.api.NamedCatalogType; import org.spongepowered.api.util.annotation.CatalogedBy; +/** + * A pack type specifies the kind of resource a pack should load. i.e. client + * resources or server data. + */ @CatalogedBy(PackTypes.class) -public interface PackType extends CatalogType { +public interface PackType extends NamedCatalogType { } From 2e4ee6a4cec677f8126d4b981bcccca00e55fcba Mon Sep 17 00:00:00 2001 From: Matthew Messinger Date: Sun, 28 Jun 2020 22:06:42 -0400 Subject: [PATCH 09/19] Fix licenses --- .../api/resource/pack/PackVersions.java | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/main/java/org/spongepowered/api/resource/pack/PackVersions.java b/src/main/java/org/spongepowered/api/resource/pack/PackVersions.java index bb4c583a22a..12a5e1756d0 100644 --- a/src/main/java/org/spongepowered/api/resource/pack/PackVersions.java +++ b/src/main/java/org/spongepowered/api/resource/pack/PackVersions.java @@ -1,3 +1,27 @@ +/* + * This file is part of SpongeAPI, licensed under the MIT License (MIT). + * + * Copyright (c) SpongePowered + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ package org.spongepowered.api.resource.pack; import org.spongepowered.api.Sponge; From b78264b45bb1ce2063c16105e2ac7f0c74131e14 Mon Sep 17 00:00:00 2001 From: Matthew Messinger Date: Tue, 14 Jul 2020 23:03:35 -0400 Subject: [PATCH 10/19] Make proper register events for ResourceReloadListener and PackDiscoverer --- ....java => RegisterPackDiscovererEvent.java} | 42 ++--------- .../RegisterResourceReloadListenerEvent.java} | 19 +++-- .../api/event/resource/ResourceEvent.java | 74 ------------------- .../resource/package-info.java} | 16 +--- .../api/resource/ResourceReloadListener.java | 3 + .../api/resource/pack/PackDiscoverer.java | 4 + 6 files changed, 25 insertions(+), 133 deletions(-) rename src/main/java/org/spongepowered/api/event/resource/{PackEvent.java => RegisterPackDiscovererEvent.java} (58%) rename src/main/java/org/spongepowered/api/{resource/ReloadableResourceManager.java => event/resource/RegisterResourceReloadListenerEvent.java} (73%) delete mode 100644 src/main/java/org/spongepowered/api/event/resource/ResourceEvent.java rename src/main/java/org/spongepowered/api/{resource/pack/MutablePackList.java => event/resource/package-info.java} (78%) diff --git a/src/main/java/org/spongepowered/api/event/resource/PackEvent.java b/src/main/java/org/spongepowered/api/event/resource/RegisterPackDiscovererEvent.java similarity index 58% rename from src/main/java/org/spongepowered/api/event/resource/PackEvent.java rename to src/main/java/org/spongepowered/api/event/resource/RegisterPackDiscovererEvent.java index 1c7da114d5f..effaeca9e96 100644 --- a/src/main/java/org/spongepowered/api/event/resource/PackEvent.java +++ b/src/main/java/org/spongepowered/api/event/resource/RegisterPackDiscovererEvent.java @@ -24,48 +24,20 @@ */ package org.spongepowered.api.event.resource; -import org.spongepowered.api.event.Event; -import org.spongepowered.api.resource.pack.MutablePackList; -import org.spongepowered.api.resource.pack.Pack; +import org.spongepowered.api.Engine; +import org.spongepowered.api.event.GenericEvent; import org.spongepowered.api.resource.pack.PackDiscoverer; import org.spongepowered.api.resource.pack.PackList; /** - * Base {@link Pack} event. + * Event for registering {@link PackDiscoverer}s. */ -public interface PackEvent extends Event { +public interface RegisterPackDiscovererEvent extends GenericEvent { /** - * Gets the relevant {@link PackList} for this event. + * Adds a {@link PackDiscoverer} to the {@link PackList}. * - * @return The pack list + * @param discoverer The discoverer */ - PackList getPackList(); - - /** - * Event for registering {@link PackDiscoverer}s. It is fired sometime during init. - */ - interface RegisterPackDiscoverer extends PackEvent { - - /** - * {@inheritDoc} - *

Returns a {@link MutablePackList} to expose methods for adding listeners.

- * @return The pack list - */ - @Override - MutablePackList getPackList(); - - /** - * Register event for client resources. - */ - interface Client extends RegisterPackDiscoverer { - } - - /** - * Register event for server data. - */ - interface Server extends RegisterPackDiscoverer { - } - } - + void registerPackDiscoverer(PackDiscoverer discoverer); } diff --git a/src/main/java/org/spongepowered/api/resource/ReloadableResourceManager.java b/src/main/java/org/spongepowered/api/event/resource/RegisterResourceReloadListenerEvent.java similarity index 73% rename from src/main/java/org/spongepowered/api/resource/ReloadableResourceManager.java rename to src/main/java/org/spongepowered/api/event/resource/RegisterResourceReloadListenerEvent.java index ca8462b92e8..4adf8af6798 100644 --- a/src/main/java/org/spongepowered/api/resource/ReloadableResourceManager.java +++ b/src/main/java/org/spongepowered/api/event/resource/RegisterResourceReloadListenerEvent.java @@ -22,18 +22,18 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -package org.spongepowered.api.resource; +package org.spongepowered.api.event.resource; -import org.spongepowered.api.event.resource.ResourceEvent; +import org.spongepowered.api.Engine; +import org.spongepowered.api.event.GenericEvent; +import org.spongepowered.api.resource.ResourceManager; +import org.spongepowered.api.resource.ResourceReloadListener; /** - * A {@link ResourceManager} that supports being reloaded. Listeners can be - * added to load assets asynchronously when this happens. - * - *

To register listeners, add them during the - * {@link ResourceEvent.RegisterReloadListener} event.

+ * Event for registering {@link ResourceReloadListener reload listeners} to the + * {@link ResourceManager}. */ -public interface ReloadableResourceManager extends ResourceManager { +public interface RegisterResourceReloadListenerEvent extends GenericEvent { /** * Adds a reload listener to the resource manager. @@ -41,6 +41,5 @@ public interface ReloadableResourceManager extends ResourceManager { * @param listener The listener * @see ResourceReloadListener */ - void addReloadListener(ResourceReloadListener listener); - + void registerReloadListener(ResourceReloadListener listener); } diff --git a/src/main/java/org/spongepowered/api/event/resource/ResourceEvent.java b/src/main/java/org/spongepowered/api/event/resource/ResourceEvent.java deleted file mode 100644 index 42b3c2f2d16..00000000000 --- a/src/main/java/org/spongepowered/api/event/resource/ResourceEvent.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * This file is part of SpongeAPI, licensed under the MIT License (MIT). - * - * Copyright (c) SpongePowered - * Copyright (c) contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package org.spongepowered.api.event.resource; - -import org.spongepowered.api.event.Event; -import org.spongepowered.api.resource.ReloadableResourceManager; -import org.spongepowered.api.resource.ResourceReloadListener; -import org.spongepowered.api.resource.Resource; -import org.spongepowered.api.resource.ResourceManager; - -/** - * Base event for {@link Resource}s. - */ -public interface ResourceEvent extends Event { - - /** - * Gets the relevant {@link ResourceManager} for this event. - * - * @return The resource manager - */ - ResourceManager getResourceManager(); - - /** - * Event for registering {@link ResourceReloadListener reload listeners} to the - * {@link ResourceManager}. It is fired sometime during init. - */ - interface RegisterReloadListener extends ResourceEvent { - - /** - * {@inheritDoc} - * - *

The type is a {@link ReloadableResourceManager} to expose methods - * to add reload listeners

- * - * @return The reloadable resource manager - */ - @Override - ReloadableResourceManager getResourceManager(); - - /** - * Register event for client resources. - */ - interface Client extends RegisterReloadListener { - } - - /** - * Register event for server data. - */ - interface Server extends RegisterReloadListener { - } - } -} diff --git a/src/main/java/org/spongepowered/api/resource/pack/MutablePackList.java b/src/main/java/org/spongepowered/api/event/resource/package-info.java similarity index 78% rename from src/main/java/org/spongepowered/api/resource/pack/MutablePackList.java rename to src/main/java/org/spongepowered/api/event/resource/package-info.java index 5dd4b946220..9778be2f03f 100644 --- a/src/main/java/org/spongepowered/api/resource/pack/MutablePackList.java +++ b/src/main/java/org/spongepowered/api/event/resource/package-info.java @@ -22,17 +22,5 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -package org.spongepowered.api.resource.pack; - -/** - * A {@link PackList} which can have {@link PackDiscoverer}s added to it. - */ -public interface MutablePackList extends PackList { - - /** - * Adds a {@link PackDiscoverer} to the list. - * - * @param discoverer The discoverer - */ - void addPackDiscoverer(PackDiscoverer discoverer); -} +@org.checkerframework.framework.qual.DefaultQualifier(org.checkerframework.checker.nullness.qual.NonNull.class) +package org.spongepowered.api.event.resource; diff --git a/src/main/java/org/spongepowered/api/resource/ResourceReloadListener.java b/src/main/java/org/spongepowered/api/resource/ResourceReloadListener.java index a9127020bbe..08b8881d94a 100644 --- a/src/main/java/org/spongepowered/api/resource/ResourceReloadListener.java +++ b/src/main/java/org/spongepowered/api/resource/ResourceReloadListener.java @@ -26,6 +26,7 @@ import org.spongepowered.api.Sponge; import org.spongepowered.api.data.persistence.DataView; +import org.spongepowered.api.event.resource.RegisterResourceReloadListenerEvent; import java.util.Map; import java.util.concurrent.CompletableFuture; @@ -63,6 +64,8 @@ * } * } *
+ * + * @see RegisterResourceReloadListenerEvent */ public interface ResourceReloadListener { diff --git a/src/main/java/org/spongepowered/api/resource/pack/PackDiscoverer.java b/src/main/java/org/spongepowered/api/resource/pack/PackDiscoverer.java index b4b4230ad15..fbb75a53deb 100644 --- a/src/main/java/org/spongepowered/api/resource/pack/PackDiscoverer.java +++ b/src/main/java/org/spongepowered/api/resource/pack/PackDiscoverer.java @@ -24,6 +24,8 @@ */ package org.spongepowered.api.resource.pack; +import org.spongepowered.api.event.resource.RegisterPackDiscovererEvent; + import java.util.Map; import java.util.Optional; import java.util.function.Supplier; @@ -31,6 +33,8 @@ /** * A pack discoverer will populate the {@link PackList} with {@link PackInfo}s * and provide it a supplier to create a new {@link Pack}. + * + * @see RegisterPackDiscovererEvent */ public interface PackDiscoverer { From 11f60bf471a5ef618491b8906542de4addab566d Mon Sep 17 00:00:00 2001 From: Matthew Messinger Date: Tue, 14 Jul 2020 23:04:33 -0400 Subject: [PATCH 11/19] Add a reload method to Engine to reload resources. --- src/main/java/org/spongepowered/api/Engine.java | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/spongepowered/api/Engine.java b/src/main/java/org/spongepowered/api/Engine.java index 84e659bad46..846128488da 100644 --- a/src/main/java/org/spongepowered/api/Engine.java +++ b/src/main/java/org/spongepowered/api/Engine.java @@ -25,10 +25,16 @@ package org.spongepowered.api; import org.spongepowered.api.event.CauseStackManager; +import org.spongepowered.api.resource.Resource; import org.spongepowered.api.resource.ResourceManager; +import org.spongepowered.api.resource.ResourceReloadListener; +import org.spongepowered.api.resource.pack.Pack; +import org.spongepowered.api.resource.pack.PackDiscoverer; import org.spongepowered.api.resource.pack.PackList; import org.spongepowered.api.scheduler.Scheduler; +import java.util.concurrent.CompletableFuture; + /** * Shared functionality between {@link Client} and {@link Server} engines. */ @@ -51,7 +57,7 @@ public interface Engine { /** * Gets the {@link PackList} instance of this engine. * - * @return + * @return The pack list */ PackList getPackList(); @@ -75,4 +81,12 @@ public interface Engine { * @return {@code true} if main thread, {@code false} if not */ boolean onMainThread(); + + /** + * Rediscovers {@link Pack}s using all registered {@link PackDiscoverer}s and + * reloads all {@link Resource}s by running all registered {@link ResourceReloadListener}s. + * + * @return A future that completes when reloading is complete + */ + CompletableFuture reloadResources(); } From a6fab5358c2096dabd5af06dd8c1e88516842b88 Mon Sep 17 00:00:00 2001 From: Matthew Messinger Date: Sat, 1 Aug 2020 22:33:19 -0400 Subject: [PATCH 12/19] Tweaks to API for common impl --- .../java/org/spongepowered/api/Engine.java | 2 ++ .../spongepowered/api/resource/Resource.java | 4 +-- .../api/resource/ResourceReloadListener.java | 8 +++-- .../api/resource/meta/MetaSection.java | 5 +-- .../api/resource/meta/NamedMetaSection.java | 32 +++++++++++++++++++ ...taSections.java => NamedMetaSections.java} | 6 ++-- .../spongepowered/api/resource/pack/Pack.java | 3 +- 7 files changed, 47 insertions(+), 13 deletions(-) create mode 100644 src/main/java/org/spongepowered/api/resource/meta/NamedMetaSection.java rename src/main/java/org/spongepowered/api/resource/meta/{MetaSections.java => NamedMetaSections.java} (85%) diff --git a/src/main/java/org/spongepowered/api/Engine.java b/src/main/java/org/spongepowered/api/Engine.java index 846128488da..58f357a344c 100644 --- a/src/main/java/org/spongepowered/api/Engine.java +++ b/src/main/java/org/spongepowered/api/Engine.java @@ -86,6 +86,8 @@ public interface Engine { * Rediscovers {@link Pack}s using all registered {@link PackDiscoverer}s and * reloads all {@link Resource}s by running all registered {@link ResourceReloadListener}s. * + *

On the server, the future will always be completed.

+ * * @return A future that completes when reloading is complete */ CompletableFuture reloadResources(); diff --git a/src/main/java/org/spongepowered/api/resource/Resource.java b/src/main/java/org/spongepowered/api/resource/Resource.java index 12e9de815b2..3ef6b27084d 100644 --- a/src/main/java/org/spongepowered/api/resource/Resource.java +++ b/src/main/java/org/spongepowered/api/resource/Resource.java @@ -28,7 +28,7 @@ import org.spongepowered.api.data.persistence.DataFormats; import org.spongepowered.api.data.persistence.DataView; import org.spongepowered.api.resource.meta.MetaSection; -import org.spongepowered.api.resource.meta.MetaSections; +import org.spongepowered.api.resource.meta.NamedMetaSections; import org.spongepowered.api.resource.pack.PackInfo; import org.spongepowered.api.resource.pack.PackList; @@ -87,7 +87,7 @@ public interface Resource extends Closeable { * * @param section The section serializer * @return The metadata or empty if it doesn't exist - * @see MetaSections + * @see NamedMetaSections */ Optional getMetadata(MetaSection section); diff --git a/src/main/java/org/spongepowered/api/resource/ResourceReloadListener.java b/src/main/java/org/spongepowered/api/resource/ResourceReloadListener.java index 08b8881d94a..eba67ffd545 100644 --- a/src/main/java/org/spongepowered/api/resource/ResourceReloadListener.java +++ b/src/main/java/org/spongepowered/api/resource/ResourceReloadListener.java @@ -25,6 +25,7 @@ package org.spongepowered.api.resource; import org.spongepowered.api.Sponge; +import org.spongepowered.api.data.persistence.DataFormat; import org.spongepowered.api.data.persistence.DataView; import org.spongepowered.api.event.resource.RegisterResourceReloadListenerEvent; @@ -123,11 +124,12 @@ interface Factory { * Creates a data tree reload listener that loads every json file in a * folder from each namespace. * - * @param path The path of the folder to load - * @param listener The listener implementation + * @param pathPrefix The path of the folder to load + * @param format The data format of the files + * @param listener The listener implementation * @return The listener */ - ResourceReloadListener dataTree(String path, DataTreeReloadListener listener); + ResourceReloadListener dataTree(String pathPrefix, DataFormat format, DataTreeReloadListener listener); } /** diff --git a/src/main/java/org/spongepowered/api/resource/meta/MetaSection.java b/src/main/java/org/spongepowered/api/resource/meta/MetaSection.java index 453762e2866..5a7d9995354 100644 --- a/src/main/java/org/spongepowered/api/resource/meta/MetaSection.java +++ b/src/main/java/org/spongepowered/api/resource/meta/MetaSection.java @@ -24,10 +24,8 @@ */ package org.spongepowered.api.resource.meta; -import org.spongepowered.api.CatalogType; import org.spongepowered.api.data.persistence.DataQuery; import org.spongepowered.api.data.persistence.DataView; -import org.spongepowered.api.util.annotation.CatalogedBy; /** * A meta section is a well-known resource meta object. Meta is typically @@ -36,8 +34,7 @@ * * @param The object type */ -@CatalogedBy(MetaSections.class) -public interface MetaSection extends CatalogType { +public interface MetaSection { /** * Gets the query of the key containing the meta section. diff --git a/src/main/java/org/spongepowered/api/resource/meta/NamedMetaSection.java b/src/main/java/org/spongepowered/api/resource/meta/NamedMetaSection.java new file mode 100644 index 00000000000..feca4f572d7 --- /dev/null +++ b/src/main/java/org/spongepowered/api/resource/meta/NamedMetaSection.java @@ -0,0 +1,32 @@ +/* + * This file is part of SpongeAPI, licensed under the MIT License (MIT). + * + * Copyright (c) SpongePowered + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.spongepowered.api.resource.meta; + +import org.spongepowered.api.NamedCatalogType; +import org.spongepowered.api.util.annotation.CatalogedBy; + +@CatalogedBy(NamedMetaSections.class) +public interface NamedMetaSection extends MetaSection, NamedCatalogType { +} diff --git a/src/main/java/org/spongepowered/api/resource/meta/MetaSections.java b/src/main/java/org/spongepowered/api/resource/meta/NamedMetaSections.java similarity index 85% rename from src/main/java/org/spongepowered/api/resource/meta/MetaSections.java rename to src/main/java/org/spongepowered/api/resource/meta/NamedMetaSections.java index 84d5b8ac826..0d57076f7fd 100644 --- a/src/main/java/org/spongepowered/api/resource/meta/MetaSections.java +++ b/src/main/java/org/spongepowered/api/resource/meta/NamedMetaSections.java @@ -28,13 +28,13 @@ import java.util.function.Supplier; -public class MetaSections { +public class NamedMetaSections { // SORTFIELDS:ON - private static final Supplier> PACK = Sponge.getRegistry().getCatalogRegistry().provideSupplier(MetaSection.class, "pack/pack"); + private static final Supplier> PACK = Sponge.getRegistry().getCatalogRegistry().provideSupplier(NamedMetaSection.class, "pack/pack"); // SORTFIELDS:OFF - private MetaSections() {} + private NamedMetaSections() {} } diff --git a/src/main/java/org/spongepowered/api/resource/pack/Pack.java b/src/main/java/org/spongepowered/api/resource/pack/Pack.java index 911e81a0d14..b1c3ec66321 100644 --- a/src/main/java/org/spongepowered/api/resource/pack/Pack.java +++ b/src/main/java/org/spongepowered/api/resource/pack/Pack.java @@ -126,9 +126,10 @@ static Supplier fromPlugin(PluginContainer pluginContainer) { * * @param section The name metadata section type * @return The metadata if it exists + * @throws IOException If the data could not be read * @throws MetaParseException If the metadata could not be parsed */ - Optional getMetadata(MetaSection section) throws MetaParseException; + Optional getMetadata(MetaSection section) throws IOException; interface Factory { From 2c6749588b6f233842ffa045c11a18bb05050128 Mon Sep 17 00:00:00 2001 From: Matthew Messinger Date: Sat, 1 Aug 2020 23:59:21 -0400 Subject: [PATCH 13/19] Update to use kyori text --- .../java/org/spongepowered/api/resource/meta/PackMeta.java | 4 ++-- .../java/org/spongepowered/api/resource/pack/PackInfo.java | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main/java/org/spongepowered/api/resource/meta/PackMeta.java b/src/main/java/org/spongepowered/api/resource/meta/PackMeta.java index 338aa3ba1ab..78970a2a682 100644 --- a/src/main/java/org/spongepowered/api/resource/meta/PackMeta.java +++ b/src/main/java/org/spongepowered/api/resource/meta/PackMeta.java @@ -24,7 +24,7 @@ */ package org.spongepowered.api.resource.meta; -import org.spongepowered.api.text.Text; +import net.kyori.adventure.text.Component; /** * Metadata for a pack. It contains the description and pack format. @@ -36,7 +36,7 @@ public interface PackMeta { * * @return The description */ - Text getDescription(); + Component getDescription(); /** * Gets the format version of the pack. diff --git a/src/main/java/org/spongepowered/api/resource/pack/PackInfo.java b/src/main/java/org/spongepowered/api/resource/pack/PackInfo.java index 4647b387c4f..75d06126c72 100644 --- a/src/main/java/org/spongepowered/api/resource/pack/PackInfo.java +++ b/src/main/java/org/spongepowered/api/resource/pack/PackInfo.java @@ -24,8 +24,8 @@ */ package org.spongepowered.api.resource.pack; +import net.kyori.adventure.text.Component; import org.spongepowered.api.resource.meta.PackMeta; -import org.spongepowered.api.text.Text; import org.spongepowered.api.util.Nameable; /** @@ -49,7 +49,7 @@ public interface PackInfo extends Nameable { * * @return The title */ - Text getTitle(); + Component getTitle(); /** * Gets the description of the pack. @@ -57,7 +57,7 @@ public interface PackInfo extends Nameable { * @return The description * @see PackMeta#getDescription() */ - Text getDescription(); + Component getDescription(); /** * Gets the version compatibility of the pack. From 286305e343b38a60c47002aaf9ed982a36428f70 Mon Sep 17 00:00:00 2001 From: Matthew Messinger Date: Tue, 8 Sep 2020 17:05:07 -0400 Subject: [PATCH 14/19] Update for API changes --- .../org/spongepowered/api/resource/pack/Pack.java | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/src/main/java/org/spongepowered/api/resource/pack/Pack.java b/src/main/java/org/spongepowered/api/resource/pack/Pack.java index b1c3ec66321..d79837f3f1e 100644 --- a/src/main/java/org/spongepowered/api/resource/pack/Pack.java +++ b/src/main/java/org/spongepowered/api/resource/pack/Pack.java @@ -67,7 +67,7 @@ static Supplier fromPath(Path path) { * * @param pluginContainer The plugin * @return The supplier to create a new pack - * @see PluginContainer#getFile() + * @see PluginContainer#getPath() */ static Supplier fromPlugin(PluginContainer pluginContainer) { return Sponge.getRegistry().getFactoryRegistry().provideFactory(Factory.class).fromPlugin(pluginContainer); @@ -88,14 +88,15 @@ static Supplier fromPlugin(PluginContainer pluginContainer) { * Finds all the {@link ResourcePath}s in this pack matching the * prefix and filter, and within the given depth. * - * @param type The type of pack resource to find - * @param prefix The prefix of the path - * @param depth The depth to search - * @param filter The filter every path must match + * @param type The type of pack resource to find + * @param namespace The namespace to search + * @param prefix The prefix of the path + * @param depth The depth to search + * @param filter The filter every path must match * @return A collection of matching paths * @see PackTypes */ - Collection find(PackType type, String prefix, int depth, Predicate filter); + Collection find(PackType type, String namespace, String prefix, int depth, Predicate filter); /** * Tests if this pack contains an entry at the given {@link ResourcePath}. @@ -109,8 +110,6 @@ static Supplier fromPlugin(PluginContainer pluginContainer) { /** * Gets the namespaces known by this pack. - *

- * TODO: Does this need to be exposed? * * @param type The pack type to query * @return The set of namespaces From 5d8b660d70ee5e9ed8585de30102b639d761cb09 Mon Sep 17 00:00:00 2001 From: Matthew Messinger Date: Sat, 12 Sep 2020 17:32:55 -0400 Subject: [PATCH 15/19] Implement resource events API: rename the register event method --- .../api/event/resource/RegisterPackDiscovererEvent.java | 2 +- .../api/event/resource/RegisterResourceReloadListenerEvent.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/spongepowered/api/event/resource/RegisterPackDiscovererEvent.java b/src/main/java/org/spongepowered/api/event/resource/RegisterPackDiscovererEvent.java index effaeca9e96..068dc0cb575 100644 --- a/src/main/java/org/spongepowered/api/event/resource/RegisterPackDiscovererEvent.java +++ b/src/main/java/org/spongepowered/api/event/resource/RegisterPackDiscovererEvent.java @@ -39,5 +39,5 @@ public interface RegisterPackDiscovererEvent extends GenericEv * * @param discoverer The discoverer */ - void registerPackDiscoverer(PackDiscoverer discoverer); + void register(PackDiscoverer discoverer); } diff --git a/src/main/java/org/spongepowered/api/event/resource/RegisterResourceReloadListenerEvent.java b/src/main/java/org/spongepowered/api/event/resource/RegisterResourceReloadListenerEvent.java index 4adf8af6798..9550d752e7b 100644 --- a/src/main/java/org/spongepowered/api/event/resource/RegisterResourceReloadListenerEvent.java +++ b/src/main/java/org/spongepowered/api/event/resource/RegisterResourceReloadListenerEvent.java @@ -41,5 +41,5 @@ public interface RegisterResourceReloadListenerEvent extends G * @param listener The listener * @see ResourceReloadListener */ - void registerReloadListener(ResourceReloadListener listener); + void register(ResourceReloadListener listener); } From 2c45a73b025b503845b226053f2342dca21ea5e5 Mon Sep 17 00:00:00 2001 From: Matthew Messinger Date: Sun, 13 Dec 2020 12:27:05 -0500 Subject: [PATCH 16/19] Re-add asset manager to make merges simpler --- src/main/java/org/spongepowered/api/Game.java | 8 + .../java/org/spongepowered/api/Sponge.java | 10 + .../org/spongepowered/api/asset/Asset.java | 216 ++++++++++++++++++ .../org/spongepowered/api/asset/AssetId.java | 50 ++++ .../spongepowered/api/asset/AssetManager.java | 59 +++++ .../spongepowered/api/asset/package-info.java | 26 +++ 6 files changed, 369 insertions(+) create mode 100644 src/main/java/org/spongepowered/api/asset/Asset.java create mode 100644 src/main/java/org/spongepowered/api/asset/AssetId.java create mode 100644 src/main/java/org/spongepowered/api/asset/AssetManager.java create mode 100644 src/main/java/org/spongepowered/api/asset/package-info.java diff --git a/src/main/java/org/spongepowered/api/Game.java b/src/main/java/org/spongepowered/api/Game.java index 691fabcdd42..3a5fe2f7f76 100644 --- a/src/main/java/org/spongepowered/api/Game.java +++ b/src/main/java/org/spongepowered/api/Game.java @@ -24,6 +24,7 @@ */ package org.spongepowered.api; +import org.spongepowered.api.asset.AssetManager; import org.spongepowered.api.command.manager.CommandManager; import org.spongepowered.api.config.ConfigManager; import org.spongepowered.api.data.DataManager; @@ -168,6 +169,13 @@ default Client getClient() { */ EventManager getEventManager(); + /** + * Gets the {@link AssetManager}. + * + * @return The asset manager + */ + AssetManager getAssetManager(); + /** * Gets the {@link ConfigManager} used to load and manage configuration files * for plugins. diff --git a/src/main/java/org/spongepowered/api/Sponge.java b/src/main/java/org/spongepowered/api/Sponge.java index 5b8b5be906f..0f0c42566c9 100644 --- a/src/main/java/org/spongepowered/api/Sponge.java +++ b/src/main/java/org/spongepowered/api/Sponge.java @@ -25,6 +25,7 @@ package org.spongepowered.api; import com.google.inject.Inject; +import org.spongepowered.api.asset.AssetManager; import org.spongepowered.api.command.manager.CommandManager; import org.spongepowered.api.config.ConfigManager; import org.spongepowered.api.data.DataManager; @@ -105,6 +106,15 @@ public static EventManager getEventManager() { return Sponge.getGame().getEventManager(); } + /** + * Gets the {@link AssetManager} instance. + * + * @return The asset manager instance + */ + public static AssetManager getAssetManager() { + return Sponge.getGame().getAssetManager(); + } + /** * Gets the {@link ConfigManager} used to load and manage configuration files * for plugins. diff --git a/src/main/java/org/spongepowered/api/asset/Asset.java b/src/main/java/org/spongepowered/api/asset/Asset.java new file mode 100644 index 00000000000..cda69866cf1 --- /dev/null +++ b/src/main/java/org/spongepowered/api/asset/Asset.java @@ -0,0 +1,216 @@ +/* + * This file is part of SpongeAPI, licensed under the MIT License (MIT). + * + * Copyright (c) SpongePowered + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.spongepowered.api.asset; + +import com.google.common.io.Resources; +import org.spongepowered.plugin.PluginContainer; +import org.spongepowered.plugin.jvm.Plugin; + +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.List; +import java.util.Objects; + +/** + * Represents an {@link Asset} within Sponge that belongs to a {@link Plugin}. + */ +public interface Asset { + + /** + * The default {@link Charset} that is used for reading {@link Asset}s. + */ + Charset DEFAULT_CHARSET = StandardCharsets.UTF_8; + + /** + * Returns the original {@link PluginContainer plugin} owner of this Asset. + * + * @return Original owner of asset + */ + PluginContainer getOwner(); + + /** + * Returns the {@link URL} to this Asset. + * + * @return URL to asset + */ + URL getUrl(); + + /** + * Copies this Asset to the specified 'output' {@link Path}. + * + * @param output Path to copy to + * @throws IOException If any file exception is thrown + */ + default void copyToFile(Path output) throws IOException { + this.copyToFile(output, false); + } + + /** + * Copies this Asset to the specified 'output' {@link Path}. + * + * @param output Path to copy to + * @param overwrite If the file should be overwritten if it exists + * @throws IOException File exception + */ + default void copyToFile(Path output, boolean overwrite) throws IOException { + this.copyToFile(output, overwrite, true); + } + + /** + * Copies this Asset to the specified 'output' {@link Path}. + * + * @param output Path to copy to + * @param overwrite If the file should be overwritten if it exists + * @param onlyIfAbsent If the file should only be copied if absent + * @throws IOException File exception + */ + default void copyToFile(Path output, boolean overwrite, boolean onlyIfAbsent) throws IOException { + Objects.requireNonNull(output, "output"); + if (Files.exists(output)) { + if (overwrite) { + Files.delete(output); + } else if (onlyIfAbsent) { + return; + } + } + try (InputStream in = this.getUrl().openStream()) { + Files.copy(in, output); + } + } + + /** + * Copies this Asset to the specified 'outputDirectory' {@link Path}. + * + * @param outputDirectory The directory to copy to + * @throws IOException If any file exception is thrown + */ + default void copyToDirectory(Path outputDirectory) throws IOException { + this.copyToDirectory(outputDirectory, false); + } + + /** + * Copies this Asset to the specified 'outputDirectory' {@link Path}. + * + * @param outputDirectory The directory to copy to + * @param overwrite If the file should be overwritten if it exists + * @throws IOException File exception + */ + default void copyToDirectory(Path outputDirectory, boolean overwrite) throws IOException { + this.copyToDirectory(outputDirectory, overwrite, true); + } + + /** + * Copies this Asset to the specified 'outputDirectory' {@link Path}. + * + * @param outputDirectory The directory to copy to + * @param overwrite If the file should be overwritten if it exists + * @param onlyIfAbsent If the file should only be copied if absent + * @throws IOException File exception + */ + default void copyToDirectory(Path outputDirectory, boolean overwrite, boolean onlyIfAbsent) throws IOException { + Objects.requireNonNull(outputDirectory, "outputDirectory"); + Files.createDirectories(outputDirectory); + this.copyToFile(outputDirectory.resolve(this.getFileName()), overwrite, onlyIfAbsent); + } + + /** + * Returns the the last portion of the Asset URL, e.g. the file name. + * + * @return The file name + */ + default String getFileName() { + String path = this.getUrl().getPath(); + //We don't need to worry about file system specific file separators as we are dealing with a substring of URL + int end = path.lastIndexOf('/'); + if (end < 0) { + return path; + } + + return path.substring(end + 1); + } + + /** + * Reads this Asset in it's entirety as a {@link String} and returns the + * result. + * + * @return String representation of Asset + * @throws IOException If any file exception is thrown + */ + default String readString() throws IOException { + return this.readString(Asset.DEFAULT_CHARSET); + } + + /** + * Reads this Asset in it's entirety as a {@link String} and returns the + * result. + * + * @param charset The charset to read the asset with + * @return String representation of Asset + * @throws IOException If any file exception is thrown + */ + default String readString(Charset charset) throws IOException { + Objects.requireNonNull(charset, "charset"); + return Resources.toString(this.getUrl(), charset); + } + + /** + * Reads all lines from the asset and returns the result. + * + * @return The lines read from the asset + * @throws IOException If any file exception is thrown + */ + default List readLines() throws IOException { + return this.readLines(Asset.DEFAULT_CHARSET); + } + + /** + * Reads all lines from the asset and returns the result. + * + * @param charset The charset to read the asset with + * @return An immutable list of the lines read from the asset + * @throws IOException If any file exception is thrown + */ + default List readLines(Charset charset) throws IOException { + Objects.requireNonNull(charset, "charset"); + return Resources.asCharSource(this.getUrl(), charset).readLines(); + } + + /** + * Reads this Asset in it's entirety as a byte array and returns the + * result. + * + * @return Byte array representation of Asset + * @throws IOException If any file exception is thrown + */ + default byte[] readBytes() throws IOException { + return Resources.toByteArray(this.getUrl()); + } + +} diff --git a/src/main/java/org/spongepowered/api/asset/AssetId.java b/src/main/java/org/spongepowered/api/asset/AssetId.java new file mode 100644 index 00000000000..94511e1bdfd --- /dev/null +++ b/src/main/java/org/spongepowered/api/asset/AssetId.java @@ -0,0 +1,50 @@ +/* + * This file is part of SpongeAPI, licensed under the MIT License (MIT). + * + * Copyright (c) SpongePowered + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.spongepowered.api.asset; + +import com.google.inject.BindingAnnotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Provides an injection for {@link Asset}s in plugins. + */ +@BindingAnnotation +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.FIELD, ElementType.PARAMETER}) +public @interface AssetId { + + /** + * The path to the {@link Asset} in the asset folder of the plugin. + * + * @return The path to the asset + * @see AssetManager#getAsset(String) + */ + String value(); + +} diff --git a/src/main/java/org/spongepowered/api/asset/AssetManager.java b/src/main/java/org/spongepowered/api/asset/AssetManager.java new file mode 100644 index 00000000000..0d55f2d5b2b --- /dev/null +++ b/src/main/java/org/spongepowered/api/asset/AssetManager.java @@ -0,0 +1,59 @@ +/* + * This file is part of SpongeAPI, licensed under the MIT License (MIT). + * + * Copyright (c) SpongePowered + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.spongepowered.api.asset; + +import org.spongepowered.plugin.PluginContainer; + +import java.util.Optional; + +/** + * The AssetManager offers a convenient way to easily retrieve resources from + * Sponge {@link PluginContainer plugins}. The asset manager will attempt to find the + * asset of the specified name at: assets/<plugin_id> + */ +public interface AssetManager { + + /** + * Returns the {@link Asset} of the specified name for the specified + * {@link PluginContainer plugin} instance. + * + * @param plugin Plugin instance + * @param name Name of resource to retrieve + * @return Asset if present, empty otherwise + */ + Optional getAsset(PluginContainer plugin, String name); + + /** + * Returns the {@link Asset} of the specified name within the domain of the + * implementation. This method will typically call + * {@link #getAsset(PluginContainer, String)} using a dummy + * {@link PluginContainer} for the SpongeAPI implementation. + * + * @param name Name of resource to retrieve + * @return Asset if present, empty otherwise + */ + Optional getAsset(String name); + +} diff --git a/src/main/java/org/spongepowered/api/asset/package-info.java b/src/main/java/org/spongepowered/api/asset/package-info.java new file mode 100644 index 00000000000..bbc2a752e3c --- /dev/null +++ b/src/main/java/org/spongepowered/api/asset/package-info.java @@ -0,0 +1,26 @@ +/* + * This file is part of SpongeAPI, licensed under the MIT License (MIT). + * + * Copyright (c) SpongePowered + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +@org.checkerframework.framework.qual.DefaultQualifier(org.checkerframework.checker.nullness.qual.NonNull.class) +package org.spongepowered.api.asset; From 2c21666ed1a863586a3d65014a58dfc075339a06 Mon Sep 17 00:00:00 2001 From: Matthew Messinger Date: Sun, 13 Dec 2020 12:55:11 -0500 Subject: [PATCH 17/19] Update for registry changes --- .../spongepowered/api/registry/Registries.java | 9 +++++++++ .../spongepowered/api/resource/ResourcePath.java | 2 +- .../api/resource/ResourceReloadListener.java | 2 +- .../api/resource/meta/NamedMetaSections.java | 15 +++++++++++---- .../org/spongepowered/api/resource/pack/Pack.java | 4 ++-- .../api/resource/pack/PackTypes.java | 13 +++++++++---- .../api/resource/pack/PackVersions.java | 15 ++++++++++----- 7 files changed, 43 insertions(+), 17 deletions(-) diff --git a/src/main/java/org/spongepowered/api/registry/Registries.java b/src/main/java/org/spongepowered/api/registry/Registries.java index 4c254a44e55..a10af653b7b 100644 --- a/src/main/java/org/spongepowered/api/registry/Registries.java +++ b/src/main/java/org/spongepowered/api/registry/Registries.java @@ -110,6 +110,9 @@ import org.spongepowered.api.item.potion.PotionType; import org.spongepowered.api.item.recipe.RecipeType; import org.spongepowered.api.placeholder.PlaceholderParser; +import org.spongepowered.api.resource.meta.NamedMetaSection; +import org.spongepowered.api.resource.pack.PackType; +import org.spongepowered.api.resource.pack.PackVersion; import org.spongepowered.api.scheduler.TaskPriority; import org.spongepowered.api.scoreboard.CollisionRule; import org.spongepowered.api.scoreboard.Visibility; @@ -303,6 +306,8 @@ public final class Registries { public static final RegistryKey> MUSIC_DISC = Registries.spongeKey("music_disc"); + public static final RegistryKey>> NAMED_META_SECTION = Registries.spongeKey("named_meta_section"); + public static final RegistryKey> NOTE_PITCH = Registries.spongeKey("note_pitch"); public static final RegistryKey> OBJECTIVE_DISPLAY_MODE = Registries.spongeKey("objective_display_mode"); @@ -311,6 +316,10 @@ public final class Registries { public static final RegistryKey> ORIENTATION = Registries.spongeKey("orientation"); + public static final RegistryKey PACK_TYPE = Registries.spongeKey("pack_type"); + + public static final RegistryKey PACK_VERSION=Registries.spongeKey("pack_version"); + public static final RegistryKey>> PALETTE_TYPE = Registries.spongeKey("palette_type"); public static final RegistryKey> PANDA_GENE = Registries.spongeKey("panda_gene"); diff --git a/src/main/java/org/spongepowered/api/resource/ResourcePath.java b/src/main/java/org/spongepowered/api/resource/ResourcePath.java index da50cf045b1..7427efc8b87 100644 --- a/src/main/java/org/spongepowered/api/resource/ResourcePath.java +++ b/src/main/java/org/spongepowered/api/resource/ResourcePath.java @@ -48,7 +48,7 @@ public interface ResourcePath extends Comparable { * @return The new builder instance */ static Builder builder() { - return Sponge.getRegistry().getBuilderRegistry().provideBuilder(Builder.class); + return Sponge.getGame().getBuilderProvider().provide(Builder.class); } /** diff --git a/src/main/java/org/spongepowered/api/resource/ResourceReloadListener.java b/src/main/java/org/spongepowered/api/resource/ResourceReloadListener.java index eba67ffd545..783f825586a 100644 --- a/src/main/java/org/spongepowered/api/resource/ResourceReloadListener.java +++ b/src/main/java/org/spongepowered/api/resource/ResourceReloadListener.java @@ -71,7 +71,7 @@ public interface ResourceReloadListener { static Factory factory() { - return Sponge.getRegistry().getFactoryRegistry().provideFactory(Factory.class); + return Sponge.getGame().getFactoryProvider().provide(Factory.class); } /** diff --git a/src/main/java/org/spongepowered/api/resource/meta/NamedMetaSections.java b/src/main/java/org/spongepowered/api/resource/meta/NamedMetaSections.java index 0d57076f7fd..12a731bb0e7 100644 --- a/src/main/java/org/spongepowered/api/resource/meta/NamedMetaSections.java +++ b/src/main/java/org/spongepowered/api/resource/meta/NamedMetaSections.java @@ -24,17 +24,24 @@ */ package org.spongepowered.api.resource.meta; +import org.spongepowered.api.ResourceKey; import org.spongepowered.api.Sponge; - -import java.util.function.Supplier; +import org.spongepowered.api.registry.DefaultedRegistryReference; +import org.spongepowered.api.registry.Registries; +import org.spongepowered.api.registry.RegistryKey; public class NamedMetaSections { // SORTFIELDS:ON - private static final Supplier> PACK = Sponge.getRegistry().getCatalogRegistry().provideSupplier(NamedMetaSection.class, "pack/pack"); + private static final DefaultedRegistryReference> PACK = NamedMetaSections.key(ResourceKey.sponge("pack/pack")); // SORTFIELDS:OFF - private NamedMetaSections() {} + private NamedMetaSections() { + } + + private static DefaultedRegistryReference> key(final ResourceKey location) { + return RegistryKey.>of(Registries.NAMED_META_SECTION.registry(), location).asDefaultedReference(() -> Sponge.getGame().registries()); + } } diff --git a/src/main/java/org/spongepowered/api/resource/pack/Pack.java b/src/main/java/org/spongepowered/api/resource/pack/Pack.java index d79837f3f1e..672bfc9600f 100644 --- a/src/main/java/org/spongepowered/api/resource/pack/Pack.java +++ b/src/main/java/org/spongepowered/api/resource/pack/Pack.java @@ -59,7 +59,7 @@ public interface Pack extends Nameable, Closeable { * @return The supplier to create a new pack. */ static Supplier fromPath(Path path) { - return Sponge.getRegistry().getFactoryRegistry().provideFactory(Factory.class).fromPath(path); + return Sponge.getGame().getFactoryProvider().provide(Factory.class).fromPath(path); } /** @@ -70,7 +70,7 @@ static Supplier fromPath(Path path) { * @see PluginContainer#getPath() */ static Supplier fromPlugin(PluginContainer pluginContainer) { - return Sponge.getRegistry().getFactoryRegistry().provideFactory(Factory.class).fromPlugin(pluginContainer); + return Sponge.getGame().getFactoryProvider().provide(Factory.class).fromPlugin(pluginContainer); } /** diff --git a/src/main/java/org/spongepowered/api/resource/pack/PackTypes.java b/src/main/java/org/spongepowered/api/resource/pack/PackTypes.java index fa1f26b3540..80040e9a16f 100644 --- a/src/main/java/org/spongepowered/api/resource/pack/PackTypes.java +++ b/src/main/java/org/spongepowered/api/resource/pack/PackTypes.java @@ -24,21 +24,26 @@ */ package org.spongepowered.api.resource.pack; +import org.spongepowered.api.ResourceKey; import org.spongepowered.api.Sponge; - -import java.util.function.Supplier; +import org.spongepowered.api.registry.DefaultedRegistryReference; +import org.spongepowered.api.registry.Registries; +import org.spongepowered.api.registry.RegistryKey; public final class PackTypes { // SORTFIELDS:ON - public static final Supplier CLIENT_RESOURCES = Sponge.getRegistry().getCatalogRegistry().provideSupplier(PackType.class, "CLIENT_RESOURCES"); + public static final DefaultedRegistryReference CLIENT_RESOURCES = PackTypes.key(ResourceKey.sponge("client_resources")); - public static final Supplier SERVER_DATA = Sponge.getRegistry().getCatalogRegistry().provideSupplier(PackType.class, "SERVER_DATA"); + public static final DefaultedRegistryReference SERVER_DATA = PackTypes.key(ResourceKey.sponge("server_data")); // SORTFIELDS:OFF private PackTypes() { } + private static DefaultedRegistryReference key(final ResourceKey location) { + return RegistryKey.of(Registries.PACK_TYPE.registry(), location).asDefaultedReference(() -> Sponge.getGame().registries()); + } } diff --git a/src/main/java/org/spongepowered/api/resource/pack/PackVersions.java b/src/main/java/org/spongepowered/api/resource/pack/PackVersions.java index 12a5e1756d0..d0e1380c71a 100644 --- a/src/main/java/org/spongepowered/api/resource/pack/PackVersions.java +++ b/src/main/java/org/spongepowered/api/resource/pack/PackVersions.java @@ -24,23 +24,28 @@ */ package org.spongepowered.api.resource.pack; +import org.spongepowered.api.ResourceKey; import org.spongepowered.api.Sponge; - -import java.util.function.Supplier; +import org.spongepowered.api.registry.DefaultedRegistryReference; +import org.spongepowered.api.registry.Registries; +import org.spongepowered.api.registry.RegistryKey; public class PackVersions { // SORTFIELDS:ON - public static final Supplier COMPATIBLE = Sponge.getRegistry().getCatalogRegistry().provideSupplier(PackVersion.class, "COMPATIBLE"); + public static final DefaultedRegistryReference COMPATIBLE = PackVersions.key(ResourceKey.sponge("compatible")); - public static final Supplier TOO_NEW = Sponge.getRegistry().getCatalogRegistry().provideSupplier(PackVersion.class, "TOO_NEW"); + public static final DefaultedRegistryReference TOO_NEW = PackVersions.key(ResourceKey.sponge("too_new")); - public static final Supplier TOO_OLD = Sponge.getRegistry().getCatalogRegistry().provideSupplier(PackVersion.class, "TOO_OLD"); + public static final DefaultedRegistryReference TOO_OLD = PackVersions.key(ResourceKey.sponge("too_old")); // SORTFIELDS:OFF private PackVersions() { } + private static DefaultedRegistryReference key(final ResourceKey location) { + return RegistryKey.of(Registries.PACK_VERSION.registry(), location).asDefaultedReference(() -> Sponge.getGame().registries()); + } } From 1f49acdfa8068dc7d443b0cf88e056a03c377a5c Mon Sep 17 00:00:00 2001 From: Matthew Messinger Date: Sun, 13 Dec 2020 13:03:59 -0500 Subject: [PATCH 18/19] Fix badly defined registries --- src/main/java/org/spongepowered/api/registry/Registries.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/spongepowered/api/registry/Registries.java b/src/main/java/org/spongepowered/api/registry/Registries.java index a10af653b7b..2bc663c9064 100644 --- a/src/main/java/org/spongepowered/api/registry/Registries.java +++ b/src/main/java/org/spongepowered/api/registry/Registries.java @@ -316,9 +316,9 @@ public final class Registries { public static final RegistryKey> ORIENTATION = Registries.spongeKey("orientation"); - public static final RegistryKey PACK_TYPE = Registries.spongeKey("pack_type"); + public static final RegistryKey> PACK_TYPE = Registries.spongeKey("pack_type"); - public static final RegistryKey PACK_VERSION=Registries.spongeKey("pack_version"); + public static final RegistryKey> PACK_VERSION = Registries.spongeKey("pack_version"); public static final RegistryKey>> PALETTE_TYPE = Registries.spongeKey("palette_type"); From c4b7a11e994080f37fd729e805688e0a03cb2c85 Mon Sep 17 00:00:00 2001 From: Matthew Messinger Date: Sun, 13 Dec 2020 16:24:43 -0500 Subject: [PATCH 19/19] ResourcePath now wraps ResourceKey --- .../api/resource/ResourcePath.java | 136 ++++++++---------- .../api/resource/ResourcePathException.java | 42 ------ 2 files changed, 63 insertions(+), 115 deletions(-) delete mode 100644 src/main/java/org/spongepowered/api/resource/ResourcePathException.java diff --git a/src/main/java/org/spongepowered/api/resource/ResourcePath.java b/src/main/java/org/spongepowered/api/resource/ResourcePath.java index 7427efc8b87..cdcc1f8dbf9 100644 --- a/src/main/java/org/spongepowered/api/resource/ResourcePath.java +++ b/src/main/java/org/spongepowered/api/resource/ResourcePath.java @@ -24,16 +24,15 @@ */ package org.spongepowered.api.resource; +import org.spongepowered.api.ResourceKey; import org.spongepowered.api.Sponge; -import org.spongepowered.api.util.ResettableBuilder; import org.spongepowered.plugin.PluginContainer; -import java.util.Collection; -import java.util.List; - /** * A namespaced path object used to get {@link Resource}s from the * {@link ResourceManager}. + * + * @see ResourceKey */ public interface ResourcePath extends Comparable { @@ -42,35 +41,28 @@ public interface ResourcePath extends Comparable { */ String SEPARATOR = "/"; - /** - * Creates a new {@link Builder} for creating {@link ResourcePath}s. - * - * @return The new builder instance - */ - static Builder builder() { - return Sponge.getGame().getBuilderProvider().provide(Builder.class); - } - /** * Creates a resource path. * * @param namespace The namespace * @param value The value * @return A new resource path + * @see ResourceKey#of(String, String) */ static ResourcePath of(final String namespace, final String value) { - return builder().namespace(namespace).path(value).build(); + return ResourcePath.of(ResourceKey.of(namespace, value)); } /** - * Creates a resource path. + * Creates a resource path from a plugin container. * - * @param container The container + * @param container The plugin container * @param value The value * @return A new resource path + * @see ResourceKey#of(PluginContainer, String) */ static ResourcePath of(final PluginContainer container, final String value) { - return builder().namespace(container).path(value).build(); + return ResourcePath.of(ResourceKey.of(container, value)); } /** @@ -81,24 +73,48 @@ static ResourcePath of(final PluginContainer container, final String value) { * * @param value The value * @return A new resource path + * @see ResourceKey#resolve(String) */ static ResourcePath parse(final String value) { - return builder().path(value).build(); + return ResourcePath.of(ResourceKey.resolve(value)); } + /** + * Creates a new path using the given {@link ResourceKey}. + * + * @param key The key object + * @return A new path + */ + static ResourcePath of(final ResourceKey key) { + return Sponge.getGame().getFactoryProvider().provide(Factory.class).of(key); + } + + /** + * Gets the backing {@link ResourceKey} for this path object. + * + * @return The key object + */ + ResourceKey key(); + /** * Gets the namespace portion of this resource path. * * @return The namespace + * @see ResourceKey#getNamespace() */ - String getNamespace(); + default String getNamespace() { + return this.key().getNamespace(); + } /** * Gets the path portion of this resource path. * * @return The path + * @see ResourceKey#getValue() */ - String getPath(); + default String getPath() { + return this.key().getValue(); + } // resolution methods @@ -106,58 +122,32 @@ static ResourcePath parse(final String value) { * Resolves this resource path's parent. * * @return The parent path - * @throws ResourcePathException If the parent normalizes to null + * @throws IllegalStateException If the path has no parent */ - ResourcePath getParent() throws ResourcePathException; - - /** - * Resolves a single file as a child of this path. - * - * @param child The child path's name - * @return The resolved path - * @throws ResourcePathException If the path is invalid or could not be - * normalized - * @see #resolve(String...) - */ - default ResourcePath resolve(String child) throws ResourcePathException { - return resolve(new String[]{child}); - } + ResourcePath getParent(); /** * Resolves a path from the current location using the specified children. * - * @param children The children paths - * @return The resolved path - * @throws ResourcePathException If the path is invalid or could not be - * normalized + * @param first The first child + * @param children The rest of the children + * @return The resolvedIllegalArgumentException path + * @throws IllegalArgumentException If the path is invalid */ - ResourcePath resolve(String... children) throws ResourcePathException; + ResourcePath resolve(String first, String... children); /** - * @param sibling The sibling's name + * Resolves a sibling of this path. + * + * @param sibling The sibling's name + * @param children The optional children of the sibling * @return The sibling resource path - * @throws ResourcePathException If the path is invalid or could not be - * normalized + * @throws IllegalArgumentException If the path is invalid */ - ResourcePath resolveSibling(String sibling) throws ResourcePathException; + ResourcePath resolveSibling(String sibling, String... children); // path utility methods - /** - * Gets all the parts of this path. i.e. the full path split by - * {@link #SEPARATOR}. The result list is unmodifiable. - * - * @return The path parts - */ - List getPathParts(); - - /** - * Gets the parent of this path or root if this is root. - * - * @return The parent path - */ - String getParentPath(); - /** * Gets the name of the file without any parent elements. * @@ -184,21 +174,21 @@ default ResourcePath resolve(String child) throws ResourcePathException { * Gets the string representation of this path as {@code "namspace:path"} * * @return The string representation + * @see ResourceKey#asString() */ - String toString(); - - interface Builder extends ResettableBuilder { - - Builder namespace(String namespace); - - Builder namespace(PluginContainer container); + String asString(); - Builder path(String path); - - Builder paths(String... paths); - - Builder paths(Collection paths); - - ResourcePath build() throws ResourcePathException; + /** + * A factory to create {@link ResourcePath}s. + */ + interface Factory { + /** + * Creates a new {@link ResourcePath} using the given + * {@link ResourceKey}. + * + * @param key The key object + * @return A new path object + */ + ResourcePath of(ResourceKey key); } } diff --git a/src/main/java/org/spongepowered/api/resource/ResourcePathException.java b/src/main/java/org/spongepowered/api/resource/ResourcePathException.java deleted file mode 100644 index 1346591fb54..00000000000 --- a/src/main/java/org/spongepowered/api/resource/ResourcePathException.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * This file is part of SpongeAPI, licensed under the MIT License (MIT). - * - * Copyright (c) SpongePowered - * Copyright (c) contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package org.spongepowered.api.resource; - -/** - * An exception thrown when a {@link ResourcePath} could not be created. - */ -public class ResourcePathException extends RuntimeException { - public ResourcePathException(String message) { - super(message); - } - - public ResourcePathException(Throwable e) { - super(e); - } - - public ResourcePathException(String message, Throwable e) { - super(message, e); - } -}