added registry for ContinuationFrame types!
This commit is contained in:
parent
a1cb9f7fab
commit
4a1e4c3269
12 changed files with 193 additions and 32 deletions
|
@ -3,14 +3,12 @@ package at.petrak.hexcasting.api.casting.eval.vm
|
|||
import at.petrak.hexcasting.api.casting.SpellList
|
||||
import at.petrak.hexcasting.api.casting.eval.CastResult
|
||||
import at.petrak.hexcasting.api.casting.iota.Iota
|
||||
import at.petrak.hexcasting.api.utils.getList
|
||||
import at.petrak.hexcasting.api.utils.hasList
|
||||
import at.petrak.hexcasting.common.lib.hex.HexIotaTypes
|
||||
import at.petrak.hexcasting.common.lib.hex.HexContinuationTypes
|
||||
import net.minecraft.nbt.CompoundTag
|
||||
import net.minecraft.nbt.Tag
|
||||
import net.minecraft.resources.ResourceLocation
|
||||
import net.minecraft.server.level.ServerLevel
|
||||
|
||||
// TODO this should probably be a registry too
|
||||
/**
|
||||
* A single frame of evaluation during the execution of a spell.
|
||||
*
|
||||
|
@ -49,34 +47,62 @@ sealed interface ContinuationFrame {
|
|||
*/
|
||||
fun size(): Int
|
||||
|
||||
val type: Type<*>
|
||||
|
||||
interface Type<U : ContinuationFrame> {
|
||||
fun deserializeFromNBT(tag: CompoundTag, world: ServerLevel): U?
|
||||
}
|
||||
|
||||
companion object {
|
||||
/**
|
||||
* Takes a tag containing the ContinuationFrame.Type resourcelocation and the serialized continuation frame, and returns
|
||||
* the deserialized continuation frame.
|
||||
*/
|
||||
@JvmStatic
|
||||
fun fromNBT(tag: CompoundTag, world: ServerLevel): ContinuationFrame {
|
||||
return when (tag.getString("type")) {
|
||||
"evaluate" -> FrameEvaluate(
|
||||
HexIotaTypes.LIST.deserialize(
|
||||
tag.getList("patterns", Tag.TAG_COMPOUND),
|
||||
world
|
||||
)!!.list,
|
||||
tag.getBoolean("isMetacasting")
|
||||
)
|
||||
val type = getTypeFromTag(tag) ?: return FrameEvaluate(SpellList.LList(0, listOf()), false)
|
||||
|
||||
"end" -> FrameFinishEval
|
||||
"foreach" -> FrameForEach(
|
||||
HexIotaTypes.LIST.deserialize(tag.getList("data", Tag.TAG_COMPOUND), world)!!.list,
|
||||
HexIotaTypes.LIST.deserialize(tag.getList("code", Tag.TAG_COMPOUND), world)!!.list,
|
||||
if (tag.hasList("base", Tag.TAG_COMPOUND))
|
||||
HexIotaTypes.LIST.deserialize(tag.getList("base", Tag.TAG_COMPOUND), world)!!.list.toList()
|
||||
else
|
||||
null,
|
||||
HexIotaTypes.LIST.deserialize(
|
||||
tag.getList("accumulator", Tag.TAG_COMPOUND),
|
||||
world
|
||||
)!!.list.toMutableList()
|
||||
)
|
||||
return (tag.get(HexContinuationTypes.KEY_DATA) as? CompoundTag)?.let { type.deserializeFromNBT(it, world) }
|
||||
?: FrameEvaluate(SpellList.LList(0, listOf()), false)
|
||||
}
|
||||
|
||||
else -> FrameEvaluate(SpellList.LList(0, listOf()), false)
|
||||
/**
|
||||
* Takes a continuation frame and serializes it along with its type.
|
||||
*/
|
||||
@JvmStatic
|
||||
fun toNBT(frame: ContinuationFrame): CompoundTag {
|
||||
val type = frame.type
|
||||
val typeId = HexContinuationTypes.REGISTRY.getKey(type)
|
||||
?: throw IllegalStateException(
|
||||
"Tried to serialize an unregistered continuation type. Continuation: " + frame
|
||||
+ " ; Type" + type.javaClass.typeName)
|
||||
|
||||
val data = frame.serializeToNBT()
|
||||
|
||||
val out = CompoundTag()
|
||||
out.putString(HexContinuationTypes.KEY_TYPE, typeId.toString())
|
||||
out.put(HexContinuationTypes.KEY_DATA, data)
|
||||
return out
|
||||
}
|
||||
|
||||
/**
|
||||
* This method attempts to find the type from the `type` key.
|
||||
* See [ContinuationFrame.serializeToNBT] for the storage format.
|
||||
*
|
||||
* @return `null` if it cannot get the type.
|
||||
*/
|
||||
private fun getTypeFromTag(tag: CompoundTag): Type<*>? {
|
||||
if (!tag.contains(HexContinuationTypes.KEY_TYPE, Tag.TAG_STRING.toInt())) {
|
||||
return null
|
||||
}
|
||||
|
||||
val typeKey = tag.getString(HexContinuationTypes.KEY_TYPE)
|
||||
if (!ResourceLocation.isValidResourceLocation(typeKey)) {
|
||||
return null
|
||||
}
|
||||
|
||||
val typeLoc = ResourceLocation(typeKey)
|
||||
return HexContinuationTypes.REGISTRY[typeLoc]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,8 +6,12 @@ import at.petrak.hexcasting.api.casting.eval.ResolvedPatternType
|
|||
import at.petrak.hexcasting.api.casting.iota.Iota
|
||||
import at.petrak.hexcasting.api.casting.iota.ListIota
|
||||
import at.petrak.hexcasting.api.utils.NBTBuilder
|
||||
import at.petrak.hexcasting.api.utils.getList
|
||||
import at.petrak.hexcasting.api.utils.serializeToNBT
|
||||
import at.petrak.hexcasting.common.lib.hex.HexEvalSounds
|
||||
import at.petrak.hexcasting.common.lib.hex.HexIotaTypes
|
||||
import net.minecraft.nbt.CompoundTag
|
||||
import net.minecraft.nbt.Tag
|
||||
import net.minecraft.server.level.ServerLevel
|
||||
|
||||
/**
|
||||
|
@ -45,10 +49,26 @@ data class FrameEvaluate(val list: SpellList, val isMetacasting: Boolean) : Cont
|
|||
}
|
||||
|
||||
override fun serializeToNBT() = NBTBuilder {
|
||||
"type" %= "evaluate"
|
||||
"patterns" %= list.serializeToNBT()
|
||||
"isMetacasting" %= isMetacasting
|
||||
}
|
||||
|
||||
override fun size() = list.size()
|
||||
|
||||
override val type: ContinuationFrame.Type<*> = TYPE
|
||||
|
||||
companion object {
|
||||
@JvmField
|
||||
val TYPE: ContinuationFrame.Type<FrameEvaluate> = object : ContinuationFrame.Type<FrameEvaluate> {
|
||||
override fun deserializeFromNBT(tag: CompoundTag, world: ServerLevel): FrameEvaluate {
|
||||
return FrameEvaluate(
|
||||
HexIotaTypes.LIST.deserialize(
|
||||
tag.getList("patterns", Tag.TAG_COMPOUND),
|
||||
world
|
||||
)!!.list,
|
||||
tag.getBoolean("isMetacasting"))
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
|
@ -6,6 +6,7 @@ import at.petrak.hexcasting.api.casting.iota.Iota
|
|||
import at.petrak.hexcasting.api.casting.iota.NullIota
|
||||
import at.petrak.hexcasting.api.utils.NBTBuilder
|
||||
import at.petrak.hexcasting.common.lib.hex.HexEvalSounds
|
||||
import net.minecraft.nbt.CompoundTag
|
||||
import net.minecraft.server.level.ServerLevel
|
||||
|
||||
/**
|
||||
|
@ -32,9 +33,14 @@ object FrameFinishEval : ContinuationFrame {
|
|||
)
|
||||
}
|
||||
|
||||
override fun serializeToNBT() = NBTBuilder {
|
||||
"type" %= "end"
|
||||
}
|
||||
override fun serializeToNBT() = CompoundTag()
|
||||
|
||||
override fun size() = 0
|
||||
|
||||
@JvmField
|
||||
val TYPE: ContinuationFrame.Type<FrameFinishEval> = object : ContinuationFrame.Type<FrameFinishEval> {
|
||||
override fun deserializeFromNBT(tag: CompoundTag, world: ServerLevel) = FrameFinishEval
|
||||
}
|
||||
|
||||
override val type = TYPE
|
||||
}
|
||||
|
|
|
@ -6,8 +6,13 @@ import at.petrak.hexcasting.api.casting.eval.ResolvedPatternType
|
|||
import at.petrak.hexcasting.api.casting.iota.Iota
|
||||
import at.petrak.hexcasting.api.casting.iota.ListIota
|
||||
import at.petrak.hexcasting.api.utils.NBTBuilder
|
||||
import at.petrak.hexcasting.api.utils.getList
|
||||
import at.petrak.hexcasting.api.utils.hasList
|
||||
import at.petrak.hexcasting.api.utils.serializeToNBT
|
||||
import at.petrak.hexcasting.common.lib.hex.HexEvalSounds
|
||||
import at.petrak.hexcasting.common.lib.hex.HexIotaTypes
|
||||
import net.minecraft.nbt.CompoundTag
|
||||
import net.minecraft.nbt.Tag
|
||||
import net.minecraft.server.level.ServerLevel
|
||||
|
||||
/**
|
||||
|
@ -76,7 +81,6 @@ data class FrameForEach(
|
|||
}
|
||||
|
||||
override fun serializeToNBT() = NBTBuilder {
|
||||
"type" %= "foreach"
|
||||
"data" %= data.serializeToNBT()
|
||||
"code" %= code.serializeToNBT()
|
||||
if (baseStack != null)
|
||||
|
@ -85,4 +89,27 @@ data class FrameForEach(
|
|||
}
|
||||
|
||||
override fun size() = data.size() + code.size() + acc.size + (baseStack?.size ?: 0)
|
||||
|
||||
override val type: ContinuationFrame.Type<*> = TYPE
|
||||
|
||||
companion object {
|
||||
@JvmField
|
||||
val TYPE: ContinuationFrame.Type<FrameForEach> = object : ContinuationFrame.Type<FrameForEach> {
|
||||
override fun deserializeFromNBT(tag: CompoundTag, world: ServerLevel): FrameForEach {
|
||||
return FrameForEach(
|
||||
HexIotaTypes.LIST.deserialize(tag.getList("data", Tag.TAG_COMPOUND), world)!!.list,
|
||||
HexIotaTypes.LIST.deserialize(tag.getList("code", Tag.TAG_COMPOUND), world)!!.list,
|
||||
if (tag.hasList("base", Tag.TAG_COMPOUND))
|
||||
HexIotaTypes.LIST.deserialize(tag.getList("base", Tag.TAG_COMPOUND), world)!!.list.toList()
|
||||
else
|
||||
null,
|
||||
HexIotaTypes.LIST.deserialize(
|
||||
tag.getList("accumulator", Tag.TAG_COMPOUND),
|
||||
world
|
||||
)!!.list.toMutableList()
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@ sealed interface SpellContinuation {
|
|||
var self = this
|
||||
val frames = mutableListOf<CompoundTag>()
|
||||
while (self is NotDone) {
|
||||
frames.add(self.frame.serializeToNBT())
|
||||
frames.add(ContinuationFrame.toNBT(self.frame))
|
||||
self = self.next
|
||||
}
|
||||
return frames
|
||||
|
|
|
@ -4,6 +4,7 @@ import at.petrak.hexcasting.api.casting.ActionRegistryEntry;
|
|||
import at.petrak.hexcasting.api.casting.arithmetic.Arithmetic;
|
||||
import at.petrak.hexcasting.api.casting.castables.SpecialHandler;
|
||||
import at.petrak.hexcasting.api.casting.eval.sideeffects.EvalSound;
|
||||
import at.petrak.hexcasting.api.casting.eval.vm.ContinuationFrame;
|
||||
import at.petrak.hexcasting.api.casting.iota.IotaType;
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
|
@ -15,5 +16,6 @@ public class HexRegistries {
|
|||
public static final ResourceKey<Registry<SpecialHandler.Factory<?>>> SPECIAL_HANDLER = ResourceKey.createRegistryKey(modLoc("special_handler"));
|
||||
public static final ResourceKey<Registry<IotaType<?>>> IOTA_TYPE = ResourceKey.createRegistryKey(modLoc("iota_type"));
|
||||
public static final ResourceKey<Registry<Arithmetic>> ARITHMETIC = ResourceKey.createRegistryKey(modLoc("arithmetic"));
|
||||
public static final ResourceKey<Registry<ContinuationFrame.Type<?>>> CONTINUATION_TYPE = ResourceKey.createRegistryKey(modLoc("continuation_type"));
|
||||
public static final ResourceKey<Registry<EvalSound>> EVAL_SOUND = ResourceKey.createRegistryKey(modLoc("eval_sound"));
|
||||
}
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
package at.petrak.hexcasting.common.lib.hex;
|
||||
|
||||
import at.petrak.hexcasting.api.HexAPI;
|
||||
import at.petrak.hexcasting.api.casting.eval.vm.ContinuationFrame;
|
||||
import at.petrak.hexcasting.api.casting.eval.vm.FrameEvaluate;
|
||||
import at.petrak.hexcasting.api.casting.eval.vm.FrameFinishEval;
|
||||
import at.petrak.hexcasting.api.casting.eval.vm.FrameForEach;
|
||||
import at.petrak.hexcasting.xplat.IXplatAbstractions;
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
|
||||
import javax.annotation.ParametersAreNonnullByDefault;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.function.BiConsumer;
|
||||
|
||||
import static at.petrak.hexcasting.api.HexAPI.modLoc;
|
||||
|
||||
/**
|
||||
* Stores the registry for continuation frame types, some utility methods, and all the types Hexcasting itself defines.
|
||||
*/
|
||||
@ParametersAreNonnullByDefault
|
||||
public class HexContinuationTypes {
|
||||
public static final Registry<ContinuationFrame.Type<?>> REGISTRY = IXplatAbstractions.INSTANCE.getContinuationTypeRegistry();
|
||||
|
||||
public static final String
|
||||
KEY_TYPE = HexAPI.MOD_ID + ":type",
|
||||
KEY_DATA = HexAPI.MOD_ID + ":data";
|
||||
|
||||
public static void registerContinuations(BiConsumer<ContinuationFrame.Type<?>, ResourceLocation> r) {
|
||||
for (var e : CONTINUATIONS.entrySet()) {
|
||||
r.accept(e.getValue(), e.getKey());
|
||||
}
|
||||
}
|
||||
|
||||
private static final Map<ResourceLocation, ContinuationFrame.Type<?>> CONTINUATIONS = new LinkedHashMap<>();
|
||||
|
||||
public static final ContinuationFrame.Type<FrameEvaluate> EVALUATE = continuation("evaluate", FrameEvaluate.TYPE);
|
||||
public static final ContinuationFrame.Type<FrameForEach> FOREACH = continuation("foreach", FrameForEach.TYPE);
|
||||
public static final ContinuationFrame.Type<FrameFinishEval> END = continuation("end", FrameFinishEval.TYPE);
|
||||
|
||||
private static <U extends ContinuationFrame, T extends ContinuationFrame.Type<U>> T continuation(String name, T continuation) {
|
||||
var old = CONTINUATIONS.put(modLoc(name), continuation);
|
||||
if (old != null) {
|
||||
throw new IllegalArgumentException("Typo? Duplicate id " + name);
|
||||
}
|
||||
return continuation;
|
||||
}
|
||||
}
|
|
@ -12,6 +12,7 @@ import at.petrak.hexcasting.api.casting.eval.ResolvedPattern;
|
|||
import at.petrak.hexcasting.api.casting.eval.sideeffects.EvalSound;
|
||||
import at.petrak.hexcasting.api.casting.eval.vm.CastingImage;
|
||||
import at.petrak.hexcasting.api.casting.eval.vm.CastingVM;
|
||||
import at.petrak.hexcasting.api.casting.eval.vm.ContinuationFrame;
|
||||
import at.petrak.hexcasting.api.casting.iota.IotaType;
|
||||
import at.petrak.hexcasting.api.pigment.ColorProvider;
|
||||
import at.petrak.hexcasting.api.pigment.FrozenPigment;
|
||||
|
@ -175,6 +176,7 @@ public interface IXplatAbstractions {
|
|||
Registry<IotaType<?>> getIotaTypeRegistry();
|
||||
|
||||
Registry<Arithmetic> getArithmeticRegistry();
|
||||
Registry<ContinuationFrame.Type<?>> getContinuationTypeRegistry();
|
||||
|
||||
Registry<EvalSound> getEvalSoundRegistry();
|
||||
|
||||
|
|
|
@ -145,6 +145,7 @@ object FabricHexInitializer : ModInitializer {
|
|||
HexActions.register(bind(IXplatAbstractions.INSTANCE.actionRegistry))
|
||||
HexSpecialHandlers.register(bind(IXplatAbstractions.INSTANCE.specialHandlerRegistry))
|
||||
HexArithmetics.register(bind(IXplatAbstractions.INSTANCE.arithmeticRegistry))
|
||||
HexContinuationTypes.registerContinuations(bind(IXplatAbstractions.INSTANCE.continuationTypeRegistry))
|
||||
HexEvalSounds.register(bind(IXplatAbstractions.INSTANCE.evalSoundRegistry))
|
||||
|
||||
// Because of Java's lazy-loading of classes, can't use Kotlin static initialization for
|
||||
|
|
|
@ -12,6 +12,7 @@ import at.petrak.hexcasting.api.casting.eval.ResolvedPattern;
|
|||
import at.petrak.hexcasting.api.casting.eval.sideeffects.EvalSound;
|
||||
import at.petrak.hexcasting.api.casting.eval.vm.CastingImage;
|
||||
import at.petrak.hexcasting.api.casting.eval.vm.CastingVM;
|
||||
import at.petrak.hexcasting.api.casting.eval.vm.ContinuationFrame;
|
||||
import at.petrak.hexcasting.api.casting.iota.IotaType;
|
||||
import at.petrak.hexcasting.api.mod.HexConfig;
|
||||
import at.petrak.hexcasting.api.mod.HexTags;
|
||||
|
@ -435,6 +436,14 @@ public class FabricXplatImpl implements IXplatAbstractions {
|
|||
Lifecycle.stable()))
|
||||
.buildAndRegister()
|
||||
);
|
||||
|
||||
private static final Supplier<Registry<ContinuationFrame.Type<?>>> CONTINUATION_TYPE_REGISTRY = Suppliers.memoize(() ->
|
||||
FabricRegistryBuilder.from(new DefaultedMappedRegistry<>(
|
||||
HexAPI.MOD_ID + ":end", HexRegistries.CONTINUATION_TYPE,
|
||||
Lifecycle.stable(), false))
|
||||
.buildAndRegister()
|
||||
);
|
||||
|
||||
private static final Supplier<Registry<EvalSound>> EVAL_SOUNDS_REGISTRY = Suppliers.memoize(() ->
|
||||
FabricRegistryBuilder.from(new DefaultedMappedRegistry<>(
|
||||
HexAPI.MOD_ID + ":nothing", HexRegistries.EVAL_SOUND,
|
||||
|
@ -462,6 +471,11 @@ public class FabricXplatImpl implements IXplatAbstractions {
|
|||
return ARITHMETIC_REGISTRY.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Registry<ContinuationFrame.Type<?>> getContinuationTypeRegistry() {
|
||||
return CONTINUATION_TYPE_REGISTRY.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Registry<EvalSound> getEvalSoundRegistry() {
|
||||
return EVAL_SOUNDS_REGISTRY.get();
|
||||
|
|
|
@ -106,6 +106,7 @@ public class ForgeHexInitializer {
|
|||
IXplatAbstractions.INSTANCE.getSpecialHandlerRegistry();
|
||||
IXplatAbstractions.INSTANCE.getIotaTypeRegistry();
|
||||
IXplatAbstractions.INSTANCE.getArithmeticRegistry();
|
||||
IXplatAbstractions.INSTANCE.getContinuationTypeRegistry();
|
||||
IXplatAbstractions.INSTANCE.getEvalSoundRegistry();
|
||||
|
||||
rootRegistry.freeze();
|
||||
|
@ -138,6 +139,7 @@ public class ForgeHexInitializer {
|
|||
bind(HexRegistries.ACTION, HexActions::register);
|
||||
bind(HexRegistries.SPECIAL_HANDLER, HexSpecialHandlers::register);
|
||||
bind(HexRegistries.ARITHMETIC, HexArithmetics::register);
|
||||
bind(HexRegistries.CONTINUATION_TYPE, HexContinuationTypes::registerContinuations);
|
||||
bind(HexRegistries.EVAL_SOUND, HexEvalSounds::register);
|
||||
|
||||
ForgeHexArgumentTypeRegistry.ARGUMENT_TYPES.register(getModEventBus());
|
||||
|
|
|
@ -12,6 +12,7 @@ import at.petrak.hexcasting.api.casting.eval.env.StaffCastEnv;
|
|||
import at.petrak.hexcasting.api.casting.eval.sideeffects.EvalSound;
|
||||
import at.petrak.hexcasting.api.casting.eval.vm.CastingImage;
|
||||
import at.petrak.hexcasting.api.casting.eval.vm.CastingVM;
|
||||
import at.petrak.hexcasting.api.casting.eval.vm.ContinuationFrame;
|
||||
import at.petrak.hexcasting.api.casting.iota.IotaType;
|
||||
import at.petrak.hexcasting.api.mod.HexTags;
|
||||
import at.petrak.hexcasting.api.pigment.ColorProvider;
|
||||
|
@ -21,6 +22,7 @@ import at.petrak.hexcasting.api.player.FlightAbility;
|
|||
import at.petrak.hexcasting.api.player.Sentinel;
|
||||
import at.petrak.hexcasting.api.utils.HexUtils;
|
||||
import at.petrak.hexcasting.common.lib.HexRegistries;
|
||||
import at.petrak.hexcasting.common.lib.hex.HexContinuationTypes;
|
||||
import at.petrak.hexcasting.common.lib.hex.HexEvalSounds;
|
||||
import at.petrak.hexcasting.common.lib.hex.HexIotaTypes;
|
||||
import at.petrak.hexcasting.common.msgs.IMessage;
|
||||
|
@ -479,6 +481,11 @@ public class ForgeXplatImpl implements IXplatAbstractions {
|
|||
ForgeAccessorBuiltInRegistries.hex$registerSimple(
|
||||
HexRegistries.ARITHMETIC, null)
|
||||
);
|
||||
private static final Supplier<Registry<ContinuationFrame.Type<?>>> CONTINUATION_TYPE_REGISTRY = Suppliers.memoize(() ->
|
||||
ForgeAccessorBuiltInRegistries.hex$registerDefaulted(
|
||||
HexRegistries.CONTINUATION_TYPE,
|
||||
modLoc("end").toString(), registry -> HexContinuationTypes.END)
|
||||
);
|
||||
private static final Supplier<Registry<EvalSound>> EVAL_SOUND_REGISTRY = Suppliers.memoize(() ->
|
||||
ForgeAccessorBuiltInRegistries.hex$registerDefaulted(
|
||||
HexRegistries.EVAL_SOUND,
|
||||
|
@ -505,6 +512,11 @@ public class ForgeXplatImpl implements IXplatAbstractions {
|
|||
return ARITHMETIC_REGISTRY.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Registry<ContinuationFrame.Type<?>> getContinuationTypeRegistry() {
|
||||
return CONTINUATION_TYPE_REGISTRY.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Registry<EvalSound> getEvalSoundRegistry() {
|
||||
return EVAL_SOUND_REGISTRY.get();
|
||||
|
|
Loading…
Reference in a new issue