Skip to content

Commit

Permalink
Add a registryLookup parameter to all serialization methods
Browse files Browse the repository at this point in the history
  • Loading branch information
Pyrofab committed Apr 26, 2024
1 parent ad07bdf commit ae19174
Show file tree
Hide file tree
Showing 35 changed files with 226 additions and 146 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@

import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NbtCompound;
import net.minecraft.registry.RegistryWrapper;
import org.jetbrains.annotations.Contract;

/**
Expand All @@ -40,21 +41,23 @@ public interface Component {
/**
* Reads this component's properties from a {@link NbtCompound}.
*
* @param tag a {@code NbtCompound} on which this component's serializable data has been written
* @param tag a {@code NbtCompound} on which this component's serializable data has been written
* @param registryLookup access to dynamic registry data
* @implNote implementations should not assert that the data written on the tag corresponds to any
* specific scheme, as saved data is susceptible to external tempering, and may come from an earlier
* version.
*/
@Contract(mutates = "this")
void readFromNbt(NbtCompound tag);
void readFromNbt(NbtCompound tag, RegistryWrapper.WrapperLookup registryLookup);

/**
* Writes this component's properties to a {@link NbtCompound}.
*
* @param tag a {@code NbtCompound} on which to write this component's serializable data
* @param tag a {@code NbtCompound} on which to write this component's serializable data
* @param registryLookup access to dynamic registry data
*/
@Contract(mutates = "param")
void writeToNbt(NbtCompound tag);
@Contract(mutates = "param1")
void writeToNbt(NbtCompound tag, RegistryWrapper.WrapperLookup registryLookup);

/**
* Indicates whether some other object is "equal to" this component.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import com.demonwav.mcdev.annotations.CheckEnv;
import com.demonwav.mcdev.annotations.Env;
import net.minecraft.nbt.NbtCompound;
import net.minecraft.registry.RegistryWrapper;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.Nullable;
Expand Down Expand Up @@ -60,7 +61,7 @@ public interface ComponentContainer extends NbtSerializable {
boolean hasComponents();

@Contract(mutates = "this")
void copyFrom(ComponentContainer other);
void copyFrom(ComponentContainer other, RegistryWrapper.WrapperLookup registryLookup);

@AsmGeneratedCallback(ServerTickingComponent.class)
void tickServerComponents();
Expand Down Expand Up @@ -110,23 +111,25 @@ default ComponentKey<?> getKey(Component component) {
/**
* Reads this object's properties from a {@link NbtCompound}.
*
* @param tag a {@code NbtCompound} on which this object's serializable data has been written
* @param tag a {@code NbtCompound} on which this object's serializable data has been written
* @param registryLookup access to dynamic registry data
* @implNote implementations must not assert that the data written on the tag corresponds to any
* specific scheme, as saved data is susceptible to external tempering, and may come from an earlier
* version. They should also store values into {@code tag} using only unique namespaced keys, as other
* information may be stored in said tag.
*/
@Contract(mutates = "this")
void fromTag(NbtCompound tag);
void fromTag(NbtCompound tag, RegistryWrapper.WrapperLookup registryLookup);

/**
* Writes this object's properties to a {@link NbtCompound}.
*
* @param tag a {@code NbtCompound} on which to write this component's serializable data
* @param tag a {@code NbtCompound} on which to write this component's serializable data
* @param registryLookup access to dynamic registry data
* @return {@code tag} for easy chaining
*/
@Contract(mutates = "param")
NbtCompound toTag(NbtCompound tag);
NbtCompound toTag(NbtCompound tag, RegistryWrapper.WrapperLookup registryLookup);

/**
* A factory for {@link ComponentContainer}s.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
package org.ladysnake.cca.api.v3.component;

import net.minecraft.nbt.NbtCompound;
import net.minecraft.registry.RegistryWrapper;

/**
* A component that can copy its data from another component of the same type.
Expand All @@ -34,12 +35,12 @@ public interface CopyableComponent<C extends Component> extends Component {
/**
* Copies the data from {@code other} into {@code this}.
*
* @implSpec The default implementation {@linkplain #writeToNbt(NbtCompound) serializes}
* the component data to a {@link NbtCompound} and calls {@link #readFromNbt(NbtCompound)}.
* @implSpec The default implementation {@linkplain Component#writeToNbt(NbtCompound, RegistryWrapper.WrapperLookup) serializes}
* the component data to a {@link NbtCompound} and calls {@link Component#readFromNbt(NbtCompound, RegistryWrapper.WrapperLookup)}.
* @implNote The default implementation should generally be overridden.
* The serialization done by the default implementation assumes NBT consistency
* between implementations, and is generally slower than a direct copy.
* Implementing classes can nearly always provide a better implementation.
*/
void copyFrom(C other);
void copyFrom(C other, RegistryWrapper.WrapperLookup registryLookup);
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,19 +23,20 @@
package org.ladysnake.cca.api.v3.component;

