From dad68746389318e02cc8dd44bf8f2cd8da1bac05 Mon Sep 17 00:00:00 2001 From: Jonathan Coates Date: Sun, 11 Aug 2024 11:53:16 +0100 Subject: [PATCH] Add detail provider for data components Historically we'd provide specific data based on the current item and NBT (hence BasicItemDetailProvider). However, with components, it now makes sense to provide details for all items with a specific component. This commit adds a new "ComponentDetailProvider" class, that reads a component from an item stack (or other component holder) and provides details about it if present. --- .../api/detail/ComponentDetailProvider.java | 72 +++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 projects/common-api/src/main/java/dan200/computercraft/api/detail/ComponentDetailProvider.java diff --git a/projects/common-api/src/main/java/dan200/computercraft/api/detail/ComponentDetailProvider.java b/projects/common-api/src/main/java/dan200/computercraft/api/detail/ComponentDetailProvider.java new file mode 100644 index 000000000..c79e526b4 --- /dev/null +++ b/projects/common-api/src/main/java/dan200/computercraft/api/detail/ComponentDetailProvider.java @@ -0,0 +1,72 @@ +// SPDX-FileCopyrightText: 2024 The CC: Tweaked Developers +// +// SPDX-License-Identifier: MPL-2.0 + +package dan200.computercraft.api.detail; + +import net.minecraft.core.component.DataComponentHolder; +import net.minecraft.core.component.DataComponentType; +import net.minecraft.world.item.ItemStack; + +import javax.annotation.Nullable; +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; + +/** + * An item detail provider for a specific {@linkplain DataComponentType data component} on {@link ItemStack}s or + * other {@link DataComponentHolder}. + * + * @param The type of the component's contents. + */ +public abstract class ComponentDetailProvider implements DetailProvider { + private final DataComponentType component; + private final @Nullable String namespace; + + /** + * Create a new component detail provider. Details will be inserted into a new sub-map named as per {@code namespace}. + * + * @param component The data component to provide details for. + * @param namespace The namespace to use for this provider. + */ + public ComponentDetailProvider(@Nullable String namespace, DataComponentType component) { + Objects.requireNonNull(component); + this.component = component; + this.namespace = namespace; + } + + /** + * Create a new component detail provider. Details will be inserted directly into the results. + * + * @param component The data component to provide details for. + */ + public ComponentDetailProvider(DataComponentType component) { + this(null, component); + } + + /** + * Provide additional details for the given data component. This method is called by {@code turtle.getItemDetail()}. + * New properties should be added to the given {@link Map}, {@code data}. + *

+ * This method is always called on the server thread, so it is safe to interact with the world here, but you should + * take care to avoid long blocking operations as this will stall the server and other computers. + * + * @param data The full details to be returned for this item stack. New properties should be added to this map. + * @param item The component to provide details for. + */ + public abstract void provideComponentDetails(Map data, T item); + + @Override + public final void provideDetails(Map data, DataComponentHolder holder) { + var value = holder.get(component); + if (value == null) return; + + if (namespace == null) { + provideComponentDetails(data, value); + } else { + Map child = new HashMap<>(); + provideComponentDetails(child, value); + data.put(namespace, child); + } + } +}