Created
October 18, 2020 19:26
-
-
Save kvverti/dec17e824922e1974313b8beadc621c5 to your computer and use it in GitHub Desktop.
Extending Codecs with Mixin
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[15:18:46] [main/INFO] (Minecraft) [STDOUT]: Injected field: 47 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package robosky.uplands.mixin; | |
import java.util.function.Function; | |
import com.mojang.datafixers.kinds.App; | |
import com.mojang.serialization.Codec; | |
import com.mojang.serialization.MapCodec; | |
import com.mojang.serialization.codecs.RecordCodecBuilder; | |
import org.spongepowered.asm.mixin.Dynamic; | |
import org.spongepowered.asm.mixin.Mixin; | |
import org.spongepowered.asm.mixin.Unique; | |
import org.spongepowered.asm.mixin.injection.At; | |
import org.spongepowered.asm.mixin.injection.ModifyArg; | |
import net.minecraft.world.gen.surfacebuilder.TernarySurfaceConfig; | |
@Mixin(TernarySurfaceConfig.class) | |
public abstract class TernarySurfaceConfigMixin { | |
// injected field(s) | |
@Unique | |
private int myInteger = 3; | |
// codec modification | |
// target the `RecordCodecBuilder.create(...)` call | |
// generics are extra disgusting, see DFU docs for more info | |
@Dynamic("Static init") | |
@ModifyArg( | |
method = "<clinit>", | |
index = 0, | |
at = @At( | |
value = "INVOKE", | |
target = "Lcom/mojang/serialization/codecs/RecordCodecBuilder;create(Ljava/util/function/Function;)Lcom/mojang/serialization/Codec;", | |
remap = false | |
) | |
) | |
private static Function<RecordCodecBuilder.Instance<TernarySurfaceConfig>, ? extends App<RecordCodecBuilder.Mu<TernarySurfaceConfig>, TernarySurfaceConfig>> | |
extendCodec(Function<RecordCodecBuilder.Instance<TernarySurfaceConfig>, ? extends App<RecordCodecBuilder.Mu<TernarySurfaceConfig>, TernarySurfaceConfig>> fields) { | |
MapCodec<TernarySurfaceConfig> mapCodec = RecordCodecBuilder.mapCodec(fields); | |
return inst -> inst.group( | |
// preserve the original fields | |
mapCodec.forGetter(Function.identity()), | |
// inject our new field | |
// use optionalFieldOf so that vanilla JSON configs still deserialize properly | |
Codec.INT.optionalFieldOf("myInt", 3).forGetter(cfg -> ((TernarySurfaceConfigMixin)(Object)cfg).myInteger) | |
).apply(inst, (cfg, i) -> { | |
// set additional fields in cfg, then return it | |
((TernarySurfaceConfigMixin)(Object)cfg).myInteger = i; | |
System.out.println("Injected field: " + i); | |
return cfg; | |
}); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"type": "$modid:uplands_surface_builder", | |
"config": { | |
"top_material": { | |
"Name": "$modid:uplander_grass" | |
}, | |
"under_material": { | |
"Name": "$modid:uplander_dirt" | |
}, | |
"underwater_material": { | |
"Name": "$modid:uplander_dirt" | |
}, | |
"myInt": 47 | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment