Skip to content

Commit

Permalink
Change datapack element parse method
Browse files Browse the repository at this point in the history
  • Loading branch information
dhyces committed Jun 13, 2024
1 parent d9a663c commit 9fb9906
Show file tree
Hide file tree
Showing 6 changed files with 69 additions and 56 deletions.
21 changes: 19 additions & 2 deletions common/src/main/java/dev/dhyces/trimmed/TrimmedClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import dev.dhyces.trimmed.api.client.map.ClientMapKeys;
import dev.dhyces.trimmed.api.client.map.ClientMapTypes;
import dev.dhyces.trimmed.impl.ModApiConsumer;
import dev.dhyces.trimmed.impl.client.GameRegistryHolder;
import dev.dhyces.trimmed.impl.client.TrimmedClientRegistrationImpl;
import dev.dhyces.trimmed.impl.client.atlas.TrimmedSpriteSourceTypes;
import dev.dhyces.trimmed.impl.client.maps.KeyResolvers;
Expand All @@ -20,6 +21,7 @@
import dev.dhyces.trimmed.modhelper.services.Services;
import net.minecraft.client.Minecraft;
import net.minecraft.core.RegistryAccess;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.server.packs.resources.PreparableReloadListener;
import net.minecraft.server.packs.resources.ResourceManager;

Expand All @@ -29,6 +31,16 @@
import java.util.function.BiConsumer;

