Skip to content

Commit 8723559

Browse files
committed
Avoid reentrant resource generation
1 parent 92eb922 commit 8723559

File tree

5 files changed

+102
-23
lines changed

5 files changed

+102
-23
lines changed

common/src/main/java/dev/lukebemish/dynamicassetgenerator/impl/GeneratedPackResources.java

+39-15
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
package dev.lukebemish.dynamicassetgenerator.impl;
77

88
import dev.lukebemish.dynamicassetgenerator.api.ResourceCache;
9+
import dev.lukebemish.dynamicassetgenerator.impl.util.ReentryDetector;
910
import net.minecraft.resources.ResourceLocation;
1011
import net.minecraft.server.packs.PackResources;
1112
import net.minecraft.server.packs.PackType;
@@ -22,7 +23,7 @@
2223
public class GeneratedPackResources implements PackResources {
2324

2425
private final ResourceCache cache;
25-
private Map<ResourceLocation, IoSupplier<InputStream>> streams;
26+
private @Nullable Map<ResourceLocation, IoSupplier<InputStream>> streams;
2627

2728
public GeneratedPackResources(ResourceCache cache) {
2829
this.cache = cache;
@@ -50,34 +51,49 @@ public IoSupplier<InputStream> getRootResource(String @NonNull ... strings) {
5051
@Nullable
5152
@Override
5253
public IoSupplier<InputStream> getResource(@NonNull PackType packType, @NonNull ResourceLocation location) {
53-
if (packType == cache.getPackType()) {
54-
if (getStreams().containsKey(location)) {
55-
return getStreams().get(location);
54+
try (var lock = getResourceDetector.reentrant(new GetResource(packType, location))) {
55+
if (lock.reentrant()) {
56+
return null;
5657
}
58+
if (packType == cache.getPackType()) {
59+
if (getStreams().containsKey(location)) {
60+
return getStreams().get(location);
61+
}
62+
}
63+
return null;
5764
}
58-
return null;
5965
}
6066

6167
@Override
6268
public void listResources(@NonNull PackType packType, @NonNull String namespace, @NonNull String directory, @NonNull ResourceOutput resourceOutput) {
63-
if (packType == cache.getPackType()) {
64-
for (ResourceLocation key : getStreams().keySet()) {
65-
if (key.getPath().startsWith(directory) && key.getNamespace().equals(namespace) && getStreams().get(key) != null) {
66-
resourceOutput.accept(key, getStreams().get(key));
69+
try (var lock = listResourcesDetector.reentrant(new ListResources(packType, namespace, directory))) {
70+
if (lock.reentrant()) {
71+
return;
72+
}
73+
if (packType == cache.getPackType()) {
74+
for (ResourceLocation key : getStreams().keySet()) {
75+
if (key.getPath().startsWith(directory) && key.getNamespace().equals(namespace) && getStreams().get(key) != null) {
76+
resourceOutput.accept(key, getStreams().get(key));
77+
}
6778
}
6879
}
6980
}
7081
}
7182

7283
@Override
7384
public @NonNull Set<String> getNamespaces(@NonNull PackType type) {
74-
Set<String> namespaces = new HashSet<>();
75-
if (type == cache.getPackType()) {
76-
for (ResourceLocation key : getStreams().keySet()) {
77-
namespaces.add(key.getNamespace());
85+
try (var lock = getNamespacesDetector.reentrant(type)) {
86+
if (lock.reentrant()) {
87+
return Set.of();
7888
}
89+
Set<String> namespaces = new HashSet<>();
90+
if (type == cache.getPackType()) {
91+
for (ResourceLocation key : getStreams().keySet()) {
92+
namespaces.add(key.getNamespace());
93+
}
94+
}
95+
return namespaces;
7996
}
80-
return namespaces;
8197
}
8298

8399
@SuppressWarnings("unchecked")
@@ -92,11 +108,19 @@ public <T> T getMetadataSection(MetadataSectionSerializer<T> deserializer) {
92108

93109
@Override
94110
public @NonNull String packId() {
95-
return DynamicAssetGenerator.MOD_ID+'/'+cache.getName().toString();
111+
return DynamicAssetGenerator.MOD_ID + '/' + cache.getName();
96112
}
97113

98114
@Override
99115
public void close() {
100116

101117
}
118+
119+
private record GetResource(@NonNull PackType packType, @NonNull ResourceLocation location) {}
120+
private final ReentryDetector<GetResource> getResourceDetector = new ReentryDetector<>();
121+
122+
private record ListResources(@NonNull PackType packType, @NonNull String namespace, @NonNull String directory) {}
123+
private final ReentryDetector<ListResources> listResourcesDetector = new ReentryDetector<>();
124+
125+
private final ReentryDetector<PackType> getNamespacesDetector = new ReentryDetector<>();
102126
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
/*
2+
* Copyright (C) 2023 Luke Bemish and contributors
3+
* SPDX-License-Identifier: LGPL-3.0-or-later
4+
*/
5+
6+
package dev.lukebemish.dynamicassetgenerator.impl.util;
7+
8+
import java.util.HashSet;
9+
import java.util.Set;
10+
11+
public class ReentryDetector<T> {
12+
private final ThreadLocal<Set<T>> threadLocal = ThreadLocal.withInitial(HashSet::new);
13+
14+
public Lock reentrant(T value) {
15+
var reentrant = !threadLocal.get().add(value);
16+
return new Lock(reentrant);
17+
}
18+
19+
public class Lock implements AutoCloseable {
20+
private final boolean reentrant;
21+
22+
public Lock(boolean reentrant) {
23+
this.reentrant = reentrant;
24+
}
25+
26+
public boolean reentrant() {
27+
return reentrant;
28+
}
29+
30+
@Override
31+
public void close(){
32+
threadLocal.get().clear();
33+
}
34+
}
35+
}

common/src/main/resources/mods.groovy

+24
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
1+
/*
2+
* Copyright (C) 2023 Luke Bemish and contributors
3+
* SPDX-License-Identifier: LGPL-3.0-or-later
4+
*/
5+
6+
import modsdotgroovy.Dependency
7+
18
/*
29
* Copyright (C) 2022-2023 Luke Bemish and contributors
310
* SPDX-License-Identifier: LGPL-3.0-or-later
@@ -39,6 +46,23 @@ ModsDotGroovy.make {
3946
}
4047
}
4148

49+
dependencies = dependencies.collect {dep ->
50+
new Dependency() {
51+
@Override
52+
Map asForgeMap() {
53+
def map = super.asForgeMap()
54+
map.remove('mandatory')
55+
map.put('type', this.mandatory ? 'required' : 'optional')
56+
}
57+
}.tap {
58+
it.modId = dep.modId
59+
it.mandatory = dep.mandatory
60+
it.versionRange = dep.versionRange
61+
it.ordering = dep.ordering
62+
it.side = dep.side
63+
}
64+
}
65+
4266
entrypoints {
4367
onFabric {
4468
entrypoint 'client', ['dev.lukebemish.dynamicassetgenerator.impl.fabriquilt.fabric.DynamicAssetGeneratorClientFabric']

neoforge/src/main/java/dev/lukebemish/dynamicassetgenerator/impl/neoforge/DynamicAssetGeneratorNeoForge.java

+3-5
Original file line numberDiff line numberDiff line change
@@ -10,20 +10,18 @@
1010
import net.neoforged.api.distmarker.Dist;
1111
import net.neoforged.bus.api.IEventBus;
1212
import net.neoforged.fml.common.Mod;
13-
import net.neoforged.fml.javafmlmod.FMLJavaModLoadingContext;
1413
import net.neoforged.fml.loading.FMLEnvironment;
1514

1615
@Mod(DynamicAssetGenerator.MOD_ID)
1716
public class DynamicAssetGeneratorNeoForge {
18-
public DynamicAssetGeneratorNeoForge() {
19-
IEventBus modbus = FMLJavaModLoadingContext.get().getModEventBus();
17+
public DynamicAssetGeneratorNeoForge(IEventBus modBus) {
2018
DynamicAssetGenerator.init();
2119
if (FMLEnvironment.dist == Dist.CLIENT) {
2220
DynamicAssetGeneratorClient.init();
2321
}
2422
if (FMLEnvironment.dist == Dist.CLIENT) {
25-
modbus.addListener(PlatformClientImpl::reloadListenerListener);
23+
modBus.addListener(PlatformClientImpl::reloadListenerListener);
2624
}
27-
modbus.addListener(EventHandler::addResourcePack);
25+
modBus.addListener(EventHandler::addResourcePack);
2826
}
2927
}

neoforge/src/main/java/dev/lukebemish/dynamicassetgenerator/impl/neoforge/EventHandler.java

+1-3
Original file line numberDiff line numberDiff line change
@@ -29,15 +29,13 @@ public static void addResourcePack(AddPackFindersEvent event) {
2929
var metadata = DynamicAssetGenerator.fromCache(info.cache());
3030
var packInfo = new Pack.Info(
3131
metadata.description(),
32-
metadata.packFormat(PackType.SERVER_DATA),
33-
metadata.packFormat(PackType.CLIENT_RESOURCES),
3432
PackCompatibility.COMPATIBLE,
3533
FeatureFlagSet.of(),
3634
List.of(),
3735
true
3836
);
3937
Pack pack = Pack.create(
40-
DynamicAssetGenerator.MOD_ID + ':' + info.cache().getName().toString(),
38+
DynamicAssetGenerator.MOD_ID + ':' + info.cache().getName(),
4139
Component.literal(info.cache().getName().toString()),
4240
true,
4341
new Pack.ResourcesSupplier() {

0 commit comments

Comments
 (0)