Skip to content

Commit

Permalink
feat(registry): metatag datagen provider
Browse files Browse the repository at this point in the history
  • Loading branch information
CallMeEchoCodes committed Oct 10, 2024
1 parent e283669 commit 9015731
Show file tree
Hide file tree
Showing 4 changed files with 111 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@
import com.mojang.serialization.Codec;
import com.mojang.serialization.JsonOps;
import dev.spiritstudios.specter.api.registry.metatag.Metatag;
import dev.spiritstudios.specter.api.registry.metatag.data.MetatagResource;
import dev.spiritstudios.specter.impl.registry.metatag.MetatagHolder;
import dev.spiritstudios.specter.impl.registry.metatag.data.MetatagResource;
import net.minecraft.command.CommandSource;
import net.minecraft.command.argument.IdentifierArgumentType;
import net.minecraft.registry.Registries;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package dev.spiritstudios.specter.impl.registry.metatag.data;
package dev.spiritstudios.specter.api.registry.metatag.data;

import com.mojang.datafixers.util.Pair;
import com.mojang.serialization.Codec;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
package dev.spiritstudios.specter.api.registry.metatag.datagen;

import com.google.gson.JsonElement;
import com.mojang.datafixers.util.Pair;
import com.mojang.serialization.Codec;
import com.mojang.serialization.DynamicOps;
import com.mojang.serialization.JsonOps;
import dev.spiritstudios.specter.api.registry.metatag.Metatag;
import dev.spiritstudios.specter.api.registry.metatag.data.MetatagResource;
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
import net.fabricmc.fabric.api.datagen.v1.FabricDataOutput;
import net.minecraft.data.DataOutput;
import net.minecraft.data.DataProvider;
import net.minecraft.data.DataWriter;
import net.minecraft.registry.RegistryOps;
import net.minecraft.registry.RegistryWrapper;
import net.minecraft.util.Identifier;

import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.CompletableFuture;
import java.util.function.Consumer;

public abstract class MetatagProvider<R> implements DataProvider {
protected final CompletableFuture<RegistryWrapper.WrapperLookup> registriesFuture;
protected final FabricDataOutput dataOutput;
protected final DataOutput.OutputType outputType;

protected MetatagProvider(FabricDataOutput dataOutput, CompletableFuture<RegistryWrapper.WrapperLookup> registriesFuture, DataOutput.OutputType outputType) {
this.dataOutput = dataOutput;
this.registriesFuture = registriesFuture;
this.outputType = outputType;
}

@Override
public CompletableFuture<?> run(DataWriter writer) {
return this.registriesFuture.thenCompose(lookup -> {
DataOutput.PathResolver pathResolver = dataOutput.getResolver(outputType, "metatags");
DynamicOps<JsonElement> ops = RegistryOps.of(JsonOps.INSTANCE, lookup);

List<MetatagBuilder<R, ?>> metatags = new ArrayList<>();
configure(metatags::add, lookup);

return CompletableFuture.allOf(metatags.stream()
.map(builder -> generate(builder, pathResolver, writer, ops))
.toArray(CompletableFuture[]::new));
});
}

private <V> CompletableFuture<?> generate(MetatagBuilder<R, V> builder, DataOutput.PathResolver pathResolver, DataWriter writer, DynamicOps<JsonElement> ops) {
return CompletableFuture.supplyAsync(() -> {
Codec<MetatagResource<V>> resourceCodec = MetatagResource.resourceCodecOf(builder.metatag);
return resourceCodec.encodeStart(ops, builder.build())
.getOrThrow(error -> {
throw new IllegalStateException("Failed to encode metatag resource: " + error);
});
}).thenComposeAsync(encoded -> {
Identifier registryId = builder.metatag.getRegistry().getKey().getValue();
Path metatagPath = pathResolver.resolveJson(builder.metatag.getId().withPrefixedPath(registryId.getNamespace() + "/" + registryId.getPath() + "/"));

return DataProvider.writeToPath(writer, encoded, metatagPath);
});
}

protected abstract void configure(Consumer<MetatagBuilder<R, ?>> provider, RegistryWrapper.WrapperLookup lookup);

protected final <V> MetatagBuilder<R, V> create(Metatag<R, V> metatag) {
return new MetatagBuilder<>(metatag, false);
}

protected final <V> MetatagBuilder<R, V> create(Metatag<R, V> metatag, boolean replace) {
return new MetatagBuilder<>(metatag, replace);
}

@Override
public String getName() {
return "Metatags";
}

protected static final class MetatagBuilder<R, V> {
private final Metatag<R, V> metatag;
private final Map<R, V> values = new Object2ObjectOpenHashMap<>();
private final boolean replace;

private MetatagBuilder(Metatag<R, V> metatag, boolean replace) {
this.metatag = metatag;
this.replace = replace;
}

public MetatagBuilder<R, V> put(R value, V metatagValue) {
this.values.put(value, metatagValue);
return this;
}

private MetatagResource<V> build() {
return new MetatagResource<>(
replace,
values.entrySet().stream()
.map(entry -> Pair.of(metatag.getRegistry().getId(entry.getKey()), entry.getValue()))
.filter(pair -> Objects.nonNull(pair.getFirst()))
.toList()
);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import com.mojang.serialization.Codec;
import com.mojang.serialization.JsonOps;
import dev.spiritstudios.specter.api.registry.metatag.Metatag;
import dev.spiritstudios.specter.api.registry.metatag.data.MetatagResource;
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
import net.minecraft.registry.Registry;
import net.minecraft.resource.Resource;
Expand Down

0 comments on commit 9015731

Please sign in to comment.