public class TrimmedClient {
private static GameRegistryHolder staticAccess;
public static GameRegistryHolder getStaticHolder() {
if (staticAccess == null) {
staticAccess = new GameRegistryHolder(RegistryAccess.fromRegistryOfRegistries(BuiltInRegistries.REGISTRY), false);
}
return staticAccess;
}
public static boolean isSyncedAccess() {
return getStaticHolder().isSynced();
}

public static void init() {
KeyResolvers.register(Trimmed.id("texture"), ClientKeyResolvers.TEXTURE);
Expand Down Expand Up @@ -58,15 +70,20 @@ public static void injectListenersAtBeginning() {
}

public static void onTagsSynced(RegistryAccess registryAccess, boolean shouldUpdateStatic) {
staticAccess = new GameRegistryHolder(registryAccess, true);
if (shouldUpdateStatic) { //TODO: Disabled the toast for now. Use toast later when a datapack registry queued
// if (Minecraft.getInstance().player != null) {
// Minecraft.getInstance().getToasts().addToast(InfoToast.reloadClientInfo());
// }
ClientTagManager.updateDatapacksSynced(registryAccess);
ClientMapManager.updateDatapacksSynced(registryAccess);
ClientTagManager.updateDatapacksSynced(staticAccess);
ClientMapManager.updateDatapacksSynced(staticAccess);
}
}

public static void resetSyncedStatus() {
staticAccess = null;
}

public static CompletableFuture<Collection<NamedModel>> startGeneratingModels(ResourceManager resourceManager, Executor executor) {
return ModelTemplateManager.load(resourceManager, executor)
.thenComposeAsync(templateManager -> ModelSourceLoader.load(templateManager, resourceManager, executor));
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package dev.dhyces.trimmed.impl.client;

import net.minecraft.core.RegistryAccess;

public record GameRegistryHolder(RegistryAccess registryAccess, boolean isSynced) {
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@

import com.mojang.serialization.JsonOps;
import dev.dhyces.trimmed.Trimmed;
import dev.dhyces.trimmed.TrimmedClient;
import dev.dhyces.trimmed.api.maps.MapHolder;
import dev.dhyces.trimmed.api.util.Utils;
import dev.dhyces.trimmed.api.maps.MapKey;
import dev.dhyces.trimmed.impl.client.GameRegistryHolder;
import dev.dhyces.trimmed.impl.client.maps.KeyResolvers;
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
import it.unimi.dsi.fastutil.objects.Reference2ObjectOpenHashMap;
Expand All @@ -30,8 +32,6 @@ public class ClientMapManager implements PreparableReloadListener {
public static final String PATH = "trimmed/maps";
private static CompletableFuture<Unit> completable = new CompletableFuture<>();
private static final Map<MapKey<?, ?>, MapHandler<?, ?>> REGISTRY = new Reference2ObjectOpenHashMap<>();
private static RegistryAccess syncedAccess;
private static final List<Consumer<RegistryAccess>> REQUIRE_SYNC = new ObjectArrayList<>();

public static <K, V> void registerBaseKey(MapKey<K, V> key) {
if (key.isSubKey()) {
Expand All @@ -53,11 +53,8 @@ public static CompletableFuture<Unit> future() {
return completable;
}

public static void updateDatapacksSynced(RegistryAccess registryAccess) {
syncedAccess = registryAccess;
for (Consumer<RegistryAccess> consumer : REQUIRE_SYNC) {
consumer.accept(registryAccess);
}
public static void updateDatapacksSynced(GameRegistryHolder registryHolder) {
load(Minecraft.getInstance().getResourceManager(), registryHolder, true);
}

private static void finishReload() {
Expand All @@ -68,28 +65,18 @@ private static void finishReload() {

@Override
public CompletableFuture<Void> reload(PreparationBarrier pPreparationBarrier, ResourceManager pResourceManager, ProfilerFiller pPreparationsProfiler, ProfilerFiller pReloadProfiler, Executor pBackgroundExecutor, Executor pGameExecutor) {
return load(pResourceManager).thenApply(completable::complete).thenCompose(pPreparationBarrier::wait).thenRun(ClientMapManager::finishReload);
}

private CompletableFuture<Unit> load(ResourceManager resourceManager) {
REGISTRY.values().forEach(MapHandler::clear);
REQUIRE_SYNC.clear();
return load(pResourceManager, TrimmedClient.getStaticHolder(), false).thenApply(completable::complete).thenCompose(pPreparationBarrier::wait).thenRun(ClientMapManager::finishReload);
}

private static CompletableFuture<Unit> load(ResourceManager resourceManager, GameRegistryHolder registryHolder, boolean onlyLoadSynced) {
for (Map.Entry<MapKey<?, ?>, MapHandler<?, ?>> entry : REGISTRY.entrySet()) {
ResourceLocation resolverPath = entry.getKey().getMapId().withPrefix("trimmed/maps/" + Utils.namespacedPath(KeyResolvers.getId(entry.getKey().getType().getKeyResolver())) + "/");

FileToIdConverter converter = FileToIdConverter.json(resolverPath.getPath());
try {
if (entry.getKey().getType().isDataPackSynced()) {
REQUIRE_SYNC.add(registryAccess ->
entry.getValue().parse(resolverPath, converter, resourceManager, registryAccess.createSerializationContext(JsonOps.INSTANCE))
);
}

if (!entry.getKey().getType().isDataPackSynced()) {
entry.getValue().parse(resolverPath, converter, resourceManager, JsonOps.INSTANCE);
} else if (syncedAccess != null) {
entry.getValue().parse(resolverPath, converter, resourceManager, syncedAccess.createSerializationContext(JsonOps.INSTANCE));
if (onlyLoadSynced ? entry.getKey().getType().isDataPackSynced() && registryHolder.isSynced() : !entry.getKey().getType().isDataPackSynced() || registryHolder.isSynced()) {
entry.getValue().parse(resolverPath, converter, resourceManager, registryHolder.registryAccess().createSerializationContext(JsonOps.INSTANCE));
}
} catch (RuntimeException e) {
Trimmed.LOGGER.error("Could not read map", e);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,22 +1,26 @@
package dev.dhyces.trimmed.impl.client.tags.manager;

import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParseException;
import com.mojang.serialization.DynamicOps;
import com.mojang.serialization.JsonOps;
import dev.dhyces.trimmed.TrimmedClient;
import dev.dhyces.trimmed.api.client.tag.TagHolder;
import dev.dhyces.trimmed.api.KeyResolver;
import dev.dhyces.trimmed.api.data.client.tag.ClientTagEntry;
import dev.dhyces.trimmed.api.data.client.tag.ClientTagFile;
import dev.dhyces.trimmed.impl.client.GameRegistryHolder;
import dev.dhyces.trimmed.impl.client.maps.KeyResolvers;
import dev.dhyces.trimmed.api.client.tag.ClientTagKey;
import dev.dhyces.trimmed.modhelper.services.Services;
import dev.dhyces.trimmed.Trimmed;
import dev.dhyces.trimmed.api.util.Utils;
import it.unimi.dsi.fastutil.objects.*;
import net.minecraft.client.Minecraft;
import net.minecraft.core.RegistryAccess;
import net.minecraft.resources.FileToIdConverter;
import net.minecraft.resources.ResourceLocation;
Expand All @@ -42,9 +46,6 @@ public class ClientTagManager implements PreparableReloadListener {
public static final String PATH = "trimmed/tags/";
private static final Logger LOGGER = LoggerFactory.getLogger("Trimmed / Client Tags");
private static final Map<ClientTagKey<?>, ClientTagHolder<?>> REGISTRY = new Reference2ObjectOpenHashMap<>();
// TODO: Probably need to make these weak or figure out another solution
private static RegistryAccess syncedAccess;
private static final List<Consumer<RegistryAccess>> REQUIRE_SYNC = new ObjectArrayList<>();

public static <T> TagHolder<T> getHolder(ClientTagKey<T> clientTagKey) {
return getOrCreateHolder(clientTagKey);
Expand All @@ -61,41 +62,30 @@ private static <T> ClientTagHolder<T> getExistingHolder(ClientTagKey<T> clientTa
return (ClientTagHolder<T>) REGISTRY.get(clientTagKey);
}

public static void updateDatapacksSynced(RegistryAccess registryAccess) {
syncedAccess = registryAccess;
for (Consumer<RegistryAccess> consumer : REQUIRE_SYNC) {
consumer.accept(registryAccess);
}
public static void updateDatapacksSynced(GameRegistryHolder registryHolder) {
load(Minecraft.getInstance().getResourceManager(), registryHolder, true);
}

@Override
public CompletableFuture<Void> reload(PreparationBarrier pPreparationBarrier, ResourceManager pResourceManager, ProfilerFiller pPreparationsProfiler, ProfilerFiller pReloadProfiler, Executor pBackgroundExecutor, Executor pGameExecutor) {
return load(pResourceManager).thenCompose(pPreparationBarrier::wait).thenRun(() -> Trimmed.logInDev("Client tags loaded!"));
}

private CompletableFuture<Void> load(ResourceManager resourceManager) {
REGISTRY.values().forEach(ClientTagHolder::reset);
REQUIRE_SYNC.clear();
return load(pResourceManager, TrimmedClient.getStaticHolder(), false).thenCompose(pPreparationBarrier::wait).thenRun(() -> Trimmed.logInDev("Client tags loaded!"));
}

private static CompletableFuture<Void> load(ResourceManager resourceManager, GameRegistryHolder registryHolder, boolean onlyLoadSynced) {
return CompletableFuture.allOf(StreamSupport.stream(KeyResolvers.getEntries().spliterator(), false)
.map(entry -> CompletableFuture.runAsync(() -> {
if (entry.getValue().requiresActiveWorld()) {
REQUIRE_SYNC.add(registryAccess ->
resolveTags(entry.getKey(), entry.getValue(), resourceManager, registryAccess.createSerializationContext(JsonOps.INSTANCE))
);
}

if (!entry.getValue().requiresActiveWorld()) {
resolveTags(entry.getKey(), entry.getValue(), resourceManager, JsonOps.INSTANCE);
} else if (syncedAccess != null) {
resolveTags(entry.getKey(), entry.getValue(), resourceManager, syncedAccess.createSerializationContext(JsonOps.INSTANCE));
// if onlyLoadSynced, only resolveTags if isSynced and requiresActiveWorld
// otherwise, load if not requiresActiveWorld or isSynced
if (onlyLoadSynced ? entry.getValue().requiresActiveWorld() && registryHolder.isSynced() : !entry.getValue().requiresActiveWorld() || registryHolder.isSynced()) {
resolveTags(entry.getKey(), entry.getValue(), resourceManager, registryHolder.registryAccess().createSerializationContext(JsonOps.INSTANCE));
}
}))
.toArray(CompletableFuture[]::new)
);
}

private <T> void resolveTags(ResourceLocation registryId, KeyResolver<T> keyResolver, ResourceManager resourceManager, DynamicOps<JsonElement> jsonOps) {
private static <T> void resolveTags(ResourceLocation registryId, KeyResolver<T> keyResolver, ResourceManager resourceManager, DynamicOps<JsonElement> jsonOps) {
String resolverPath = PATH + Utils.namespacedPath(registryId);
FileToIdConverter converter = FileToIdConverter.json(resolverPath);
Map<ResourceLocation, Set<ClientTagEntry>> unresolved = Utils.unsafeCast(readMap(converter, resourceManager, keyResolver, jsonOps));
Expand All @@ -110,7 +100,7 @@ private <T> void resolveTags(ResourceLocation registryId, KeyResolver<T> keyReso
});
}

private <T> Map<ResourceLocation, Set<ClientTagEntry>> readMap(FileToIdConverter converter, ResourceManager resourceManager, KeyResolver<T> keyResolver, DynamicOps<JsonElement> jsonOps) {
private static <T> Map<ResourceLocation, Set<ClientTagEntry>> readMap(FileToIdConverter converter, ResourceManager resourceManager, KeyResolver<T> keyResolver, DynamicOps<JsonElement> jsonOps) {
ImmutableMap.Builder<ResourceLocation, Set<ClientTagEntry>> builder = ImmutableMap.builder();
for (Map.Entry<ResourceLocation, List<Resource>> entry : converter.listMatchingResourceStacks(resourceManager).entrySet()) {
ResourceLocation id = converter.fileToId(entry.getKey());
Expand All @@ -123,7 +113,7 @@ private <T> Map<ResourceLocation, Set<ClientTagEntry>> readMap(FileToIdConverter
return builder.build();
}

private <T> Set<ClientTagEntry> readResources(ResourceLocation fileName, List<Resource> resourceStack, KeyResolver<T> keyResolver, DynamicOps<JsonElement> jsonOps) {
private static <T> Set<ClientTagEntry> readResources(ResourceLocation fileName, List<Resource> resourceStack, KeyResolver<T> keyResolver, DynamicOps<JsonElement> jsonOps) {
ImmutableSet.Builder<ClientTagEntry> setBuilder = ImmutableSet.builder();
for (Resource resource : resourceStack) {
try (BufferedReader reader = resource.openAsReader()) {
Expand All @@ -145,7 +135,7 @@ private <T> Set<ClientTagEntry> readResources(ResourceLocation fileName, List<Re
return setBuilder.build();
}

private <T> void resolveEntry(ResourceLocation id, TagSetEntry<T> tagSetEntry, KeyResolver<T> resolver, DynamicOps<JsonElement> jsonOps) {
private static <T> void resolveEntry(ResourceLocation id, TagSetEntry<T> tagSetEntry, KeyResolver<T> resolver, DynamicOps<JsonElement> jsonOps) {
ClientTagKey<T> key = ClientTagKey.of(resolver, id);
Set<T> set;
Set<T> optionalSet;
Expand Down
10 changes: 5 additions & 5 deletions fabric/src/main/java/dev/dhyces/trimmed/FabricTrimmedClient.java
Original file line number Diff line number Diff line change
@@ -1,18 +1,15 @@
package dev.dhyces.trimmed;

import dev.dhyces.trimmed.api.client.TrimmedClientApiEntrypoint;
import dev.dhyces.trimmed.impl.ModelBakeryHelper;
import dev.dhyces.trimmed.impl.client.models.source.ModelSourceLoader;
import dev.dhyces.trimmed.impl.client.models.source.NamedModel;
import dev.dhyces.trimmed.impl.client.models.template.ModelTemplateManager;
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
import net.fabricmc.api.ClientModInitializer;
import net.fabricmc.fabric.api.client.model.loading.v1.PreparableModelLoadingPlugin;
import net.fabricmc.fabric.api.client.networking.v1.ClientPlayConnectionEvents;
import net.fabricmc.fabric.api.event.lifecycle.v1.CommonLifecycleEvents;
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents;
import net.fabricmc.fabric.api.resource.IdentifiableResourceReloadListener;
import net.fabricmc.fabric.api.resource.ResourceManagerHelper;
import net.fabricmc.loader.api.FabricLoader;
import net.minecraft.client.renderer.block.model.BlockModel;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.packs.PackType;
import net.minecraft.server.packs.resources.PreparableReloadListener;
Expand Down Expand Up @@ -49,6 +46,9 @@ public void onInitializeClient() {
});
});

ServerLifecycleEvents.SERVER_STOPPING.register(server -> TrimmedClient.resetSyncedStatus());
ClientPlayConnectionEvents.DISCONNECT.register((handler, client) -> TrimmedClient.resetSyncedStatus());

CommonLifecycleEvents.TAGS_LOADED.register(TrimmedClient::onTagsSynced);

TrimmedClient.initApi();
Expand Down
13 changes: 13 additions & 0 deletions neo/src/main/java/dev/dhyces/trimmed/NeoTrimmedClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,13 @@
import net.neoforged.bus.api.IEventBus;
import net.neoforged.fml.ModContainer;
import net.neoforged.fml.common.Mod;
import net.neoforged.neoforge.client.event.ClientPlayerNetworkEvent;
import net.neoforged.neoforge.client.event.ModelEvent;
import net.neoforged.neoforge.client.event.RegisterClientReloadListenersEvent;
import net.neoforged.neoforge.common.NeoForge;
import net.neoforged.neoforge.event.TagsUpdatedEvent;
import net.neoforged.neoforge.event.server.ServerStoppingEvent;

import java.util.Set;

@SuppressWarnings("unused")
Expand All @@ -22,6 +25,8 @@ public NeoTrimmedClient(IEventBus modBus, ModContainer container) {
modBus.addListener(this::addModels);

NeoForge.EVENT_BUS.addListener(this::tagsSynced);
NeoForge.EVENT_BUS.addListener(this::onShutdown);
NeoForge.EVENT_BUS.addListener(this::onLogout);

TrimmedClient.initApi();
}
Expand All @@ -39,6 +44,14 @@ private void tagsSynced(final TagsUpdatedEvent event) {
TrimmedClient.onTagsSynced(event.getRegistryAccess(), event.shouldUpdateStaticData());
}

private void onShutdown(final ServerStoppingEvent event) {
TrimmedClient.resetSyncedStatus();
}

private void onLogout(final ClientPlayerNetworkEvent.LoggingOut event) {
TrimmedClient.resetSyncedStatus();
}

public static void setModels(Set<ResourceLocation> models) {
additionalGeneratedModels = models;
}
Expand Down

0 comments on commit 9fb9906

Please sign in to comment.