feat(D-01): instantiate ComponentHolder per item definition on reload

Add a parallel COMPONENT_HOLDERS volatile cache to DataDrivenItemRegistry,
rebuilt from raw componentConfigs every time definitions are loaded via
reload() or mergeAll(). Cleared alongside DEFINITIONS in clear().

Two accessor methods allow looking up a ComponentHolder by ItemStack
(reads tiedup_item_id NBT) or by ResourceLocation directly.
This commit is contained in:
NotEvil
2026-04-14 01:46:19 +02:00
parent 750be66d80
commit a781dad597

View File

@@ -1,7 +1,12 @@
package com.tiedup.remake.v2.bondage.datadriven; package com.tiedup.remake.v2.bondage.datadriven;
import com.google.gson.JsonObject;
import com.tiedup.remake.v2.bondage.component.ComponentHolder;
import com.tiedup.remake.v2.bondage.component.ComponentType;
import com.tiedup.remake.v2.bondage.component.IItemComponent;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.EnumMap;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.CompoundTag;
@@ -34,6 +39,13 @@ public final class DataDrivenItemRegistry {
DataDrivenItemDefinition DataDrivenItemDefinition
> DEFINITIONS = Map.of(); > DEFINITIONS = Map.of();
/**
* Parallel cache of instantiated component holders, keyed by item definition ID.
* Rebuilt every time DEFINITIONS changes.
*/
private static volatile Map<ResourceLocation, ComponentHolder>
COMPONENT_HOLDERS = Map.of();
private DataDrivenItemRegistry() {} private DataDrivenItemRegistry() {}
/** /**
@@ -46,6 +58,7 @@ public final class DataDrivenItemRegistry {
Map<ResourceLocation, DataDrivenItemDefinition> newDefs Map<ResourceLocation, DataDrivenItemDefinition> newDefs
) { ) {
DEFINITIONS = Collections.unmodifiableMap(new HashMap<>(newDefs)); DEFINITIONS = Collections.unmodifiableMap(new HashMap<>(newDefs));
COMPONENT_HOLDERS = buildComponentHolders(DEFINITIONS);
} }
/** /**
@@ -66,6 +79,7 @@ public final class DataDrivenItemRegistry {
); );
merged.putAll(newDefs); merged.putAll(newDefs);
DEFINITIONS = Collections.unmodifiableMap(merged); DEFINITIONS = Collections.unmodifiableMap(merged);
COMPONENT_HOLDERS = buildComponentHolders(DEFINITIONS);
} }
/** /**
@@ -111,5 +125,65 @@ public final class DataDrivenItemRegistry {
*/ */
public static void clear() { public static void clear() {
DEFINITIONS = Map.of(); DEFINITIONS = Map.of();
COMPONENT_HOLDERS = Map.of();
}
// ===== COMPONENT HOLDERS =====
/**
* Get the ComponentHolder for a data-driven item stack.
*
* @param stack the ItemStack to inspect
* @return the holder, or null if the stack is not data-driven or has no definition
*/
@Nullable
public static ComponentHolder getComponents(ItemStack stack) {
DataDrivenItemDefinition def = get(stack);
if (def == null) return null;
return COMPONENT_HOLDERS.get(def.id());
}
/**
* Get the ComponentHolder for a data-driven item by its definition ID.
*
* @param id the definition ID
* @return the holder, or null if not found
*/
@Nullable
public static ComponentHolder getComponents(ResourceLocation id) {
return COMPONENT_HOLDERS.get(id);
}
/**
* Build component holders from a definitions map.
* Each definition's raw componentConfigs are instantiated via
* {@link ComponentType#create(JsonObject)}.
*/
private static Map<ResourceLocation, ComponentHolder> buildComponentHolders(
Map<ResourceLocation, DataDrivenItemDefinition> definitions
) {
Map<ResourceLocation, ComponentHolder> holders = new HashMap<>();
for (Map.Entry<ResourceLocation, DataDrivenItemDefinition> entry :
definitions.entrySet()) {
DataDrivenItemDefinition def = entry.getValue();
Map<ComponentType, IItemComponent> components =
new EnumMap<>(ComponentType.class);
if (def.componentConfigs() != null) {
for (Map.Entry<ComponentType, JsonObject> compEntry :
def.componentConfigs().entrySet()) {
components.put(
compEntry.getKey(),
compEntry.getKey().create(compEntry.getValue())
);
}
}
holders.put(
entry.getKey(),
components.isEmpty()
? ComponentHolder.EMPTY
: new ComponentHolder(components)
);
}
return Collections.unmodifiableMap(holders);
} }
} }