Update raw palette array on value insertion for SingleValuePalette

It may be possible to invoke moonrise$getRawPalette before
the palette's single value is initialised, so we need to track
the returned raw palette array.
This commit is contained in:
Spottedleaf
2024-07-14 05:14:36 -07:00
parent 24657f1fd6
commit e0aac6916b
4 changed files with 56 additions and 5 deletions

View File

@@ -22,7 +22,7 @@ public abstract class CrudeIncrementalIntIdentityHashBiMapMixin<K> implements Id
private FastPaletteData<K> reference;
@Override
public K[] moonrise$getRawPalette(final FastPaletteData<K> src) {
public final K[] moonrise$getRawPalette(final FastPaletteData<K> src) {
this.reference = src;
return this.byId;
}

View File

@@ -17,7 +17,7 @@ public abstract class HashMapPaletteMixin<T> implements Palette<T>, FastPalette<
private CrudeIncrementalIntIdentityHashBiMap<T> values;
@Override
public T[] moonrise$getRawPalette(final FastPaletteData<T> container) {
public final T[] moonrise$getRawPalette(final FastPaletteData<T> container) {
return ((FastPalette<T>)this.values).moonrise$getRawPalette(container);
}
}

View File

@@ -16,7 +16,7 @@ public abstract class LinearPaletteMixin<T> implements Palette<T>, FastPalette<T
private T[] values;
@Override
public T[] moonrise$getRawPalette(final FastPaletteData<T> container) {
public final T[] moonrise$getRawPalette(final FastPaletteData<T> container) {
return this.values;
}
}

View File

@@ -2,10 +2,18 @@ package ca.spottedleaf.moonrise.mixin.fast_palette;
import ca.spottedleaf.moonrise.patches.fast_palette.FastPalette;
import ca.spottedleaf.moonrise.patches.fast_palette.FastPaletteData;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.world.level.chunk.Palette;
import net.minecraft.world.level.chunk.SingleValuePalette;
import org.objectweb.asm.Opcodes;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.Redirect;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@Mixin(SingleValuePalette.class)
public abstract class SingleValuePaletteMixin<T> implements Palette<T>, FastPalette<T> {
@@ -13,8 +21,51 @@ public abstract class SingleValuePaletteMixin<T> implements Palette<T>, FastPale
@Shadow
private T value;
@Unique
private T[] rawPalette;
@Override
public T[] moonrise$getRawPalette(final FastPaletteData<T> container) {
return (T[])new Object[] { this.value };
public final T[] moonrise$getRawPalette(final FastPaletteData<T> container) {
if (this.rawPalette != null) {
return this.rawPalette;
}
return this.rawPalette = (T[])new Object[] { this.value };
}
/**
* @reason Hook for updating the raw palette array on value update
* @author Spottedleaf
*/
@Inject(
method = "idFor",
at = @At(
value = "FIELD",
opcode = Opcodes.PUTFIELD,
target = "Lnet/minecraft/world/level/chunk/SingleValuePalette;value:Ljava/lang/Object;"
)
)
private void updateRawPalette1(final T object, final CallbackInfoReturnable<Integer> cir) {
if (this.rawPalette != null) {
this.rawPalette[0] = object;
}
}
/**
* @reason Hook for updating the raw palette array on section read
* @author Spottedleaf
*/
@Redirect(
method = "read",
at = @At(
value = "FIELD",
opcode = Opcodes.PUTFIELD,
target = "Lnet/minecraft/world/level/chunk/SingleValuePalette;value:Ljava/lang/Object;"
)
)
private void updateRawPalette2(final SingleValuePalette<T> instance, final T value) {
((SingleValuePaletteMixin<T>)(Object)instance).value = value;
if (this.rawPalette != null) {
this.rawPalette[0] = value;
}
}
}