Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
96 commits
Select commit Hold shift + click to select a range
bd067a6
Version bump
RainWarrior Mar 12, 2020
86514dc
Posfix function application helper for Dynamic
RainWarrior Mar 9, 2020
83fc8f7
Moved dynamic-related code to a separate package
RainWarrior Mar 9, 2020
e188d4b
Renamed NilSave to EmptyPartSaving and NilDrop to EmptyPart; Added Da…
RainWarrior Mar 10, 2020
1701c43
Replaced read with a version that returns DataResult.
RainWarrior Mar 10, 2020
1b44126
Convert EmptyPartSaving instead of only casting.
RainWarrior Mar 10, 2020
165b35c
Added a Codec interface
RainWarrior Mar 10, 2020
d6b5502
Changed error handling functions slightly
RainWarrior Mar 11, 2020
00331a2
Added list and map builder helpers to DynamicOps.
RainWarrior Mar 11, 2020
3ae1c19
Re-added empty as a valid input for mergeInto methods.
RainWarrior Mar 11, 2020
6378f3d
Applicative syntax helpers, decoder helpers, decoder-based helpers in…
RainWarrior Mar 12, 2020
cd0da20
Replaced remaining usages of Optional in Dynamic API with DataResult.
RainWarrior Mar 12, 2020
a84c574
Pair map collector
RainWarrior Mar 12, 2020
ffbd838
Java boilerplate for DataResult
RainWarrior Mar 12, 2020
4f838a6
Decoder factories improvements
RainWarrior Mar 12, 2020
f7f6224
Renamed mergeInto to either mergeToList or mergeToMap, added mergeToP…
RainWarrior Mar 14, 2020
70f54be
Made ListBox invariant, added a bunch of dynamic helpers.
RainWarrior Mar 14, 2020
7ababc2
Split off codecs and types.
RainWarrior Mar 14, 2020
0ca3396
Split off primitive codecs, removed NamespacedString.
RainWarrior Mar 14, 2020
8fcfa8c
Fixed early initialization of codec field.
RainWarrior Mar 14, 2020
8f216b5
builder.add overload
RainWarrior Mar 14, 2020
ae6eedd
Moved input to a first argument of Encoder.encode to allow instance m…
RainWarrior Mar 14, 2020
b15d114
Lazy unit decoder
RainWarrior Mar 14, 2020
ca9885c
Fixed error in JsonOps list builder override
RainWarrior Mar 14, 2020
77be75c
Replaced Type with Codec in DynamicOps
RainWarrior Mar 14, 2020
1e8fe07
Better map interface for DynamicOps, allows returning a wrapper inste…
RainWarrior Mar 15, 2020
6bde925
Applicative codec builder; switched applicative implementation from l…
RainWarrior Mar 15, 2020
26fdeff
Couple more overrides in DataResult.Instance for less recursion.
RainWarrior Mar 15, 2020
3773900
Added OptionalFieldCodec
RainWarrior Mar 15, 2020
ccea94f
8-arg applicative boilerplate.
RainWarrior Mar 15, 2020
cf620f6
Codec.withDefault
RainWarrior Mar 15, 2020
ed12c92
Use applicative syntax for DataResult if possible.
RainWarrior Mar 15, 2020
69507ee
Made Codec.BOOL use DynamicOps.getBooleanValue
RainWarrior Mar 15, 2020
0a847c0
Fixed null being used for Unit instance
RainWarrior Mar 15, 2020
cbe67e4
Track used keys in map codecs
RainWarrior Mar 15, 2020
8447c28
MapLike.get overload for String keys
RainWarrior Mar 15, 2020
a042d34
Compressed map codec
RainWarrior Mar 15, 2020
7098975
Call MapLike.get(String) if possible
RainWarrior Mar 15, 2020
5ef666c
Compressable JsonOps instance
RainWarrior Mar 15, 2020
c03ca06
Split FieldDecoder and FieldEncoder from FieldCodec, added a helper f…
RainWarrior Mar 16, 2020
4d86331
A bunch of toStrings
RainWarrior Mar 17, 2020
09299f0
Performance optimizations, specialized record builder for JsonOps
RainWarrior Mar 17, 2020
8e2ecab
Exploring slightly alternative syntax for RecordCodecBuilder
RainWarrior Mar 24, 2020
ea97a3f
Codecs for lists of primitives specialised in DynamicOps
RainWarrior Mar 26, 2020
d4f705a
Fixed error in compressed OptionalFieldCodec, cleaned up compressed M…
RainWarrior Apr 21, 2020
a9858d6
Added a direct getter to OptionalDynamic
RainWarrior Apr 21, 2020
a9d0d6b
Applicative .and helpers
RainWarrior Apr 22, 2020
438d062
Function9 - Function16
RainWarrior Apr 22, 2020
21303f6
9-arg applicative methods, sorted
RainWarrior Apr 22, 2020
c324d75
ap10 - ap16
RainWarrior Apr 22, 2020
9c28f5c
P9 - P16
RainWarrior Apr 22, 2020
f3a3eef
group(9) - group(16)
RainWarrior Apr 22, 2020
302d259
A bunch of helpers on Codec
RainWarrior Apr 23, 2020
82b3356
Method to thread error through RecordBuilder and ListBuilder.
RainWarrior Apr 23, 2020
e7f9e26
Fixed json null handling
RainWarrior Apr 23, 2020
52602ad
Removed useless overrides in field codecs
RainWarrior Apr 23, 2020
7987718
Simple map codec
RainWarrior Apr 23, 2020
36feaf5
Extracted KeyDispatchCodec from TaggedChoiceType
RainWarrior Apr 23, 2020
9d211c4
Fixed compressor not falling back to non-string keys gracefully
RainWarrior Apr 23, 2020
ea09a02
Tweaked and expanded error handling, made list and map codecs collect…
RainWarrior Apr 24, 2020
4d4587e
Made KeyDispatchCodec more robust for non-map codecs, added PairMapCo…
RainWarrior May 4, 2020
27b00ac
Pair codecs encode second element first, to make typed entries overri…
RainWarrior May 4, 2020
658c05f
Lifecycle tracking in codecs and DataResult
RainWarrior May 5, 2020
96396bb
Optional field with default value and different lifecycles helper
RainWarrior May 6, 2020
21e277a
Marked more things stable
RainWarrior May 7, 2020
85ccdf7
Added UnboundedMapCodec
RainWarrior May 7, 2020
2a67508
Fixed lifecycle addition bug
RainWarrior May 8, 2020
15d3282
Slighly cleaner implementation of keys() in RecordCodecBuilder
RainWarrior May 8, 2020
d9def8e
Split off generic products from Applicative, moved factories to Kind
RainWarrior May 11, 2020
0a69855
Made MapCodec not extend Codec anymore
RainWarrior May 9, 2020
c5117e0
Removed Serializable interface
RainWarrior May 9, 2020
d5d4b3a
Fixed duplicate key issue in KeyDispatchCodec
RainWarrior May 11, 2020
a7cc332
Do not create the new object in Lifecycle.add
RainWarrior May 11, 2020
bea693c
Renamed DynamicException to PartialResult
RainWarrior May 11, 2020
8628de3
Made Deprecated class public
RainWarrior May 11, 2020
07d6317
Extracted message appending logic in DataResult
RainWarrior May 11, 2020
d50e28a
Function<String, String> -> UnaryOperator<String>
RainWarrior May 11, 2020
e09880b
Removed unused method
RainWarrior May 11, 2020
ae27361
Removed useless stream collect
RainWarrior May 11, 2020
afb8369
List variable type
RainWarrior May 11, 2020
061642a
Saving -> Passthrough
RainWarrior May 11, 2020
d4a1dba
Replaced getType with ops-based dispatch
RainWarrior May 11, 2020
47bfac1
Fixed copypaste error
RainWarrior May 11, 2020
330d3ea
Extracted CompressorHolder from Map*.Implementation
RainWarrior May 11, 2020
ca21051
Inlined redundant self constants
RainWarrior May 11, 2020
5d34fe8
MapCompressor -> KeyCompressor
RainWarrior May 11, 2020
99b0497
Cleaned up RecordBuilder hierarchy
RainWarrior May 12, 2020
45a1715
Use Stream.reduce in BaseMapCodec
RainWarrior May 12, 2020
5fdd984
AtomicReference -> MutableObject
RainWarrior May 12, 2020
56fdd77
Fixed extraneous field
RainWarrior May 12, 2020
d612243
Added roundrip codec test
RainWarrior May 12, 2020
ce9ec60
Reordered primitive codec definitions
RainWarrior May 12, 2020
dab00f1
ImmutableList.Builder -> Stream.Builder
RainWarrior May 12, 2020
aef2853
Small cleanup of byte buffer stream creation
RainWarrior May 12, 2020
a1f4543
Fixed implementation of keys in EitherMapCodec
RainWarrior May 12, 2020
4b40983
Style/import stuff.
grum May 12, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ dependencies {
compile 'com.google.guava:guava:21.0'
compile 'org.apache.commons:commons-lang3:3.5'
compile 'it.unimi.dsi:fastutil:7.1.0'
testCompile 'junit:junit-dep:4.10'
}

