fix ProbabilityCollection map issues

This commit is contained in:
dfsek
2021-03-01 16:43:14 -07:00
parent 1125b498ec
commit 265449c5a7
6 changed files with 70 additions and 34 deletions

View File

@@ -23,6 +23,8 @@ dependencies {
"compileOnly"("com.googlecode.json-simple:json-simple:1.1")
"compileOnly"("com.google.guava:guava:30.0-jre")
"testImplementation"("com.google.guava:guava:30.0-jre")
}
publishing {

View File

@@ -2,25 +2,28 @@ package com.dfsek.terra.api.util.collections;
import com.dfsek.terra.api.math.MathUtil;
import com.dfsek.terra.api.math.noise.NoiseSampler;
import com.dfsek.terra.api.util.mutable.MutableInteger;
import org.jetbrains.annotations.NotNull;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Random;
import java.util.Set;
import java.util.function.Function;
@SuppressWarnings("unchecked")
public class ProbabilityCollection<E> implements Collection<E> {
private final Set<E> cont = new HashSet<>();
protected final Map<E, MutableInteger> cont = new HashMap<>();
private Object[] array = new Object[0];
private int size;
public ProbabilityCollection<E> add(E item, int probability) {
if(!cont.contains(item)) size++;
cont.add(item);
if(!cont.containsKey(item)) size++;
cont.computeIfAbsent(item, i -> new MutableInteger(0)).increment();
int oldLength = array.length;
Object[] newArray = new Object[array.length + probability];
System.arraycopy(array, 0, newArray, 0, array.length); // Expand array.
@@ -59,6 +62,20 @@ public class ProbabilityCollection<E> implements Collection<E> {
return array.length;
}
public int getProbability(E item) {
MutableInteger integer = cont.get(item);
return integer == null ? 0 : integer.get();
}
@Override
public String toString() {
StringBuilder builder = new StringBuilder("[");
cont.forEach((item, prob) -> builder.append(item).append(": ").append(prob).append(", "));
return builder.append("]").toString();
}
@Override
public int size() {
return size;
@@ -71,26 +88,26 @@ public class ProbabilityCollection<E> implements Collection<E> {
@Override
public boolean contains(Object o) {
return cont.contains(o);
return cont.containsKey(o);
}
@NotNull
@Override
public Iterator<E> iterator() {
return cont.iterator();
return cont.keySet().iterator();
}
@NotNull
@Override
public Object[] toArray() {
return cont.toArray();
return cont.keySet().toArray();
}
@SuppressWarnings("SuspiciousToArrayCall")
@NotNull
@Override
public <T> T[] toArray(@NotNull T[] a) {
return cont.toArray(a);
return cont.keySet().toArray(a);
}
/**
@@ -109,7 +126,7 @@ public class ProbabilityCollection<E> implements Collection<E> {
@Override
public boolean containsAll(@NotNull Collection<?> c) {
return cont.containsAll(c);
return cont.keySet().containsAll(c);
}
@Override
@@ -135,7 +152,7 @@ public class ProbabilityCollection<E> implements Collection<E> {
}
public Set<E> getContents() {
return new HashSet<>(cont);
return new HashSet<>(cont.keySet());
}
public static final class Singleton<T> extends ProbabilityCollection<T> {
@@ -143,6 +160,7 @@ public class ProbabilityCollection<E> implements Collection<E> {
public Singleton(T single) {
this.single = single;
cont.put(single, new MutableInteger(1));
}
@Override
@@ -150,6 +168,12 @@ public class ProbabilityCollection<E> implements Collection<E> {
throw new UnsupportedOperationException();
}
@Override
public <T1> ProbabilityCollection<T1> map(Function<T, T1> mapper, boolean carryNull) {
if(carryNull && single == null) return new Singleton<>(null);
return new Singleton<>(mapper.apply(single));
}
@Override
public T get(Random r) {
return single;

View File

@@ -3,11 +3,9 @@ package com.dfsek.terra.api.world.biome;
import com.dfsek.terra.api.platform.world.Biome;
import com.dfsek.terra.api.platform.world.World;
import com.dfsek.terra.api.util.collections.ProbabilityCollection;
import com.dfsek.terra.config.builder.GeneratorBuilder;
import com.dfsek.terra.config.templates.BiomeTemplate;
import com.dfsek.terra.world.generation.WorldGenerator;
import java.util.HashSet;
import java.util.Set;
/**
@@ -65,4 +63,9 @@ public class UserDefinedBiome implements TerraBiome {
public Set<String> getTags() {
return tags;
}
@Override
public String toString() {
return "{BIOME:" + getID() + "}";
}
}

View File

@@ -16,11 +16,14 @@ import com.dfsek.terra.world.generation.WorldGenerator;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
public class UserDefinedBiomeBuilder implements BiomeBuilder {
private final BiomeTemplate template;
private final ConfigPack pack;
private final Map<Long, UserDefinedBiome> biomeMap = new ConcurrentHashMap<>();
public UserDefinedBiomeBuilder(BiomeTemplate template, ConfigPack pack) {
this.template = template;
this.pack = pack;
@@ -28,29 +31,36 @@ public class UserDefinedBiomeBuilder implements BiomeBuilder {
@Override
public UserDefinedBiome apply(Long seed) {
NoiseSampler noise;
NoiseSampler elevation;
NoiseSampler carving;
Scope varScope = new Scope().withParent(pack.getVarScope());
synchronized(biomeMap) {
return biomeMap.computeIfAbsent(seed,
s -> {
NoiseSampler noise;
NoiseSampler elevation;
NoiseSampler carving;
Scope varScope = new Scope().withParent(pack.getVarScope());
template.getVariables().forEach(varScope::create);
template.getVariables().forEach(varScope::create);
System.out.println("Building biome " + template.getID() + " for seed " + s);
Map<String, NoiseSeeded> noiseBuilderMap = pack.getTemplate().getNoiseBuilderMap();
Map<String, FunctionTemplate> functionTemplateMap = new HashMap<>(template.getFunctions());
Map<String, NoiseSeeded> noiseBuilderMap = pack.getTemplate().getNoiseBuilderMap();
Map<String, FunctionTemplate> functionTemplateMap = new HashMap<>(template.getFunctions());
functionTemplateMap.putAll(template.getFunctions());
functionTemplateMap.putAll(template.getFunctions());
try {
noise = new ExpressionSampler(template.getNoiseEquation(), varScope, seed, noiseBuilderMap, functionTemplateMap);
elevation = template.getElevationEquation() == null ? new ConstantSampler(0) : new ExpressionSampler(template.getElevationEquation(), varScope, seed, noiseBuilderMap, functionTemplateMap);
carving = new ExpressionSampler(template.getCarvingEquation(), varScope, seed, noiseBuilderMap, functionTemplateMap);
} catch(ParseException e) {
throw new RuntimeException(e);
try {
noise = new ExpressionSampler(template.getNoiseEquation(), varScope, seed, noiseBuilderMap, functionTemplateMap);
elevation = template.getElevationEquation() == null ? new ConstantSampler(0) : new ExpressionSampler(template.getElevationEquation(), varScope, seed, noiseBuilderMap, functionTemplateMap);
carving = new ExpressionSampler(template.getCarvingEquation(), varScope, seed, noiseBuilderMap, functionTemplateMap);
} catch(ParseException e) {
throw new RuntimeException(e);
}
WorldGenerator generator = new WorldGenerator(template.getPalette(), template.getSlantPalette(), noise, elevation, carving, template.getBiomeNoise().apply(seed), template.getElevationWeight(),
template.getBlendDistance(), template.getBlendStep(), template.getBlendWeight());
return new UserDefinedBiome(template.getVanilla(), generator, template);
}
);
}
WorldGenerator generator = new WorldGenerator(template.getPalette(), template.getSlantPalette(), noise, elevation, carving, template.getBiomeNoise().apply(seed), template.getElevationWeight(),
template.getBlendDistance(), template.getBlendStep(), template.getBlendWeight());
return new UserDefinedBiome(template.getVanilla(), generator, template);
}
@Override

View File

@@ -6,7 +6,6 @@ import com.dfsek.terra.api.world.biome.TerraBiome;
import com.dfsek.terra.api.world.biome.pipeline.mutator.BiomeMutator;
import com.dfsek.terra.api.world.biome.pipeline.mutator.BorderListMutator;
import com.dfsek.terra.config.builder.BiomeBuilder;
import com.dfsek.terra.config.builder.UserDefinedBiomeBuilder;
import java.util.HashMap;
import java.util.Map;
@@ -19,7 +18,7 @@ public class BorderListMutatorTemplate extends MutatorStageTemplate {
private String defaultReplace;
@Value("default-to")
private ProbabilityCollection<UserDefinedBiomeBuilder> defaultTo;
private ProbabilityCollection<BiomeBuilder> defaultTo;
@Value("replace")
private Map<BiomeBuilder, ProbabilityCollection<BiomeBuilder>> replace;
@@ -29,7 +28,7 @@ public class BorderListMutatorTemplate extends MutatorStageTemplate {
public BiomeMutator build(long seed) {
Map<TerraBiome, ProbabilityCollection<TerraBiome>> replaceMap = new HashMap<>();
replace.forEach((biomeBuilder, biomeBuilders) -> replaceMap.put(biomeBuilder.apply(seed), biomeBuilders.map(builder -> builder.apply(seed), true)));
replace.forEach((keyBuilder, replacements) -> replaceMap.put(keyBuilder.apply(seed), replacements.map(replacement -> replacement.apply(seed), true)));
return new BorderListMutator(replaceMap, from, defaultReplace, noise.apply(seed), defaultTo.map(biomeBuilder -> biomeBuilder.apply(seed), true));
}

View File

@@ -33,8 +33,6 @@ dependencies {
"compileOnly"("com.sk89q.worldedit:worldedit-bukkit:7.2.0-SNAPSHOT")
"shadedImplementation"("com.google.guava:guava:30.0-jre")
"testImplementation"("com.google.guava:guava:30.0-jre")
}
val testDir = "target/server/"