Made ContinuationIotas not serialise if they're too big.

This commit is contained in:
Talia-12 2023-06-02 22:47:30 +10:00
parent 5d90b58219
commit 9b13e218ba
7 changed files with 38 additions and 4 deletions

View file

@ -44,6 +44,11 @@ sealed interface ContinuationFrame {
*/
fun serializeToNBT(): CompoundTag
/**
* Return the number of iotas contained inside this frame, used for determining whether it is valid to serialise.
*/
fun size(): Int
companion object {
@JvmStatic
fun fromNBT(tag: CompoundTag, world: ServerLevel): ContinuationFrame {

View file

@ -48,4 +48,6 @@ data class FrameEvaluate(val list: SpellList, val isMetacasting: Boolean) : Cont
"patterns" %= list.serializeToNBT()
"isMetacasting" %= isMetacasting
}
override fun size() = list.size()
}

View file

@ -33,4 +33,6 @@ object FrameFinishEval : ContinuationFrame {
override fun serializeToNBT() = NBTBuilder {
"type" %= "end"
}
override fun size() = 0
}

View file

@ -84,4 +84,6 @@ data class FrameForEach(
"base" %= baseStack.serializeToNBT()
"accumulator" %= acc.serializeToNBT()
}
override fun size() = data.size() + code.size() + acc.size + (baseStack?.size ?: 0)
}

View file

@ -13,7 +13,6 @@ import net.minecraft.nbt.Tag;
import net.minecraft.network.chat.Component;
import net.minecraft.server.level.ServerLevel;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.List;
@ -57,6 +56,19 @@ public class ContinuationIota extends Iota {
return true;
}
@Override
public int size() {
var continuation = this.getContinuation();
var size = 0;
while (continuation instanceof SpellContinuation.NotDone notDone) {
size += 1;
size += notDone.component1().size();
continuation = notDone.component2();
}
return Math.min(size, 1);
}
public static IotaType<ContinuationIota> TYPE = new IotaType<>() {
@Override
public @NotNull ContinuationIota deserialize(Tag tag, ServerLevel world) throws IllegalArgumentException {

View file

@ -78,13 +78,24 @@ public abstract class Iota {
* This method is called to determine whether the iota is above the max serialisation depth/serialisation count
* limits. It should return every "iota" that is a subelement of this iota.
* For example, if you implemented a Map&lt;Iota, Iota&gt;, then it should be an iterable over the keys *and*
* values of the map. If you implemented a typed List&lt;Double&gt; iota for some reason, it would
* probably be a good idea to supply an iterable over those doubles mapped to double iotas.
* values of the map. If you implemented a typed List&lt;Double&gt; iota for some reason, you should instad override
* {@link Iota#size}.
*/
public @Nullable Iterable<Iota> subIotas() {
return null;
}
/**
* This method is called to determine whether the iota is above the max serialisation depth/serialisation count limits.
* This is an alternative to deriving subIotas for if your Iota is a datastructure of variable size over something that
* doesn't make sense to convert to an Iota iterable, such as {@link ContinuationIota}, or a typed List&lt;Double&gt;.
* It should return "1" per "iota sized" unit of memory that it would occupy. Easy option, return the element count of
* your data structure.
*/
public int size() {
return 1;
}
public Component display() {
return this.type.display(this.serialize());
}

View file

@ -87,7 +87,7 @@ public abstract class IotaType<T extends Iota> {
var sublist = iotaPair.getFirst();
int depth = iotaPair.getSecond();
for (var iota : sublist) {
totalEltsFound++;
totalEltsFound += iota.size();
if (totalEltsFound >= HexIotaTypes.MAX_SERIALIZATION_TOTAL) {
return true; // too bad
}