Skip to content

Commit

Permalink
Deduplicate code and ensure all ID variants have network and NBT meth…
Browse files Browse the repository at this point in the history
…ods as relevant

Technicaly there is a breaking change here with the removal of a method in pattern, but that method was broken so there is no way anyone was using it.
The protected class from pattern being removed should not be a breaking change
  • Loading branch information
KnightMiner committed Dec 29, 2023
1 parent 5a99461 commit 25baf8d
Show file tree
Hide file tree
Showing 7 changed files with 103 additions and 89 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,19 @@

import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonSyntaxException;
import net.minecraft.ResourceLocationException;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.util.GsonHelper;
import net.minecraft.world.item.ItemStack;
import slimeknights.tconstruct.library.tools.part.IMaterialItem;
import slimeknights.tconstruct.library.utils.IdParser;

import javax.annotation.Nullable;

/**
* This is just a copy of ResourceLocation for type safety.
*/
public final class MaterialId extends ResourceLocation implements MaterialVariantId {
public static final IdParser<MaterialId> PARSER = new IdParser<>(MaterialId::new, "Material");

public MaterialId(String resourceName) {
super(resourceName);
}
Expand Down Expand Up @@ -71,20 +71,7 @@ public boolean matchesVariant(MaterialVariantId other) {
*/
@Nullable
public static MaterialId tryParse(String string) {
try {
return new MaterialId(string);
} catch (ResourceLocationException resourcelocationexception) {
return null;
}
}

/** Shared logic for {@link #fromJson(JsonObject, String)} and {@link #convertJson(JsonElement, String)} */
private static MaterialId parse(String text, String key) {
MaterialId location = tryParse(text);
if (location == null) {
throw new JsonSyntaxException("Expected " + key + " to be a material ID, was '" + text + "'");
}
return location;
return PARSER.tryParse(string);
}

/**
Expand All @@ -94,8 +81,7 @@ private static MaterialId parse(String text, String key) {
* @return Resource location parsed
*/
public static MaterialId fromJson(JsonObject json, String key) {
String text = GsonHelper.getAsString(json, key);
return parse(text, key);
return PARSER.getFromJson(json, key);
}

/**
Expand All @@ -105,7 +91,6 @@ public static MaterialId fromJson(JsonObject json, String key) {
* @return Resource location parsed
*/
public static MaterialId convertJson(JsonElement json, String key) {
String text = GsonHelper.convertToString(json, key);
return parse(text, key);
return PARSER.convertFromJson(json, key);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import com.google.gson.JsonObject;
import com.google.gson.JsonSyntaxException;
import net.minecraft.ResourceLocationException;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.util.GsonHelper;
import net.minecraft.world.item.ItemStack;
Expand Down Expand Up @@ -103,6 +104,9 @@ static MaterialVariantId parse(String text) {
return location;
}


/* JSON */

/** Shared logic for {@link #fromJson(JsonObject, String)} and {@link #convertJson(JsonElement, String)} */
private static MaterialVariantId parse(String text, String key) {
MaterialVariantId location = tryParse(text);
Expand Down Expand Up @@ -133,4 +137,17 @@ static MaterialVariantId convertJson(JsonElement json, String key) {
String text = GsonHelper.convertToString(json, key);
return parse(text, key);
}


/* Networking */

/** Writes an ID to the packet buffer */
default void toNetwork(FriendlyByteBuf buf) {
buf.writeUtf(toString());
}

/** Reads an ID from the packet buffer */
static MaterialVariantId fromNetwork(FriendlyByteBuf buf) {
return parse(buf.readUtf(Short.MAX_VALUE));
}
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
package slimeknights.tconstruct.library.materials.stats;

import net.minecraft.resources.ResourceLocation;
import slimeknights.tconstruct.library.utils.IdParser;

/**
* This is just a copy of ResourceLocation for type safety.
*/
public class MaterialStatsId extends ResourceLocation {
public static final IdParser<MaterialStatsId> PARSER = new IdParser<>(MaterialStatsId::new, "Material Stat Type");

public MaterialStatsId(String text) {
super(text);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,17 @@

import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonSyntaxException;
import net.minecraft.ResourceLocationException;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.util.GsonHelper;
import slimeknights.tconstruct.library.utils.IdParser;

import javax.annotation.Nullable;

/**
* This is just a copy of ResourceLocation for type safety.
*/
public class ModifierId extends ResourceLocation {
public static final IdParser<ModifierId> PARSER = new IdParser<>(ModifierId::new, "Modifier");

public ModifierId(String resourceName) {
super(resourceName);
Expand All @@ -34,11 +33,7 @@ public ModifierId(ResourceLocation resourceLocation) {
*/
@Nullable
public static ModifierId tryParse(String string) {
try {
return new ModifierId(string);
} catch (ResourceLocationException resourcelocationexception) {
return null;
}
return PARSER.tryParse(string);
}

/**
Expand All @@ -48,12 +43,7 @@ public static ModifierId tryParse(String string) {
* @return Resource location parsed
*/
public static ModifierId getFromJson(JsonObject json, String key) {
String text = GsonHelper.getAsString(json, key);
ModifierId location = tryParse(text);
if (location == null) {
throw new JsonSyntaxException("Expected " + key + " to be a Modifier ID, was '" + text + "'");
}
return location;
return PARSER.getFromJson(json, key);
}

/**
Expand All @@ -63,12 +53,7 @@ public static ModifierId getFromJson(JsonObject json, String key) {
* @return Resource location parsed
*/
public static ModifierId convertFromJson(JsonElement json, String key) {
String text = GsonHelper.convertToString(json, key);
ModifierId location = tryParse(text);
if (location == null) {
throw new JsonSyntaxException("Expected " + key + " to be a Modifier ID, was '" + text + "'");
}
return location;
return PARSER.convertFromJson(json, key);
}

/** Writes an ID to the packet buffer */
Expand Down
Original file line number Diff line number Diff line change
@@ -1,28 +1,18 @@
package slimeknights.tconstruct.library.recipe.partbuilder;

import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonParseException;
import com.google.gson.JsonPrimitive;
import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonSerializer;
import net.minecraft.util.GsonHelper;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.ResourceLocationException;
import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.TranslatableComponent;
import slimeknights.tconstruct.library.modifiers.ModifierId;
import net.minecraft.resources.ResourceLocation;
import slimeknights.mantle.data.ResourceLocationSerializer;
import slimeknights.tconstruct.library.utils.IdParser;
import slimeknights.tconstruct.library.utils.Util;

import javax.annotation.Nullable;
import java.lang.reflect.Type;

/**
* This is a copy of resource location with a couple extra helpers
*/
public class Pattern extends ResourceLocation {
public static final Serializer SERIALIZER = new Serializer();
public static final IdParser<Pattern> PARSER = new IdParser<>(Pattern::new, "Pattern");
public static final ResourceLocationSerializer<Pattern> SERIALIZER = new ResourceLocationSerializer<>(Pattern::new, "minecraft");

public Pattern(String resourceName) {
super(resourceName);
Expand All @@ -36,20 +26,6 @@ public Pattern(ResourceLocation resourceLocation) {
super(resourceLocation.getNamespace(), resourceLocation.getPath());
}

/**
* Creates a new modifier ID from the given string
* @param string String
* @return Material ID, or null if invalid
*/
@Nullable
public static ModifierId tryCreate(String string) {
try {
return new ModifierId(string);
} catch (ResourceLocationException resourcelocationexception) {
return null;
}
}

/**
* Gets the display name for this pattern
* @return Display name
Expand All @@ -65,17 +41,4 @@ public Component getDisplayName() {
public ResourceLocation getTexture() {
return new ResourceLocation(getNamespace(), "gui/tinker_pattern/" + getPath());
}

/** Type sensitive version of the resource location serializer */
protected static class Serializer implements JsonDeserializer<Pattern>, JsonSerializer<Pattern> {
@Override
public Pattern deserialize(JsonElement json, Type type, JsonDeserializationContext context) throws JsonParseException {
return new Pattern(GsonHelper.convertToString(json, "location"));
}

@Override
public JsonElement serialize(Pattern pattern, Type type, JsonSerializationContext context) {
return new JsonPrimitive(pattern.toString());
}
}
}
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
package slimeknights.tconstruct.library.tools.stat;

import net.minecraft.resources.ResourceLocation;
import net.minecraft.ResourceLocationException;
import slimeknights.tconstruct.library.utils.IdParser;

import javax.annotation.Nullable;

/**
* This is just a copy of ResourceLocation for type safety.
*/
public class ToolStatId extends ResourceLocation {
public static final IdParser<ToolStatId> PARSER = new IdParser<>(ToolStatId::new, "Tool Stat");

public ToolStatId(String namespaceIn, String pathIn) {
super(namespaceIn, pathIn);
Expand All @@ -29,10 +30,6 @@ public ToolStatId(String value) {
*/
@Nullable
public static ToolStatId tryCreate(String string) {
try {
return new ToolStatId(string);
} catch (ResourceLocationException resourcelocationexception) {
return null;
}
return PARSER.tryParse(string);
}
}
64 changes: 64 additions & 0 deletions src/main/java/slimeknights/tconstruct/library/utils/IdParser.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
package slimeknights.tconstruct.library.utils;

import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonSyntaxException;
import net.minecraft.ResourceLocationException;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.util.GsonHelper;

import javax.annotation.Nullable;
import java.util.function.Function;

/** Helper to parse variants of resource locations */
public record IdParser<T extends ResourceLocation>(Function<String, T> constructor, String name) {
/**
* Creates a new ID from the given string
* @param string String
* @return ID, or null if invalid
*/
@Nullable
public T tryParse(String string) {
try {
return constructor.apply(string);
} catch (ResourceLocationException resourcelocationexception) {
return null;
}
}

/**
* Gets an ID from JSON, throwing a nice exception if invalid
* @param json JSON object
* @param key Key to fetch
* @return Resource location parsed
*/
public T getFromJson(JsonObject json, String key) {
String text = GsonHelper.getAsString(json, key);
T location = tryParse(text);
if (location == null) {
throw new JsonSyntaxException("Expected " + key + " to be a " + name + " ID, was '" + text + "'");
}
return location;
}

/**
* Gets an ID from JSON, throwing a nice exception if invalid
* @param json JSON object
* @param key Key to fetch
* @return Resource location parsed
*/
public T convertFromJson(JsonElement json, String key) {
String text = GsonHelper.convertToString(json, key);
T location = tryParse(text);
if (location == null) {
throw new JsonSyntaxException("Expected " + key + " to be a " + name + " ID, was '" + text + "'");
}
return location;
}

/** Reads an ID from the packet buffer */
public T fromNetwork(FriendlyByteBuf buf) {
return constructor.apply(buf.readUtf(Short.MAX_VALUE));
}
}

0 comments on commit 25baf8d

Please sign in to comment.