Task prep

This commit is contained in:
cyberpwn 2022-06-27 07:26:28 -04:00
parent cc70a30315
commit cbfad43467
6 changed files with 144 additions and 4 deletions

View File

@ -8,9 +8,15 @@ import com.volmit.iris.platform.PlatformNamespaceKey;
import com.volmit.iris.platform.PlatformRegistry;
import com.volmit.iris.platform.PlatformWorld;
import lombok.Data;
import manifold.util.concurrent.ConcurrentWeakHashMap;
import java.lang.ref.WeakReference;
import java.util.Map;
import java.util.Optional;
@Data
public class IrisEngine {
private static final Map<Thread, WeakReference<IrisEngine>> engineContext = new ConcurrentWeakHashMap<>();
private final IrisPlatform platform;
private final EngineRegistry registry;
private final EngineConfiguration configuration;
@ -41,4 +47,16 @@ public class IrisEngine {
{
return getPlatform().key(nsk);
}
public static Optional<IrisEngine> context()
{
WeakReference<IrisEngine> reference = engineContext.get(Thread.currentThread());
if(reference != null)
{
return Optional.ofNullable(reference.get());
}
return Optional.empty();
}
}

View File

@ -7,13 +7,25 @@ import lombok.Data;
@Data
public abstract class IrisFeature<T extends PlatformNamespaced, S extends IrisFeatureState> {
private final String name;
private boolean heightAgnostic;
public IrisFeature(String name, IrisEngine engine)
{
this.name = name;
this.heightAgnostic = true;
}
public abstract S prepare(IrisEngine engine, IrisFeatureSizedTarget target);
public S prepare(IrisEngine engine, IrisFeatureSizedTarget target)
{
return onPrepare(engine, target);
}
public abstract void generate(IrisEngine engine, S state, IrisFeatureTarget<T> target);
public void generate(IrisEngine engine, S state, IrisFeatureTarget<T> target)
{
onGenerate(engine, state, target);
}
public abstract S onPrepare(IrisEngine engine, IrisFeatureSizedTarget target);
public abstract void onGenerate(IrisEngine engine, S state, IrisFeatureTarget<T> target);
}

View File

@ -9,6 +9,9 @@ import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
import java.util.stream.Stream;
@Builder
@NoArgsConstructor
@AllArgsConstructor
@ -27,6 +30,48 @@ public class IrisFeatureSizedTarget {
@Builder.Default
private final int offsetZ = 0;
Stream<IrisFeatureSizedTarget> splitX()
{
if(width <= 1) {
return Stream.of(this);
}
return Stream.of(IrisFeatureSizedTarget.builder()
.width(width/2).height(height).depth(depth)
.offsetX(offsetX).offsetY(offsetY).offsetZ(offsetZ).build(),
IrisFeatureSizedTarget.builder()
.width(width - (width/2)).height(height).depth(depth)
.offsetX(offsetX + (width/2)).offsetY(offsetY).offsetZ(offsetZ).build());
}
Stream<IrisFeatureSizedTarget> splitY()
{
if(height <= 1) {
return Stream.of(this);
}
return Stream.of(IrisFeatureSizedTarget.builder()
.width(width).height(height/2).depth(depth)
.offsetX(offsetX).offsetY(offsetY).offsetZ(offsetZ).build(),
IrisFeatureSizedTarget.builder()
.width(width).height(height - (height / 2)).depth(depth)
.offsetX(offsetX).offsetY(offsetY + (height/2)).offsetZ(offsetZ).build());
}
Stream<IrisFeatureSizedTarget> splitZ()
{
if(depth <= 1) {
return Stream.of(this);
}
return Stream.of(IrisFeatureSizedTarget.builder()
.width(width).height(height).depth(depth/2)
.offsetX(offsetX).offsetY(offsetY).offsetZ(offsetZ).build(),
IrisFeatureSizedTarget.builder()
.width(width).height(height).depth(depth - (depth/2))
.offsetX(offsetX).offsetY(offsetY).offsetZ(offsetZ + (depth/2)).build());
}
public int getAbsoluteMaxX()
{
return getOffsetX() + getWidth() - 1;

View File

@ -0,0 +1,52 @@
package com.volmit.iris.engine.feature;
import com.volmit.iris.engine.IrisEngine;
import com.volmit.iris.platform.PlatformNamespaced;
import lombok.AllArgsConstructor;
import lombok.Builder;
import java.util.concurrent.RecursiveTask;
import java.util.stream.Collectors;
/**
* Continuously splits up a hunk of work in all 3 dimensions until the job size is within the
* specified limits. This allows a single hunk to be split until the ideal amount of tasks can run in parallel.
* @param <T> The namespaced object type
* @param <S> The feature state type
*/
@Builder
@AllArgsConstructor
public class IrisFeatureTask<T extends PlatformNamespaced, S extends IrisFeatureState> extends RecursiveTask<IrisPreparedFeature<T, S>> {
private final IrisEngine engine;
private final IrisFeature<T, S> feature;
private final IrisFeatureSizedTarget size;
private final int verticalPrepareSize;
private final int horizontalPrepareSize;
private final boolean heightAgnostic;
@Override
protected IrisPreparedFeature<T, S> compute() {
if(!heightAgnostic && size.getHeight() > verticalPrepareSize * 2) {
invokeAll(size.splitY().map(this::with).collect(Collectors.toList()));
}
else if(size.getWidth() > horizontalPrepareSize * 2) {
invokeAll(size.splitX().map(this::with).collect(Collectors.toList()));
}
else if(size.getDepth() > horizontalPrepareSize * 2) {
invokeAll(size.splitZ().map(this::with).collect(Collectors.toList()));
}
else {
return new IrisPreparedFeature<>(feature, size, feature.prepare(engine, size));
}
return null;
}
private IrisFeatureTask<T, S> with(IrisFeatureSizedTarget size)
{
return new IrisFeatureTask<>(engine, feature, size, verticalPrepareSize, horizontalPrepareSize, heightAgnostic);
}
}

View File

@ -0,0 +1,13 @@
package com.volmit.iris.engine.feature;
import com.volmit.iris.platform.PlatformNamespaced;
import lombok.Builder;
import lombok.Data;
@Builder
@Data
public class IrisPreparedFeature<T extends PlatformNamespaced, S extends IrisFeatureState> {
private final IrisFeature<T, S> feature;
private final IrisFeatureSizedTarget size;
private final S state;
}

View File

@ -29,7 +29,7 @@ public class FeatureTerrain extends IrisFeature<PlatformBlock, FeatureTerrain.Te
}
@Override
public TerrainFeatureState prepare(IrisEngine engine, IrisFeatureSizedTarget target) {
public TerrainFeatureState onPrepare(IrisEngine engine, IrisFeatureSizedTarget target) {
final ShortNoiseCache noise = new ShortNoiseCache(target.getWidth(), target.getDepth());
int cx,cz;
@ -48,7 +48,7 @@ public class FeatureTerrain extends IrisFeature<PlatformBlock, FeatureTerrain.Te
}
@Override
public void generate(IrisEngine engine, TerrainFeatureState state, IrisFeatureTarget<PlatformBlock> target) {
public void onGenerate(IrisEngine engine, TerrainFeatureState state, IrisFeatureTarget<PlatformBlock> target) {
for(int x : target.localX()) {
for(int z : target.localZ()) {
int h = state.getNoise().get(x, z);