Skip to content

Commit

Permalink
Switch to a proper HAMT impl for map fragments
Browse files Browse the repository at this point in the history
  • Loading branch information
enjarai committed Nov 13, 2024
1 parent f4c0394 commit 7a5494d
Show file tree
Hide file tree
Showing 21 changed files with 71 additions and 561 deletions.
2 changes: 2 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,8 @@ dependencies {
// implementation "io.wispforest:endec:0.1.0-pre.8"
include modLocalRuntime("io.wispforest.lavender-md:owo-ui:0.1.2+1.21")

include clientImplementation(implementation("io.vavr:vavr:0.10.5"))

modApi("nl.enjarai:cicada-lib:${property('deps.cicada')}")

include modApi("org.ladysnake.cardinal-components-api:cardinal-components-base:${property('deps.cardinal-components-api')}")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
import dev.enjarai.trickster.spell.fragment.ListFragment;
import dev.enjarai.trickster.spell.fragment.NumberFragment;
import dev.enjarai.trickster.spell.fragment.MapFragment;
import dev.enjarai.trickster.util.Hamt;
import dev.enjarai.trickster.spell.trick.Tricks;

import java.util.*;
Expand Down Expand Up @@ -33,7 +32,7 @@ public class Revisions {

public static final Revision ONE_PONY_TRICK = register(new ConstantRevision(Tricks.TWO.getPattern(), new NumberFragment(2)));
public static final Revision EMPTY_LIST = register(new ConstantRevision(Tricks.LIST_CREATE.getPattern(), new ListFragment(List.of())));
public static final Revision EMPTY_MAP = register(new ConstantRevision(Pattern.of(2, 5, 8, 6, 3, 0), new MapFragment(Hamt.empty())));
public static final Revision EMPTY_MAP = register(new ConstantRevision(Pattern.of(2, 5, 8, 6, 3, 0), new MapFragment(io.vavr.collection.HashMap.empty())));

public static Optional<Revision> lookup(Pattern pattern) {
return Optional.ofNullable(REGISTRY.get(pattern));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,9 @@
import dev.enjarai.trickster.ModSounds;
import dev.enjarai.trickster.Trickster;
import dev.enjarai.trickster.render.SpellCircleRenderer;
import dev.enjarai.trickster.revision.Revision;
import dev.enjarai.trickster.revision.RevisionContext;
import dev.enjarai.trickster.revision.Revisions;
import dev.enjarai.trickster.spell.*;
import dev.enjarai.trickster.util.Hamt;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.*;
import net.minecraft.client.gui.screen.narration.NarrationMessageBuilder;
Expand Down Expand Up @@ -427,7 +425,7 @@ protected void stopDrawing() {

spellPart = result;
}
} else if (revisionContext.getMacros().get(compiled).isPresent()) {
} else if (revisionContext.getMacros().get(compiled).isDefined()) {
toBeReplaced = drawingPart;
revisionContext.updateSpellWithSpell(drawingPart, revisionContext.getMacros().get(compiled).get());
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import dev.enjarai.trickster.revision.RevisionContext;
import dev.enjarai.trickster.screen.SpellPartWidget;
import dev.enjarai.trickster.spell.SpellPart;
import dev.enjarai.trickster.util.Hamt;
import io.vavr.collection.HashMap;
import io.wispforest.owo.ui.base.BaseComponent;
import io.wispforest.owo.ui.component.ButtonComponent;
import io.wispforest.owo.ui.core.OwoUIDrawContext;
Expand Down Expand Up @@ -53,8 +53,8 @@ public void executeOffhand() {
}

@Override
public Hamt<Pattern, SpellPart> getMacros() {
return Hamt.empty();
public HashMap<Pattern, SpellPart> getMacros() {
return HashMap.empty();
}
}, false);
this.wrapped.setMutable(false);
Expand Down
5 changes: 5 additions & 0 deletions src/main/java/dev/enjarai/trickster/EndecTomfoolery.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import com.mojang.datafixers.util.Function3;
import com.mojang.serialization.Codec;
import com.mojang.util.UndashedUuid;
import io.vavr.collection.HashMap;
import io.wispforest.endec.*;
import io.wispforest.endec.impl.StructEndecBuilder;
import io.wispforest.owo.serialization.CodecUtils;
Expand Down Expand Up @@ -185,4 +186,8 @@ public T decodeStruct(SerializationContext ctx, Deserializer<?> deserializer, De
return wrapped.get().decodeStruct(ctx, deserializer, struct);
}
}

public static <K, V> Endec<HashMap<K, V>> hamt(Endec<K> key, Endec<V> value) {
return Endec.map(key, value).xmap(HashMap::ofAll, HashMap::toJavaMap);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import dev.enjarai.trickster.item.component.FragmentComponent;
import dev.enjarai.trickster.screen.ScrollAndQuillScreenHandler;
import dev.enjarai.trickster.spell.SpellPart;
import dev.enjarai.trickster.util.Hamt;
import io.vavr.collection.HashMap;
import net.minecraft.entity.EquipmentSlot;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.player.PlayerInventory;
Expand All @@ -26,7 +26,7 @@ public EvaluationMirrorItem(Settings settings) {
public TypedActionResult<ItemStack> use(World world, PlayerEntity user, Hand hand) {
var stack = user.getStackInHand(hand);
var otherStack = user.getStackInHand(hand == Hand.MAIN_HAND ? Hand.OFF_HAND : Hand.MAIN_HAND);
var macros = FragmentComponent.getUserMergedMap(user, "ring", Hamt::empty);
var macros = FragmentComponent.getUserMergedMap(user, "ring", HashMap::empty);

if (!user.isSneaking()) {
user.openHandledScreen(new NamedScreenHandlerFactory() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import dev.enjarai.trickster.item.component.FragmentComponent;
import dev.enjarai.trickster.item.component.ModComponents;
import dev.enjarai.trickster.screen.ScrollAndQuillScreenHandler;
import dev.enjarai.trickster.util.Hamt;
import io.vavr.collection.HashMap;
import net.minecraft.entity.EquipmentSlot;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.player.PlayerInventory;
Expand Down Expand Up @@ -34,7 +34,7 @@ public TypedActionResult<ItemStack> use(World world, PlayerEntity user, Hand han
var stack = user.getStackInHand(hand);
var otherStack = user.getStackInHand(hand == Hand.MAIN_HAND ? Hand.OFF_HAND : Hand.MAIN_HAND);
var slot = hand == Hand.MAIN_HAND ? EquipmentSlot.MAINHAND : EquipmentSlot.OFFHAND;
var mergedMap = FragmentComponent.getUserMergedMap(user, "ring", Hamt::empty);
var mergedMap = FragmentComponent.getUserMergedMap(user, "ring", HashMap::empty);

var spell = stack.get(ModComponents.FRAGMENT);
if (spell == null || spell.closed()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
import dev.enjarai.trickster.screen.ScrollAndQuillScreenHandler;
import dev.enjarai.trickster.spell.SpellPart;
import dev.enjarai.trickster.spell.execution.SpellQueueResult;
import dev.enjarai.trickster.util.Hamt;
import dev.enjarai.trickster.spell.mana.SimpleManaPool;
import io.vavr.collection.HashMap;
import net.minecraft.entity.EquipmentSlot;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.player.PlayerInventory;
Expand Down Expand Up @@ -60,7 +60,7 @@ public Text getDisplayName() {
public ScreenHandler createMenu(int syncId, PlayerInventory playerInventory, PlayerEntity player) {
return new ScrollAndQuillScreenHandler(
syncId, playerInventory, stack, otherStack, slot,
Hamt.empty(),
HashMap.empty(),
false, false
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import dev.enjarai.trickster.spell.Pattern;
import dev.enjarai.trickster.spell.SpellPart;
import dev.enjarai.trickster.spell.fragment.MapFragment;
import dev.enjarai.trickster.util.Hamt;
import io.vavr.collection.HashMap;
import io.wispforest.endec.Endec;
import io.wispforest.endec.impl.StructEndecBuilder;
import net.minecraft.component.DataComponentTypes;
Expand Down Expand Up @@ -118,12 +118,12 @@ public static <T extends Fragment> Optional<T> getValue(ItemStack stack, Class<T
});
}

public static Optional<Hamt<Pattern, SpellPart>> getMap(ItemStack stack) {
public static Optional<HashMap<Pattern, SpellPart>> getMap(ItemStack stack) {
return getValue(stack, MapFragment.class)
.flatMap(MapFragment::getMacroMap);
.map(MapFragment::getMacroMap);
}

public static Optional<Hamt<Pattern, SpellPart>> getUserMergedMap(PlayerEntity user, String type) {
public static Optional<HashMap<Pattern, SpellPart>> getUserMergedMap(PlayerEntity user, String type) {
var capability = user.accessoriesCapability();

if (capability == null)
Expand All @@ -134,16 +134,16 @@ public static Optional<Hamt<Pattern, SpellPart>> getUserMergedMap(PlayerEntity u
if (ringContainer == null)
return Optional.empty();

var result = Hamt.<Pattern, SpellPart>empty();
var result = HashMap.<Pattern, SpellPart>empty();

for (var pair : ringContainer.getAccessories()) {
result = result.assocAll(getMap(pair.getSecond()).orElse(Hamt.empty()));
result = result.merge(getMap(pair.getSecond()).orElse(HashMap.empty()));
}

return Optional.of(result);
}

public static Hamt<Pattern, SpellPart> getUserMergedMap(PlayerEntity user, String type, Supplier<Hamt<Pattern, SpellPart>> otherwise) {
public static HashMap<Pattern, SpellPart> getUserMergedMap(PlayerEntity user, String type, Supplier<HashMap<Pattern, SpellPart>> otherwise) {
return getUserMergedMap(user, type).orElseGet(otherwise);
}
}
4 changes: 2 additions & 2 deletions src/main/java/dev/enjarai/trickster/net/SpellEditPacket.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@

import dev.enjarai.trickster.item.ModItems;
import dev.enjarai.trickster.screen.ScrollAndQuillScreenHandler;
import io.vavr.collection.HashMap;
import io.wispforest.owo.network.ServerAccess;
import net.minecraft.entity.EquipmentSlot;
import dev.enjarai.trickster.util.Hamt;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.screen.NamedScreenHandlerFactory;
Expand All @@ -31,7 +31,7 @@ public Text getDisplayName() {
public ScreenHandler createMenu(int syncId, PlayerInventory playerInventory, PlayerEntity player) {
return new ScrollAndQuillScreenHandler(
syncId, playerInventory, stack, player.getOffHandStack(), EquipmentSlot.MAINHAND,
Hamt.empty(), stack.isOf(ModItems.MIRROR_OF_EVALUATION), true
HashMap.empty(), stack.isOf(ModItems.MIRROR_OF_EVALUATION), true
);
}
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@

import dev.enjarai.trickster.spell.Pattern;
import dev.enjarai.trickster.spell.SpellPart;
import dev.enjarai.trickster.util.Hamt;
import io.vavr.collection.HashMap;

public interface RevisionContext {
void updateSpell(SpellPart sp);
void updateSpellWithSpell(SpellPart drawingPart, SpellPart spell);
void updateOtherHandSpell(SpellPart sp);
SpellPart getOtherHandSpell();
void executeOffhand();
Hamt<Pattern, SpellPart> getMacros();
HashMap<Pattern, SpellPart> getMacros();
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package dev.enjarai.trickster.screen;

import dev.enjarai.trickster.EndecTomfoolery;
import dev.enjarai.trickster.ModSounds;
import dev.enjarai.trickster.advancement.criterion.ModCriteria;
import dev.enjarai.trickster.item.ModItems;
Expand All @@ -11,10 +12,10 @@
import dev.enjarai.trickster.spell.execution.executor.DefaultSpellExecutor;
import dev.enjarai.trickster.spell.execution.source.PlayerSpellSource;
import dev.enjarai.trickster.spell.fragment.FragmentType;
import dev.enjarai.trickster.util.Hamt;
import dev.enjarai.trickster.spell.fragment.VoidFragment;
import dev.enjarai.trickster.spell.blunder.BlunderException;
import dev.enjarai.trickster.spell.blunder.NaNBlunder;
import io.vavr.collection.HashMap;
import io.wispforest.endec.Endec;
import io.wispforest.endec.impl.StructEndecBuilder;
import io.wispforest.owo.client.screens.SyncedProperty;
Expand All @@ -27,7 +28,8 @@
import net.minecraft.sound.SoundCategory;
import net.minecraft.text.Text;

import java.util.*;
import java.util.List;
import java.util.Optional;
import java.util.function.Consumer;

public class ScrollAndQuillScreenHandler extends ScreenHandler implements RevisionContext {
Expand All @@ -38,7 +40,7 @@ public class ScrollAndQuillScreenHandler extends ScreenHandler implements Revisi
public final SyncedProperty<SpellPart> otherHandSpell = createProperty(SpellPart.class, SpellPart.ENDEC, new SpellPart());
public final SyncedProperty<Boolean> isMutable = createProperty(Boolean.class, true);
//TODO: Ask glisco why the null parameter isn't used in owo's source -- Aurora Dawn
public final SyncedProperty<Hamt<Pattern, SpellPart>> macros = createProperty(null, Hamt.endec(Pattern.ENDEC, SpellPart.ENDEC), Hamt.empty());
public final SyncedProperty<HashMap<Pattern, SpellPart>> macros = createProperty(null, EndecTomfoolery.hamt(Pattern.ENDEC, SpellPart.ENDEC), HashMap.empty());

public Consumer<Fragment> replacerCallback;
public Consumer<Optional<SpellPart>> updateDrawingPartCallback;
Expand All @@ -50,7 +52,7 @@ public ScrollAndQuillScreenHandler(int syncId, PlayerInventory playerInventory)
this(syncId, playerInventory, null, null, null, null, false, true);
}

public ScrollAndQuillScreenHandler(int syncId, PlayerInventory playerInventory, ItemStack scrollStack, ItemStack otherHandStack, EquipmentSlot slot, Hamt<Pattern, SpellPart> macros, boolean greedyEvaluation, boolean isMutable) {
public ScrollAndQuillScreenHandler(int syncId, PlayerInventory playerInventory, ItemStack scrollStack, ItemStack otherHandStack, EquipmentSlot slot, HashMap<Pattern, SpellPart> macros, boolean greedyEvaluation, boolean isMutable) {
super(ModScreenHandlers.SCROLL_AND_QUILL, syncId);

this.scrollStack = scrollStack;
Expand Down Expand Up @@ -194,7 +196,7 @@ public SpellPart getOtherHandSpell() {
}

@Override
public Hamt<Pattern, SpellPart> getMacros() {
public HashMap<Pattern, SpellPart> getMacros() {
return macros.get();
}

Expand Down
4 changes: 2 additions & 2 deletions src/main/java/dev/enjarai/trickster/spell/SpellPart.java
Original file line number Diff line number Diff line change
Expand Up @@ -116,13 +116,13 @@ public Fragment destructiveRun(SpellContext ctx) {
return value;
}

public void buildClosure(Map<Fragment, Fragment> replacements) {
public void buildClosure(io.vavr.collection.Map<Fragment, Fragment> replacements) {
subParts.forEach(part -> part.buildClosure(replacements));

if (glyph instanceof SpellPart spellPart) {
spellPart.buildClosure(replacements);
} else if (replacements.containsKey(glyph)) {
glyph = replacements.get(glyph);
glyph = replacements.get(glyph).get();
}
}

Expand Down
40 changes: 14 additions & 26 deletions src/main/java/dev/enjarai/trickster/spell/fragment/MapFragment.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
package dev.enjarai.trickster.spell.fragment;

import java.util.HashMap;
import java.util.Optional;
import java.util.Stack;

import dev.enjarai.trickster.spell.Fragment;
Expand All @@ -10,16 +8,17 @@
import dev.enjarai.trickster.spell.SpellContext;
import dev.enjarai.trickster.spell.SpellPart;
import dev.enjarai.trickster.spell.execution.executor.FoldingSpellExecutor;
import io.vavr.Tuple2;
import io.vavr.collection.HashMap;
import io.wispforest.endec.Endec;
import io.wispforest.endec.StructEndec;
import io.wispforest.endec.impl.StructEndecBuilder;
import net.minecraft.text.MutableText;
import dev.enjarai.trickster.util.Hamt;
import net.minecraft.text.Text;

public record MapFragment(Hamt<Fragment, Fragment> map) implements FoldableFragment {
public record MapFragment(HashMap<Fragment, Fragment> map) implements FoldableFragment {
public static final StructEndec<MapFragment> ENDEC = StructEndecBuilder.of(
Endec.map(Fragment.ENDEC, Fragment.ENDEC).xmap(Hamt::fromMap, Hamt::asMap).fieldOf("entries", MapFragment::map),
Endec.map(Fragment.ENDEC, Fragment.ENDEC).xmap(HashMap::ofAll, HashMap::toJavaMap).fieldOf("entries", MapFragment::map),
MapFragment::new
);

Expand All @@ -35,7 +34,7 @@ public Text asText() {
var iterator = map.iterator();

iterator.forEachRemaining(entry -> {
out.append(entry.getKey().asFormattedText()).append(": ").append(entry.getValue().asFormattedText());
out.append(entry._1().asFormattedText()).append(": ").append(entry._2().asFormattedText());
if (iterator.hasNext())
out.append(", ");
});
Expand All @@ -55,33 +54,22 @@ public int getWeight() {
int weight = 16;

for (var kv : map) {
weight += kv.getKey().getWeight();
weight += kv.getValue().getWeight();
weight += kv._1().getWeight();
weight += kv._2().getWeight();
}

return weight;
}

@Override
public MapFragment applyEphemeral() {
return new MapFragment(map.stream()
.reduce(Hamt.<Fragment, Fragment>empty(),
(last, current) -> Hamt.<Fragment, Fragment>empty().assoc(current.getKey().applyEphemeral(), current.getValue().applyEphemeral()),
Hamt::assocAll));
return new MapFragment(map.map((key, value) -> new Tuple2<>(key.applyEphemeral(), value.applyEphemeral())));
}

public Optional<Hamt<Pattern, SpellPart>> getMacroMap() {
var macros = new HashMap<Pattern, SpellPart>();

for (var entry : map) {
if (entry.getKey() instanceof PatternGlyph pattern && entry.getValue() instanceof SpellPart spell) {
macros.put(pattern.pattern(), spell);
} else {
return Optional.empty();
}
}

return Optional.of(Hamt.fromMap(macros));
public HashMap<Pattern, SpellPart> getMacroMap() {
return map.filter((key, value) -> key instanceof PatternGlyph && value instanceof SpellPart)
.mapKeys(k -> ((PatternGlyph) k).pattern())
.mapValues(SpellPart.class::cast);
}

@Override
Expand All @@ -90,8 +78,8 @@ public FoldingSpellExecutor fold(SpellContext ctx, SpellPart executable, Fragmen
var values = new Stack<Fragment>();

for (var kv : map) {
keys.addFirst(kv.getKey());
values.addFirst(kv.getValue());
keys.addFirst(kv._1());
values.addFirst(kv._2());
}

return new FoldingSpellExecutor(ctx, executable, identity, values, keys, this);
Expand Down
Loading

0 comments on commit 7a5494d

Please sign in to comment.