Skip to content

Commit ceefdf7

Browse files
committed
wip: reworked DataComponentAdapters to be more generic and usable in multiple places
1 parent 354a5d5 commit ceefdf7

File tree

8 files changed

+390
-268
lines changed

8 files changed

+390
-268
lines changed

paper-server/src/main/java/io/papermc/paper/datacomponent/DataComponentAdapters.java

Lines changed: 0 additions & 250 deletions
This file was deleted.

paper-server/src/main/java/io/papermc/paper/datacomponent/PaperDataComponentType.java

Lines changed: 201 additions & 11 deletions
Large diffs are not rendered by default.
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package io.papermc.paper.datacomponent;
2+
3+
import io.papermc.paper.registry.data.typed.AbstractTypedDataCollector;
4+
import io.papermc.paper.registry.data.typed.PaperTypedDataAdapter;
5+
import net.minecraft.core.Registry;
6+
import net.minecraft.core.component.DataComponentType;
7+
import net.minecraft.resources.ResourceKey;
8+
import org.bukkit.craftbukkit.util.Handleable;
9+
import java.util.Map;
10+
import java.util.function.Function;
11+
12+
class PaperDataComponentTypeCollector extends AbstractTypedDataCollector<DataComponentType<?>> {
13+
14+
public PaperDataComponentTypeCollector(final Registry<DataComponentType<?>> registry, final Map<ResourceKey<?>, PaperTypedDataAdapter<?, ?>> adapters) {
15+
super(registry, adapters);
16+
}
17+
18+
// Not using @Override because of generic types
19+
public <NMS, API extends Handleable<NMS>> void register(final DataComponentType<NMS> dataComponentType, final Function<NMS, API> vanillaToApi) {
20+
super.register(dataComponentType, vanillaToApi);
21+
}
22+
23+
// Not using @Override because of generic types
24+
public <NMS, API> void register(final DataComponentType<NMS> dataComponentType, final Function<NMS, API> vanillaToApi, final Function<API, NMS> apiToVanilla) {
25+
super.register(dataComponentType, vanillaToApi, apiToVanilla);
26+
}
27+
}
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
package io.papermc.paper.registry.data.typed;
2+
3+
import com.mojang.serialization.Codec;
4+
import java.util.Map;
5+
import java.util.function.Function;
6+
import net.minecraft.core.Registry;
7+
import net.minecraft.resources.ResourceKey;
8+
import org.bukkit.craftbukkit.util.Handleable;
9+
import org.jspecify.annotations.Nullable;
10+
11+
// This class exists only to be implemented, implementations must override the following register method:
12+
// void register(final TYPE type, final Function<NMS, API> vanillaToApi, final Function<API, NMS> apiToVanilla)
13+
// BUT should NOT use the @Override annotation, this is a hack around generics limitations to prevent
14+
// having to define generics on each register call as seen below, making collectors easier to read:
15+
// collector.<NMSType, APIType>register(...)
16+
public abstract class AbstractTypedDataCollector<TYPE> implements PaperTypedDataCollector<TYPE> {
17+
18+
private final Registry<TYPE> registry;
19+
private final Map<ResourceKey<?>, PaperTypedDataAdapter<?, ?>> adapters;
20+
21+
public AbstractTypedDataCollector(final Registry<TYPE> registry, final Map<ResourceKey<?>, PaperTypedDataAdapter<?, ?>> adapters) {
22+
this.registry = registry;
23+
this.adapters = adapters;
24+
}
25+
26+
@Override
27+
public void registerUntyped(final TYPE type) {
28+
this.registerInternal(this.getKey(type), PaperTypedDataAdapters.UNIT_TO_API_CONVERTER, PaperTypedDataAdapter.API_TO_UNIT_CONVERTER, null);
29+
}
30+
31+
@Override
32+
public <NMS> void registerIdentity(final TYPE type, final Function<TYPE, @Nullable Codec<NMS>> codecGetter) {
33+
this.registerInternal(this.getKey(type), Function.identity(), Function.identity(), codecGetter.apply(type));
34+
}
35+
36+
@Override
37+
public <NMS, API extends Handleable<NMS>> void register(final TYPE type, final Function<NMS, API> vanillaToApi) {
38+
this.registerInternal(this.getKey(type), vanillaToApi, Handleable::getHandle, null);
39+
}
40+
41+
@Override
42+
public <NMS, API> void register(final TYPE type, final Function<NMS, API> vanillaToApi, final Function<API, NMS> apiToVanilla) {
43+
this.registerInternal(this.getKey(type), vanillaToApi, apiToVanilla, null);
44+
}
45+
46+
private ResourceKey<TYPE> getKey(final TYPE type) {
47+
return this.registry.getResourceKey(type).orElseThrow();
48+
}
49+
50+
void registerUnimplemented() {
51+
for (final ResourceKey<TYPE> key : this.registry.registryKeySet()) {
52+
if (!this.adapters.containsKey(key)) {
53+
this.registerUnimplemented(key);
54+
}
55+
}
56+
}
57+
58+
@SuppressWarnings("unchecked")
59+
private void registerUnimplemented(final ResourceKey<TYPE> key) {
60+
this.registerInternal(key, PaperTypedDataAdapters.UNIMPLEMENTED_TO_API_CONVERTER, PaperTypedDataAdapter.API_TO_UNIMPLEMENTED_CONVERTER, null);
61+
}
62+
63+
private <NMS, API> void registerInternal(
64+
final ResourceKey<?> key,
65+
final Function<NMS, API> vanillaToApi,
66+
final Function<API, NMS> apiToVanilla,
67+
final @Nullable Codec<NMS> codec
68+
) {
69+
if (this.adapters.containsKey(key)) {
70+
throw new IllegalStateException("Duplicate adapter registration for " + key);
71+
}
72+
73+
this.adapters.put(key, new PaperTypedDataAdapter<>(apiToVanilla, vanillaToApi, codec));
74+
}
75+
}