task sourcesJar(type: Jar) {
Expand Down
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
@@ -1 +1 @@
majorMinor: 2.0
majorMinor: 3.0
72 changes: 29 additions & 43 deletions src/main/java/com/mojang/datafixers/DSL.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,11 @@
package com.mojang.datafixers;

import com.google.common.collect.Maps;
import com.mojang.datafixers.util.Either;
import com.mojang.datafixers.util.Pair;
import com.mojang.datafixers.util.Unit;
import com.mojang.datafixers.kinds.App2;
import com.mojang.datafixers.schemas.Schema;
import com.mojang.datafixers.types.Func;
import com.mojang.datafixers.types.Type;
import com.mojang.datafixers.types.constant.BoolType;
import com.mojang.datafixers.types.constant.ByteType;
import com.mojang.datafixers.types.constant.DoubleType;
import com.mojang.datafixers.types.constant.FloatType;
import com.mojang.datafixers.types.constant.IntType;
import com.mojang.datafixers.types.constant.LongType;
import com.mojang.datafixers.types.constant.NamespacedStringType;
import com.mojang.datafixers.types.constant.NilDrop;
import com.mojang.datafixers.types.constant.NilSave;
import com.mojang.datafixers.types.constant.ShortType;
import com.mojang.datafixers.types.constant.StringType;
import com.mojang.datafixers.types.constant.EmptyPart;
import com.mojang.datafixers.types.constant.EmptyPartPassthrough;
import com.mojang.datafixers.types.templates.Check;
import com.mojang.datafixers.types.templates.CompoundList;
import com.mojang.datafixers.types.templates.Const;
Expand All @@ -33,13 +20,17 @@
import com.mojang.datafixers.types.templates.Tag;
import com.mojang.datafixers.types.templates.TaggedChoice;
import com.mojang.datafixers.types.templates.TypeTemplate;
import com.mojang.datafixers.util.Either;
import com.mojang.datafixers.util.Pair;
import com.mojang.datafixers.util.Unit;
import com.mojang.serialization.Codec;
import com.mojang.serialization.Dynamic;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.tuple.Triple;

import java.util.Map;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.stream.Collectors;

public interface DSL {
interface TypeReference {
Expand Down Expand Up @@ -84,24 +75,20 @@ static Type<String> string() {
return Instances.STRING_TYPE;
}

static Type<String> namespacedString() {
return Instances.NAMESPACED_STRING_TYPE;
}

static TypeTemplate nil() {
return constType(Instances.NIL_DROP);
static TypeTemplate emptyPart() {
return constType(Instances.EMPTY_PART);
}

static Type<Unit> nilType() {
return Instances.NIL_DROP;
static Type<Unit> emptyPartType() {
return Instances.EMPTY_PART;
}

static TypeTemplate remainder() {
return constType(Instances.NIL_SAVE);
return constType(Instances.EMPTY_PASSTHROUGH);
}

static Type<Dynamic<?>> remainderType() {
return Instances.NIL_SAVE;
return Instances.EMPTY_PASSTHROUGH;
}

static TypeTemplate check(final String name, final int index, final TypeTemplate element) {
Expand Down Expand Up @@ -208,11 +195,11 @@ static <K> TaggedChoice<K> taggedChoice(final String name, final Type<K> keyType
}

static <K> TaggedChoice<K> taggedChoiceLazy(final String name, final Type<K> keyType, final Map<K, Supplier<TypeTemplate>> templates) {
return taggedChoice(name, keyType, templates.entrySet().stream().map(e -> Pair.of(e.getKey(), e.getValue().get())).collect(Collectors.toMap(Pair::getFirst, Pair::getSecond)));
return taggedChoice(name, keyType, templates.entrySet().stream().map(e -> Pair.of(e.getKey(), e.getValue().get())).collect(Pair.toMap()));
}

@SuppressWarnings("unchecked")
static <K> Type<Pair<K, ?>> taggedChoiceType(final String name, final Type<K> keyType, final Map<K, Type<?>> types) {
static <K> Type<Pair<K, ?>> taggedChoiceType(final String name, final Type<K> keyType, final Map<K, ? extends Type<?>> types) {
return (Type<Pair<K, ?>>) Instances.TAGGED_CHOICE_TYPE_CACHE.computeIfAbsent(Triple.of(name, keyType, types), k -> new TaggedChoice.TaggedChoiceType<>(k.getLeft(), (Type<K>) k.getMiddle(), (Map<K, Type<?>>) k.getRight()));
}

Expand All @@ -223,11 +210,11 @@ static <A, B> Type<Function<A, B>> func(final Type<A> input, final Type<B> outpu
// Helpers

static <A> Type<Either<A, Unit>> optional(final Type<A> type) {
return or(type, nilType());
return or(type, emptyPartType());
}

static TypeTemplate optional(final TypeTemplate value) {
return or(value, nil());
return or(value, emptyPart());
}

static TypeTemplate fields(
Expand Down Expand Up @@ -443,24 +430,23 @@ static <FT> OpticFinder<FT> namedChoice(final String name, final Type<FT> type)
}

static Unit unit() {
return null;
return Unit.INSTANCE;
}

final class Instances {
private static final Type<Boolean> BOOL_TYPE = new BoolType();
private static final Type<Integer> INT_TYPE = new IntType();
private static final Type<Long> LONG_TYPE = new LongType();
private static final Type<Byte> BYTE_TYPE = new ByteType();
private static final Type<Short> SHORT_TYPE = new ShortType();
private static final Type<Float> FLOAT_TYPE = new FloatType();
private static final Type<Double> DOUBLE_TYPE = new DoubleType();
private static final Type<String> STRING_TYPE = new StringType();
private static final Type<String> NAMESPACED_STRING_TYPE = new NamespacedStringType();
private static final Type<Unit> NIL_DROP = new NilDrop();
private static final Type<Dynamic<?>> NIL_SAVE = new NilSave();
private static final Type<Boolean> BOOL_TYPE = new Const.PrimitiveType<>(Codec.BOOL);
private static final Type<Integer> INT_TYPE = new Const.PrimitiveType<>(Codec.INT);
private static final Type<Long> LONG_TYPE = new Const.PrimitiveType<>(Codec.LONG);
private static final Type<Byte> BYTE_TYPE = new Const.PrimitiveType<>(Codec.BYTE);
private static final Type<Short> SHORT_TYPE = new Const.PrimitiveType<>(Codec.SHORT);
private static final Type<Float> FLOAT_TYPE = new Const.PrimitiveType<>(Codec.FLOAT);
private static final Type<Double> DOUBLE_TYPE = new Const.PrimitiveType<>(Codec.DOUBLE);
private static final Type<String> STRING_TYPE = new Const.PrimitiveType<>(Codec.STRING);
private static final Type<Unit> EMPTY_PART = new EmptyPart();
private static final Type<Dynamic<?>> EMPTY_PASSTHROUGH = new EmptyPartPassthrough();

private static final OpticFinder<Dynamic<?>> REMAINDER_FINDER = remainderType().finder();

private static final Map<Triple<String, Type<?>, Map<?, Type<?>>>, Type<? extends Pair<?, ?>>> TAGGED_CHOICE_TYPE_CACHE = Maps.newConcurrentMap();
private static final Map<Triple<String, Type<?>, Map<?, ? extends Type<?>>>, Type<? extends Pair<?, ?>>> TAGGED_CHOICE_TYPE_CACHE = Maps.newConcurrentMap();
}
}
19 changes: 15 additions & 4 deletions src/main/java/com/mojang/datafixers/DataFix.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,17 @@
package com.mojang.datafixers;

import com.mojang.datafixers.schemas.Schema;
import com.mojang.datafixers.types.DynamicOps;
import com.mojang.datafixers.types.Type;
import com.mojang.datafixers.util.Pair;
import com.mojang.serialization.Dynamic;
import com.mojang.serialization.DynamicOps;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import javax.annotation.Nullable;
import java.util.BitSet;
import java.util.Objects;
import java.util.Optional;
import java.util.function.Function;

public abstract class DataFix {
Expand Down Expand Up @@ -40,9 +43,17 @@ protected TypeRewriteRule writeAndRead(final String name, final Type<?> type, fi
}

protected <A, B> TypeRewriteRule writeFixAndRead(final String name, final Type<A> type, final Type<B> newType, final Function<Dynamic<?>, Dynamic<?>> fix) {
return fixTypeEverywhere(name, type, newType, ops -> input ->
newType.readTyped(fix.apply(type.writeDynamic(ops, input))).getSecond().orElseThrow(() -> new IllegalStateException("Could not read new type in \"" + name + "\"")).getValue()
);
return fixTypeEverywhere(name, type, newType, ops -> input -> {
final Optional<? extends Dynamic<?>> written = type.writeDynamic(ops, input).resultOrPartial(LOGGER::error);
if (!written.isPresent()) {
throw new RuntimeException("Could not write the object in " + name);
}
final Optional<? extends Pair<Typed<B>, ?>> read = newType.readTyped(fix.apply(written.get())).resultOrPartial(LOGGER::error);
if (!read.isPresent()) {
throw new RuntimeException("Could not read the new object in " + name);
}
return read.get().getFirst().getValue();
});
}

protected <A, B> TypeRewriteRule fixTypeEverywhere(final String name, final Type<A> type, final Type<B> newType, final Function<DynamicOps<?>, Function<A, B>> function) {
Expand Down
8 changes: 8 additions & 0 deletions src/main/java/com/mojang/datafixers/DataFixUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import java.util.Optional;
import java.util.function.Consumer;
import java.util.function.Supplier;
import java.util.function.UnaryOperator;

public class DataFixUtils {
private DataFixUtils() {
Expand Down Expand Up @@ -93,4 +94,11 @@ public static int getVersion(final int key) {
public static int getSubVersion(final int key) {
return key % 10;
}

public static <T> UnaryOperator<T> consumerToFunction(final Consumer<T> consumer) {
return s -> {
consumer.accept(s);
return s;
};
}
}
1 change: 1 addition & 0 deletions src/main/java/com/mojang/datafixers/DataFixer.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
package com.mojang.datafixers;

import com.mojang.datafixers.schemas.Schema;
import com.mojang.serialization.Dynamic;

public interface DataFixer {
<T> Dynamic<T> update(DSL.TypeReference type, Dynamic<T> input, int version, int newVersion);
Expand Down
26 changes: 10 additions & 16 deletions src/main/java/com/mojang/datafixers/DataFixerUpper.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,20 @@

import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
import com.mojang.datafixers.functions.PointFreeRule;
import com.mojang.datafixers.schemas.Schema;
import com.mojang.datafixers.types.Type;
import com.mojang.serialization.DataResult;
import com.mojang.serialization.Dynamic;
import it.unimi.dsi.fastutil.ints.Int2ObjectSortedMap;
import it.unimi.dsi.fastutil.ints.IntSortedSet;
import it.unimi.dsi.fastutil.longs.Long2ObjectMap;
import it.unimi.dsi.fastutil.longs.Long2ObjectMaps;
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
import com.mojang.datafixers.functions.PointFreeRule;
import com.mojang.datafixers.schemas.Schema;
import com.mojang.datafixers.types.Type;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.util.List;
import java.util.Optional;

/*
* Optimizing functions
Expand Down Expand Up @@ -78,18 +79,11 @@ protected DataFixerUpper(final Int2ObjectSortedMap<Schema> schemas, final List<D

@Override
public <T> Dynamic<T> update(final DSL.TypeReference type, final Dynamic<T> input, final int version, final int newVersion) {
try {
if (version < newVersion) {
final Type<?> dataType = getType(type, version);
final Optional<T> read = dataType.readAndWrite(input.getOps(), getType(type, newVersion), getRule(version, newVersion), OPTIMIZATION_RULE, input.getValue());
if (!read.isPresent()) {
throw new IllegalStateException("Could not parse for fixing " + dataType);
}

return new Dynamic<>(input.getOps(), read.get());
}
} catch (final Throwable t) {
LOGGER.error("Something went wrong upgrading!", t);
if (version < newVersion) {
final Type<?> dataType = getType(type, version);
final DataResult<T> read = dataType.readAndWrite(input.getOps(), getType(type, newVersion), getRule(version, newVersion), OPTIMIZATION_RULE, input.getValue());
final T result = read.resultOrPartial(LOGGER::error).orElse(input.getValue());
return new Dynamic<>(input.getOps(), result);
}
return input;
}
Expand Down
Loading