Skip to content

Commit

Permalink
Remove strict requirement that a content type is read from a string
Browse files Browse the repository at this point in the history
Buffer method is now generic, JSON has an option to read/write to object or element, and NBT is just manual now
Should mean buffer is more efficient
  • Loading branch information
KnightMiner committed Sep 13, 2020
1 parent 25dca09 commit 71baca2
Show file tree
Hide file tree
Showing 16 changed files with 315 additions and 199 deletions.
Expand Up @@ -30,7 +30,7 @@ public CauldronContentUpatePacket(PacketBuffer buffer) {
@Override
public void encode(PacketBuffer buffer) {
buffer.writeBlockPos(pos);
CauldronContentTypes.write(contents, buffer);
contents.write(buffer);
}

@Override
Expand Down
Expand Up @@ -25,13 +25,14 @@
import net.minecraftforge.common.util.Lazy;

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

/**
* Registry that helps with registering, serializing, and deserializing cauldron properties
*/
public class CauldronContentTypes {
private static final ResourceLocation UNREGISTERED = Inspirations.getResource("null");
private static final String KEY_TYPE = "type";
public static final String KEY_TYPE = "type";
private static final BiMap<ResourceLocation,CauldronContentType<?>> TYPES = HashBiMap.create();

/* Public constants */
Expand Down Expand Up @@ -102,45 +103,34 @@ public static ResourceLocation getName(CauldronContentType<?> type) {
}

/**
* Converts the given contents to JSON
* @param contents Contents
* @return JSON
* Simple helper function to make the generics work out
* @param type Content type
* @param data Data being read
* @param parser Parses data into contents
*/
public static JsonObject toJson(ICauldronContents contents) {
JsonObject json = new JsonObject();
CauldronContentType<?> type = contents.getType();
json.addProperty(KEY_TYPE, getName(type).toString());
type.write(contents, json);
return json;
private static <T, D> ICauldronContents read(CauldronContentType<T> type, D data, BiFunction<CauldronContentType<T>,D,T> parser) {
T value = parser.apply(type, data);
if (value == null) {
return DEFAULT.get();
}
return type.of(value);
}

/**
* Reads the cauldron contents from JSON
* @param json JSON to read
* @return Cauldron contents
* @throws JsonSyntaxException If the type is missing or the data invalid
*/
public static ICauldronContents read(JsonObject json) {
ResourceLocation location = new ResourceLocation(JSONUtils.getString(json, KEY_TYPE));
CauldronContentType<?> type = get(location);
if (type != null) {
return type.read(json);
return read(type, json, CauldronContentType::read);
}
throw new JsonSyntaxException("Invalid cauldron content type '" + location + "'");
}

/**
* Writes the given contents to NBT
* @param contents Contents to write
* @return Contents written to NBT
*/
public static CompoundNBT toNbt(ICauldronContents contents) {
CompoundNBT nbt = new CompoundNBT();
CauldronContentType<?> type = contents.getType();
nbt.putString(KEY_TYPE, getName(type).toString());
type.write(contents, nbt);
return nbt;
}

/**
* Reads the given contents from NBT
* @param nbt NBT contents
Expand All @@ -151,37 +141,24 @@ public static ICauldronContents read(CompoundNBT nbt) {
ResourceLocation location = new ResourceLocation(nbt.getString(KEY_TYPE));
CauldronContentType<?> type = get(location);
if (type != null) {
ICauldronContents contents = type.read(nbt);
if (contents != null) {
return contents;
}
return read(type, nbt, CauldronContentType::read);
}
}
return CauldronContentTypes.DEFAULT.get();
}

/**
* Writes the given contents to NBT
* @param contents Contents to write
* @param buffer Buffer instance
*/
public static void write(ICauldronContents contents, PacketBuffer buffer) {
CauldronContentType<?> type = contents.getType();
buffer.writeResourceLocation(getName(type));
type.write(contents, buffer);
}

/**
* Reads the given contents from NBT
* @param buffer Buffer instance
* @return Cauldron contents
* @throws DecoderException if the type is missing or the data invalids
*/
public static ICauldronContents read(PacketBuffer buffer) {
ResourceLocation name = buffer.readResourceLocation();
CauldronContentType<?> type = get(name);
if (type == null) {
throw new DecoderException("Invalid type name '" + name + "'");
}
return type.read(buffer);
return read(type, buffer, CauldronContentType::read);
}
}
@@ -1,19 +1,18 @@
package knightminer.inspirations.library.recipe.cauldron.contents;

import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonSyntaxException;
import com.google.gson.JsonPrimitive;
import io.netty.handler.codec.DecoderException;
import io.netty.handler.codec.EncoderException;
import knightminer.inspirations.Inspirations;
import knightminer.inspirations.library.recipe.cauldron.CauldronContentTypes;
import knightminer.inspirations.recipes.recipe.cauldron.contents.CauldronContents;
import net.minecraft.client.util.ITooltipFlag;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.network.PacketBuffer;
import net.minecraft.util.JSONUtils;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.text.ITextComponent;
import net.minecraftforge.common.util.Constants.NBT;
import slimeknights.mantle.util.JsonHelper;

import javax.annotation.Nullable;
import java.util.HashMap;
Expand Down Expand Up @@ -142,15 +141,7 @@ public String getModId(T value) {
public abstract String getName(T value);

/**
* Gets the entry for a given value
* @param name Name
* @return Entry, or null if missing
*/
@Nullable
public abstract T getEntry(String name);

/**
* Gets the key used for JSON and NBT
* Gets the base key used for ingredient JSON
* @return JSON and NBT key
*/
public String getKey() {
Expand All @@ -163,77 +154,67 @@ public String getKey() {
* @return Read value
*/
@Nullable
public ICauldronContents read(CompoundNBT tag) {
if (tag.contains(getKey(), NBT.TAG_STRING)) {
T value = getEntry(tag.getString(getKey()));
if (value != null) {
return of(value);
}
}
return null;
}
public abstract T read(CompoundNBT tag);

/**
* Reads the given type from JSON
* @param json JSON object
* @return Read value=
* @throws com.google.gson.JsonSyntaxException if the JSON is invalid
* Writes the given type to NBT
* @param tag NBT tag
*/
public ICauldronContents read(JsonObject json) {
String name = JSONUtils.getString(json, getKey());
T value = getEntry(name);
if (value == null) {
throw new JsonSyntaxException("Invalid name '" + name + "' for type '" + CauldronContentTypes.getName(this) + "'");
}
return of(value);
public void write(T value, CompoundNBT tag) {
tag.putString(getKey(), getName(value));
}

/**
* Reads the given type from the packet buffer
* @param buffer Packet buffer
* @return Read value
* @throws DecoderException if the type is invalid
* Gets the value from a JSON element
* @param element JSON element
* @param key Key to get
* @return Value
*/
public ICauldronContents read(PacketBuffer buffer) {
String name = buffer.readString(Short.MAX_VALUE);
T value = getEntry(name);
if (value != null) {
return of(value);
}
throw new DecoderException("Invalid name '" + name + "' for type " + this);
public abstract T getValue(JsonElement element, String key);

/**
* Writes the given type into a standalone JSON element
* @param value Value to write
* @return JsonElement representing this value
*/
public JsonElement toJson(T value) {
return new JsonPrimitive(getName(value));
}

/**
* Writes the given type to NBT
* @param contents Contents to write
* @param tag NBT tag
* Reads the given type from JSON
* @param json JSON object
* @return Read value
* @throws com.google.gson.JsonSyntaxException if the JSON is invalid
*/
public void write(ICauldronContents contents, CompoundNBT tag) {
contents.get(this).ifPresent(val -> tag.putString(getKey(), getName(val)));
public T read(JsonObject json) {
String key = getKey();
return getValue(JsonHelper.getElement(json, key), key);
}

/**
* Writes the given type to JSON
* @param contents Contents to write
* @param json JSON object
* @param value Value to write
* @param json JSON object
*/
public void write(ICauldronContents contents, JsonObject json) {
contents.get(this).ifPresent(val -> json.addProperty(getKey(), getName(val)));
public void write(T value, JsonObject json) {
json.addProperty(getKey(), getName(value));
}

/**
* Reads the given type from the packet buffer
* @param buffer Packet buffer
* @return Read value
* @throws DecoderException if the type is invalid
*/
public abstract T read(PacketBuffer buffer);

/**
* Writes the given type to the packet buffer
* @param contents Contents to write
* @param value Value to write
* @param buffer Packet buffer
*/
public void write(ICauldronContents contents, PacketBuffer buffer) {
Optional<T> value = contents.get(this);
if (value.isPresent()) {
buffer.writeString(getName(value.get()));
} else {
throw new EncoderException("Invalid type for contents argument");
}
}
public abstract void write(T value, PacketBuffer buffer);

@Override
public String toString() {
Expand Down
@@ -1,8 +1,11 @@
package knightminer.inspirations.library.recipe.cauldron.contents;

import com.google.gson.JsonObject;
import knightminer.inspirations.library.recipe.cauldron.CauldronContentTypes;
import net.minecraft.client.util.ITooltipFlag;
import net.minecraft.fluid.Fluids;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.network.PacketBuffer;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.text.ITextComponent;

Expand Down Expand Up @@ -67,12 +70,33 @@ default String getModId() {
}

/**
* Gets the unique name relative to the ingredient type
* Gets the unique name relative to the ingredient type, for differentiating it in JEI
* @return Resource searching name
*/
String getName();


/* Serializing */

/**
* Writes the given contents to JSON
* @return JSON contents
*/
JsonObject toJson();

/**
* Writes the given contents to NBT
* @return NBT contents
*/
CompoundNBT toNBT();

/**
* Writes the given contents to the packet buffer
* @param buffer Buffer instance
*/
void write(PacketBuffer buffer);


/* Mapping */

/**
Expand Down

0 comments on commit 71baca2

Please sign in to comment.