import net.minecraft.nbt.NbtCompound;
import net.minecraft.registry.RegistryWrapper;
import org.jetbrains.annotations.Nullable;

/**
* Utility interface for components that do not hold any data
*/
public interface TransientComponent extends Component {
@Override
default void readFromNbt(NbtCompound tag) {
default void readFromNbt(NbtCompound tag, RegistryWrapper.WrapperLookup registryLookup) {
// Nothing to read
}

@Override
default void writeToNbt(NbtCompound tag) {
default void writeToNbt(NbtCompound tag, RegistryWrapper.WrapperLookup registryLookup) {
// Nothing to write
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import net.minecraft.entity.Entity;
import net.minecraft.nbt.NbtCompound;
import net.minecraft.network.RegistryByteBuf;
import net.minecraft.registry.RegistryWrapper.WrapperLookup;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.world.World;
import org.jetbrains.annotations.Contract;
Expand Down Expand Up @@ -67,7 +68,7 @@ default boolean shouldSyncWith(ServerPlayerEntity player) {
* @param buf the buffer to write the data to
* @param recipient the player to which the packet will be sent
* @implSpec The default implementation writes the whole NBT representation
* of this component to the buffer using {@link #writeToNbt(NbtCompound)}.
* of this component to the buffer using {@link Component#writeToNbt(NbtCompound, WrapperLookup)}.
* @implNote The default implementation should generally be overridden.
* The serialization done by the default implementation sends possibly hidden
* information to clients, uses a wasteful data format, and does not support
Expand All @@ -81,15 +82,15 @@ default boolean shouldSyncWith(ServerPlayerEntity player) {
@Override
default void writeSyncPacket(RegistryByteBuf buf, ServerPlayerEntity recipient) {
NbtCompound tag = new NbtCompound();
this.writeToNbt(tag);
this.writeToNbt(tag, buf.getRegistryManager());
buf.writeNbt(tag);
}

/**
* Reads this component's data from {@code buf}.
*
* @implSpec The default implementation converts the buffer's content
* to a {@link NbtCompound} and calls {@link #readFromNbt(NbtCompound)}.
* to a {@link NbtCompound} and calls {@link Component#readFromNbt(NbtCompound, WrapperLookup)}.
* @implNote any implementing class overriding {@link #writeSyncPacket(RegistryByteBuf, ServerPlayerEntity)}
* such that it uses a different data format must override this method.
* @see #writeSyncPacket(RegistryByteBuf, ServerPlayerEntity)
Expand All @@ -98,7 +99,7 @@ default void writeSyncPacket(RegistryByteBuf buf, ServerPlayerEntity recipient)
default void applySyncPacket(RegistryByteBuf buf) {
NbtCompound tag = buf.readNbt();
if (tag != null) {
this.readFromNbt(tag);
this.readFromNbt(tag, buf.getRegistryManager());
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import com.mojang.serialization.Dynamic;
import net.minecraft.nbt.NbtCompound;
import net.minecraft.nbt.NbtOps;
import net.minecraft.registry.RegistryWrapper;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.Contract;

Expand All @@ -33,31 +34,33 @@ public interface NbtSerializable {
/**
* Reads this object's properties from a {@link NbtCompound}.
*
* @param tag a {@code NbtCompound} on which this object's serializable data has been written
* @param tag a {@code NbtCompound} on which this object's serializable data has been written
* @param registryLookup access to dynamic registry data
* @implNote implementations must not assert that the data written on the tag corresponds to any
* specific scheme, as saved data is susceptible to external tempering, and may come from an earlier
* version. They should also store values into {@code tag} using only unique namespaced keys, as other
* information may be stored in said tag.
*/
@Contract(mutates = "this")
void fromTag(NbtCompound tag);
void fromTag(NbtCompound tag, RegistryWrapper.WrapperLookup registryLookup);

/**
* Writes this object's properties to a {@link NbtCompound}.
*
* @param tag a {@code NbtCompound} on which to write this component's serializable data
* @param tag a {@code NbtCompound} on which to write this component's serializable data
* @param registryLookup access to dynamic registry data
* @return {@code tag} for easy chaining
*/
@Contract(mutates = "param")
NbtCompound toTag(NbtCompound tag);
NbtCompound toTag(NbtCompound tag, RegistryWrapper.WrapperLookup registryLookup);

@Contract(mutates = "this")
default void fromDynamic(Dynamic<?> dynamic) {
this.fromTag((NbtCompound) dynamic.convert(NbtOps.INSTANCE).getValue());
default void fromDynamic(Dynamic<?> dynamic, RegistryWrapper.WrapperLookup registryLookup) {
this.fromTag((NbtCompound) dynamic.convert(NbtOps.INSTANCE).getValue(), registryLookup);
}

@Contract(pure = true)
default <T> Dynamic<T> toDynamic(Dynamic<T> dynamic) {
return dynamic.convert(NbtOps.INSTANCE).map(tag -> this.toTag((NbtCompound)tag)).convert(dynamic.getOps());
default <T> Dynamic<T> toDynamic(Dynamic<T> dynamic, RegistryWrapper.WrapperLookup wrapperLookup) {
return dynamic.convert(NbtOps.INSTANCE).map(tag -> this.toTag((NbtCompound)tag, wrapperLookup)).convert(dynamic.getOps());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import net.fabricmc.fabric.api.util.NbtType;
import net.minecraft.nbt.NbtCompound;
import net.minecraft.nbt.NbtList;
import net.minecraft.registry.RegistryWrapper;
import net.minecraft.util.Identifier;
import org.ladysnake.cca.api.v3.component.Component;
import org.ladysnake.cca.api.v3.component.ComponentContainer;
Expand All @@ -42,20 +43,20 @@ public abstract class AbstractComponentContainer implements ComponentContainer {
public static final String NBT_KEY = "cardinal_components";

@Override
public void copyFrom(ComponentContainer other) {
public void copyFrom(ComponentContainer other, RegistryWrapper.WrapperLookup registryLookup) {
for (ComponentKey<?> key : this.keys()) {
Component theirs = key.getInternal(other);
Component ours = key.getInternal(this);
assert ours != null;

if (theirs != null && !ours.equals(theirs)) {
if (ours instanceof CopyableComponent) {
if (ours instanceof CopyableComponent<?>) {
@SuppressWarnings("unchecked") CopyableComponent<Component> copyable = (CopyableComponent<Component>) ours;
copyable.copyFrom(theirs);
copyable.copyFrom(theirs, registryLookup);
} else {
NbtCompound tag = new NbtCompound();
theirs.writeToNbt(tag);
ours.readFromNbt(tag);
theirs.writeToNbt(tag, registryLookup);
ours.readFromNbt(tag, registryLookup);
}
}
}
Expand All @@ -72,7 +73,7 @@ public void copyFrom(ComponentContainer other) {
* type, the component tag is skipped.
*/
@Override
public void fromTag(NbtCompound tag) {
public void fromTag(NbtCompound tag, RegistryWrapper.WrapperLookup registryLookup) {
if(tag.contains(NBT_KEY, NbtType.LIST)) {
NbtList componentList = tag.getList(NBT_KEY, NbtType.COMPOUND);
for (int i = 0; i < componentList.size(); i++) {
Expand All @@ -81,7 +82,7 @@ public void fromTag(NbtCompound tag) {
if (type != null) {
Component component = type.getInternal(this);
if (component != null) {
component.readFromNbt(nbt);
component.readFromNbt(nbt, registryLookup);
}
}
}
Expand All @@ -94,7 +95,7 @@ public void fromTag(NbtCompound tag) {
if (componentMap.contains(keyId, NbtType.COMPOUND)) {
Component component = key.getInternal(this);
assert component != null;
component.readFromNbt(componentMap.getCompound(keyId));
component.readFromNbt(componentMap.getCompound(keyId), registryLookup);
componentMap.remove(keyId);
}
}
Expand All @@ -109,19 +110,19 @@ public void fromTag(NbtCompound tag) {
* @implSpec This implementation first checks if the container is empty; if so it
* returns immediately. Then, it iterates over this container's mappings, and creates
* a compound tag for each component. The tag is then passed to the component's
* {@link Component#writeToNbt(NbtCompound)} method. Every such serialized component is appended
* {@link Component#writeToNbt(NbtCompound, RegistryWrapper.WrapperLookup)} method. Every such serialized component is appended
* to a {@code NbtCompound}, using the component type's identifier as the key.
* The serialized map is finally appended to the passed in tag using the "cardinal_components" key.
*/
@Override
public NbtCompound toTag(NbtCompound tag) {
public NbtCompound toTag(NbtCompound tag, RegistryWrapper.WrapperLookup registryLookup) {
if(this.hasComponents()) {
NbtCompound componentMap = null;
NbtCompound componentTag = new NbtCompound();

for (ComponentKey<?> type : this.keys()) {
Component component = type.getFromContainer(this);
component.writeToNbt(componentTag);
component.writeToNbt(componentTag, registryLookup);

if (!componentTag.isEmpty()) {
if (componentMap == null) {
Expand Down
8 changes: 8 additions & 0 deletions cardinal-components-base/src/main/resources/fabric.mod.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,14 @@
"minecraft": ">=1.17-",
"fabric-api-base": ">=0.1.2"
},
"breaks": {
"cardinal-components-block": "<6.0.0-beta.2",
"cardinal-components-chunk": "<6.0.0-beta.2",
"cardinal-components-entity": "<6.0.0-beta.2",
"cardinal-components-level": "<6.0.0-beta.2",
"cardinal-components-scoreboard": "<6.0.0-beta.2",
"cardinal-components-world": "<6.0.0-beta.2"
},
"authors": [
{
"name": "UpcraftLP",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@

import net.fabricmc.fabric.api.gametest.v1.FabricGameTest;
import net.minecraft.nbt.NbtCompound;
import net.minecraft.registry.RegistryWrapper;
import net.minecraft.test.GameTest;
import net.minecraft.util.Identifier;
import org.junit.Assert;
Expand Down Expand Up @@ -64,10 +65,10 @@ interface TestNotComponentItf {}

public static class TestComponentNotItf implements Component {
@Override
public void readFromNbt(NbtCompound tag) { }
public void readFromNbt(NbtCompound tag, RegistryWrapper.WrapperLookup registryLookup) { }

@Override
public void writeToNbt(NbtCompound tag) { throw new UnsupportedOperationException(); }
public void writeToNbt(NbtCompound tag, RegistryWrapper.WrapperLookup registryLookup) { throw new UnsupportedOperationException(); }
}

interface TestComponentItf extends Component {}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
package org.ladysnake.cca.test.base;

import net.minecraft.nbt.NbtCompound;
import net.minecraft.registry.RegistryWrapper;
import org.ladysnake.cca.api.v3.component.Component;
import org.ladysnake.cca.api.v3.component.CopyableComponent;

Expand All @@ -48,17 +49,17 @@ public void setVitality(int value) {
}

@Override
public void readFromNbt(NbtCompound tag) {
public void readFromNbt(NbtCompound tag, RegistryWrapper.WrapperLookup registryLookup) {
this.vitality = tag.getInt("vitality");
}

@Override
public void writeToNbt(NbtCompound tag) {
public void writeToNbt(NbtCompound tag, RegistryWrapper.WrapperLookup registryLookup) {
tag.putInt("vitality", this.vitality);
}

@Override
public void copyFrom(BaseVita other) {
public void copyFrom(BaseVita other, RegistryWrapper.WrapperLookup registryLookup) {
this.vitality = other.getVitality();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
package org.ladysnake.cca.test.base;

import net.minecraft.nbt.NbtCompound;
import net.minecraft.registry.RegistryWrapper;
import net.minecraft.util.Identifier;
import org.ladysnake.cca.api.v3.component.ComponentKey;
import org.ladysnake.cca.api.v3.component.ComponentRegistry;
Expand All @@ -36,13 +37,13 @@ public class TickingTestComponent implements ServerTickingComponent, ClientTicki
private int serverTicks;

@Override
public void readFromNbt(NbtCompound tag) {
public void readFromNbt(NbtCompound tag, RegistryWrapper.WrapperLookup registryLookup) {
this.clientTicks = tag.getInt("clientTicks");
this.serverTicks = tag.getInt("serverTicks");
}

@Override
public void writeToNbt(NbtCompound tag) {
public void writeToNbt(NbtCompound tag, RegistryWrapper.WrapperLookup registryLookup) {
tag.putInt("clientTicks", this.clientTicks);
tag.putInt("serverTicks", this.serverTicks);
}
Expand Down
Loading

0 comments on commit ae19174

Please sign in to comment.