mirror of
https://github.com/MinecraftForge/MinecraftForge.git
synced 2026-11-12 08:17:35 +00:00
Fix crash when reloading a world that uses custom placed features. Closes #9979
This commit is contained in:
1 parent
7c36115e3d
commit
95b49bedbc
8 files changed
+236
-1
No files matched your search
@@ -0,0 +1,88 @@
|
||||
package net.minecraftforge.common.util;
|
||||
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public interface ClearableLazy<T> extends Lazy<T> {
|
||||
void invalidate();
|
||||
|
||||
/**
|
||||
* Constructs a lazy-initialized object
|
||||
* @param supplier The supplier for the value, to be called the first time the value is needed.
|
||||
*/
|
||||
static <T> ClearableLazy<T> of(@NotNull Supplier<T> supplier) {
|
||||
return new ClearableLazy.Fast<T>(supplier);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a thread-safe lazy-initialized object
|
||||
* @param supplier The supplier for the value, to be called the first time the value is needed.
|
||||
*/
|
||||
static <T> ClearableLazy<T> concurrentOf(@NotNull Supplier<T> supplier) {
|
||||
return new ClearableLazy.Concurrent<>(supplier);
|
||||
}
|
||||
|
||||
/**
|
||||
* Non-thread-safe implementation.
|
||||
*/
|
||||
final class Fast<T> implements ClearableLazy<T> {
|
||||
private final Supplier<T> supplier;
|
||||
private T instance;
|
||||
|
||||
private Fast(Supplier<T> supplier) {
|
||||
this.supplier = supplier;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public final T get() {
|
||||
if (instance == null) {
|
||||
instance = supplier.get();
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void invalidate() {
|
||||
this.instance = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Thread-safe implementation.
|
||||
*/
|
||||
final class Concurrent<T> implements ClearableLazy<T> {
|
||||
private final Object lock = new Object();
|
||||
private final Supplier<T> supplier;
|
||||
private volatile T instance;
|
||||
|
||||
private Concurrent(Supplier<T> supplier) {
|
||||
this.supplier = supplier;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public final T get()
|
||||
{
|
||||
var ret = instance;
|
||||
if (ret == null) {
|
||||
synchronized (lock) {
|
||||
if (instance == null) {
|
||||
return instance = supplier.get();
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void invalidate() {
|
||||
synchronized (lock) {
|
||||
this.instance = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -132,6 +132,10 @@ public class ServerLifecycleHooks {
|
||||
registries.registryOrThrow(Registries.BIOME).holders().forEach(biomeHolder ->
|
||||
biomeHolder.value().modifiableBiomeInfo().applyBiomeModifiers(biomeHolder, biomeModifiers)
|
||||
);
|
||||
// Rebuild the indexed feature list
|
||||
registries.registryOrThrow(Registries.LEVEL_STEM).forEach(levelStem -> {
|
||||
levelStem.generator().refreshFeaturesPerStep();
|
||||
});
|
||||
// Apply sorted structure modifiers to each structure.
|
||||
registries.registryOrThrow(Registries.STRUCTURE).holders().forEach(structureHolder ->
|
||||
structureHolder.value().modifiableStructureInfo().applyStructureModifiers(structureHolder, structureModifiers)
|
||||
|
||||
Reference in new issue
Block a user