paper-server/src/main/java/io/papermc/paper/datacomponent/DataComponentAdapter.java renamed to paper-server/src/main/java/io/papermc/paper/registry/data/typed/PaperTypedDataAdapter.java

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,17 @@
1-
package io.papermc.paper.datacomponent;
1+
package io.papermc.paper.registry.data.typed;
22

3+
import com.mojang.serialization.Codec;
34
import java.util.function.Function;
45
import net.minecraft.core.Holder;
5-
import net.minecraft.core.component.DataComponentType;
66
import net.minecraft.util.NullOps;
77
import net.minecraft.util.Unit;
88
import org.bukkit.craftbukkit.CraftRegistry;
9+
import org.jspecify.annotations.Nullable;
910

10-
public record DataComponentAdapter<NMS, API>(
11+
public record PaperTypedDataAdapter<NMS, API>(
1112
Function<API, NMS> apiToVanilla,
1213
Function<NMS, API> vanillaToApi,
13-
boolean codecValidation
14+
@Nullable Codec<NMS> codec
1415
) {
1516
static final Function<Void, Unit> API_TO_UNIT_CONVERTER = $ -> Unit.INSTANCE;
1617

@@ -26,10 +27,10 @@ public boolean isUnimplemented() {
2627
return this.apiToVanilla == API_TO_UNIMPLEMENTED_CONVERTER;
2728
}
2829

29-
public NMS toVanilla(final API value, final Holder<? extends DataComponentType<NMS>> type) {
30+
public NMS toVanilla(final API value, final Holder<?> type) {
3031
final NMS nms = this.apiToVanilla.apply(value);
31-
if (this.codecValidation && !type.value().isTransient()) {
32-
type.value().codecOrThrow().encodeStart(CraftRegistry.getMinecraftRegistry().createSerializationContext(NullOps.INSTANCE), nms).ifError(error -> {
32+
if (this.codec != null) {
33+
this.codec.encodeStart(CraftRegistry.getMinecraftRegistry().createSerializationContext(NullOps.INSTANCE), nms).ifError(error -> {
3334
throw new IllegalArgumentException("Failed to encode data component %s (%s)".formatted(type.unwrapKey().orElseThrow(), error.message()));
3435
});
3536
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
package io.papermc.paper.registry.data.typed;
2+
3+
import java.util.HashMap;
4+
import java.util.Map;
5+
import java.util.function.Consumer;
6+
import java.util.function.Function;
7+
import net.minecraft.core.Registry;
8+
import net.minecraft.resources.ResourceKey;
9+
import net.minecraft.util.Unit;
10+
import org.jspecify.annotations.Nullable;
11+
12+
public final class PaperTypedDataAdapters {
13+
14+
static final Function<Unit, Void> UNIT_TO_API_CONVERTER = $ -> {
15+
throw new UnsupportedOperationException("Cannot convert the Unit type to an API value");
16+
};
17+
18+
static final Function UNIMPLEMENTED_TO_API_CONVERTER = $ -> {
19+
throw new UnsupportedOperationException("Cannot convert the an unimplemented type to an API value");
20+
};
21+
22+
private final Map<ResourceKey<?>, PaperTypedDataAdapter<?, ?>> adapters;
23+
24+
private PaperTypedDataAdapters(Map<ResourceKey<?>, PaperTypedDataAdapter<?, ?>> adapters) {
25+
this.adapters = adapters;
26+
}
27+
28+
public static <TYPE, COLLECTOR extends AbstractTypedDataCollector<TYPE>> PaperTypedDataAdapters create(
29+
Registry<TYPE> registry,
30+
PaperTypedDataCollector.Factory<TYPE, COLLECTOR> collectorFactory,
31+
Consumer<COLLECTOR> consumer
32+
) {
33+
Map<ResourceKey<?>, PaperTypedDataAdapter<?, ?>> adapters = new HashMap<>();
34+
COLLECTOR collector = collectorFactory.create(registry, adapters);
35+
36+
consumer.accept(collector);
37+
38+
// Loop through every entry in the registry and register any entry
39+
// not already registered as unimplemented
40+
collector.registerUnimplemented();
41+
42+
return new PaperTypedDataAdapters(adapters);
43+
}
44+
45+
@SuppressWarnings("unchecked")
46+
public <RETURN> @Nullable RETURN getAdapter(ResourceKey<?> key) {
47+
return (RETURN) this.adapters.get(key);
48+
}
49+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package io.papermc.paper.registry.data.typed;
2+
3+
import com.mojang.serialization.Codec;
4+
import java.util.Map;
5+
import java.util.function.Function;
6+
import net.minecraft.core.Registry;
7+
import net.minecraft.resources.ResourceKey;
8+
import org.bukkit.craftbukkit.util.Handleable;
9+
import org.jspecify.annotations.Nullable;
10+
11+
public interface PaperTypedDataCollector<TYPE> {
12+
13+
void registerUntyped(final TYPE type);
14+
15+
<NMS> void registerIdentity(final TYPE type, final Function<TYPE, @Nullable Codec<NMS>> codecGetter);
16+
17+
<NMS, API extends Handleable<NMS>> void register(final TYPE type, final Function<NMS, API> vanillaToApi);
18+
19+
<NMS, API> void register(final TYPE type, final Function<NMS, API> vanillaToApi, final Function<API, NMS> apiToVanilla);
20+
21+
interface Factory<TYPE, COLLECTOR> {
22+
23+
COLLECTOR create(Registry<TYPE> registry, Map<ResourceKey<?>, PaperTypedDataAdapter<?, ?>> adapters);
24+
25+
}
26+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
@NullMarked
2+
package io.papermc.paper.registry.data.typed;
3+
4+
import org.jspecify.annotations.NullMarked;

0 commit comments

Comments
 (0)