still causes massive loadage if requested more than 2 chunks. Don't really know why. WIP I guess
This commit is contained in:
1 parent
e549c4df64
commit
f43bd968bb
4 files changed
+158
-48
No files matched your search
@@ -2,7 +2,9 @@ package carpet.fakes;
|
||||
|
||||
import net.minecraft.util.math.ChunkPos;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface ThreadedAnvilChunkStorageInterface
|
||||
{
|
||||
void regenerateChunkRegion(ChunkPos from, ChunkPos to);
|
||||
void regenerateChunkRegion(List<ChunkPos> requestedChunks);
|
||||
}
|
||||
+56
-35
@@ -26,8 +26,12 @@ import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Queue;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
|
||||
@@ -82,15 +86,8 @@ public abstract class ThreadedAnvilChunkStorage_scarpetChunkCreationMixin implem
|
||||
}
|
||||
|
||||
@Override
|
||||
public void regenerateChunkRegion(ChunkPos from, ChunkPos to)
|
||||
public void regenerateChunkRegion(List<ChunkPos> requestedChunks)
|
||||
{
|
||||
List<ChunkPos> chunksToConvert = new ArrayList<>();
|
||||
int xmax = Math.max(from.x, to.x);
|
||||
int zmax = Math.max(from.z, to.z);
|
||||
for (int x = Math.min(from.x, to.x); x <= xmax; x++) for (int z = Math.min(from.z, to.z); z <= zmax; z++)
|
||||
{
|
||||
chunksToConvert.add(new ChunkPos(x,z));
|
||||
}
|
||||
|
||||
//flushning all tasks on the thread executor so all futures are ready - we don't want any deadlocks
|
||||
mainThreadExecutor.runTasks(() -> mainThreadExecutor.getTaskCount() == 0);
|
||||
@@ -101,8 +98,30 @@ public abstract class ThreadedAnvilChunkStorage_scarpetChunkCreationMixin implem
|
||||
runnable.run();
|
||||
}
|
||||
|
||||
List<ChunkHolder> createdChunks = new ArrayList<>();
|
||||
for (ChunkPos chpos : chunksToConvert)
|
||||
Set<ChunkPos> loadedChunks = new HashSet<>();
|
||||
for (ChunkPos pos: requestedChunks)
|
||||
{
|
||||
Chunk chunk = world.getChunk(pos.x, pos.z, ChunkStatus.FULL, false);
|
||||
if (chunk != null && chunk.getStatus() != ChunkStatus.EMPTY)
|
||||
loadedChunks.add(pos);
|
||||
}
|
||||
CarpetSettings.LOG.error("Area has "+requestedChunks.size()+" chunks");
|
||||
CarpetSettings.LOG.error("Area has "+loadedChunks.size()+" loaded chunks");
|
||||
|
||||
Map<ChunkPos,ChunkStatus> targetStatus = new HashMap<>();
|
||||
for (ChunkPos pos: requestedChunks)
|
||||
{
|
||||
|
||||
Chunk chunk = world.getChunk(pos.x, pos.z, ChunkStatus.EMPTY, true);
|
||||
if (chunk == null || chunk.getStatus() == ChunkStatus.EMPTY)
|
||||
continue;
|
||||
//unloaded areas can have unknown skirt chunk area
|
||||
targetStatus.put(pos, loadedChunks.contains(pos)?chunk.getStatus():ChunkStatus.STRUCTURE_STARTS);
|
||||
}
|
||||
CarpetSettings.LOG.error("Area has "+targetStatus.size()+" chunks for removal");
|
||||
|
||||
|
||||
for (ChunkPos chpos : targetStatus.keySet())
|
||||
{
|
||||
Long id = chpos.toLong();
|
||||
//chunk is currently in memory in some shape or form / loaded / unloaded / queued / cached
|
||||
@@ -147,7 +166,6 @@ public abstract class ThreadedAnvilChunkStorage_scarpetChunkCreationMixin implem
|
||||
field_18807.put(id, newHolder);
|
||||
//loadedChunks.add(id);
|
||||
((ChunkHolderInterface)newHolder).setDefaultProtoChunk(chpos, mainThreadExecutor);
|
||||
createdChunks.add(newHolder);
|
||||
}
|
||||
//getting rid of all signs
|
||||
this.chunkHolderListDirty = true;
|
||||
@@ -161,32 +179,35 @@ public abstract class ThreadedAnvilChunkStorage_scarpetChunkCreationMixin implem
|
||||
runnable.run();
|
||||
}
|
||||
|
||||
for (ChunkStatus status : ChunkStatus.createOrderedList())
|
||||
for (ChunkStatus status : ChunkStatus.createOrderedList())
|
||||
{
|
||||
CarpetSettings.LOG.error("Creating layer: " + status.getId() + " for "+targetStatus.size()+" chunks");
|
||||
if (status == ChunkStatus.LIGHT)
|
||||
{
|
||||
CarpetSettings.LOG.error("Creating layer: " + status.getId());
|
||||
if (status == ChunkStatus.LIGHT)
|
||||
{
|
||||
serverLightingProvider.setTaskBatchSize(chunksToConvert.size() + 20);
|
||||
}
|
||||
for (ChunkPos chpos : chunksToConvert)
|
||||
{
|
||||
//if (status==ChunkStatus.LIGHT)
|
||||
//{
|
||||
// serverLightingProvider.tick();
|
||||
//}
|
||||
//CarpetSettings.LOG.error("Creating layer: " + status.getId());
|
||||
world.getChunk(chpos.x, chpos.z, status);
|
||||
//CarpetSettings.LOG.error(" .. done");
|
||||
//if (status==ChunkStatus.LIGHT)
|
||||
//{
|
||||
// serverLightingProvider.tick();
|
||||
//}
|
||||
}
|
||||
if (status == ChunkStatus.LIGHT)
|
||||
{
|
||||
serverLightingProvider.setTaskBatchSize(5);
|
||||
}
|
||||
//break;
|
||||
serverLightingProvider.setTaskBatchSize(targetStatus.size() + 20);
|
||||
}
|
||||
for (ChunkPos chpos : new ArrayList<>(targetStatus.keySet()))
|
||||
{
|
||||
if (targetStatus.get(chpos) == status)
|
||||
targetStatus.remove(chpos);
|
||||
//if (status==ChunkStatus.LIGHT)
|
||||
//{
|
||||
// serverLightingProvider.tick();
|
||||
//}
|
||||
//CarpetSettings.LOG.error("Creating layer: " + status.getId());
|
||||
world.getChunk(chpos.x, chpos.z, status);
|
||||
//CarpetSettings.LOG.error(" .. done");
|
||||
//if (status==ChunkStatus.LIGHT)
|
||||
//{
|
||||
// serverLightingProvider.tick();
|
||||
//}
|
||||
}
|
||||
if (status == ChunkStatus.LIGHT)
|
||||
{
|
||||
serverLightingProvider.setTaskBatchSize(5);
|
||||
}
|
||||
}
|
||||
|
||||
mainThreadExecutor.runTasks(() -> mainThreadExecutor.getTaskCount() == 0);
|
||||
//worldgenExecutor.
|
||||
|
||||
@@ -1677,23 +1677,60 @@ public class CarpetExpression
|
||||
this.expr.addLazyFunction("reset_chunk", -1, (c, t, lv) ->
|
||||
{
|
||||
CarpetContext cc = (CarpetContext)c;
|
||||
BlockValue.LocatorResult locator = BlockValue.fromParams(cc, lv, 0);
|
||||
List<ChunkPos> requestedChunks = new ArrayList<>();
|
||||
if (lv.size() == 1)
|
||||
{
|
||||
//either one block or list of chunks
|
||||
Value first = lv.get(0).evalValue(c);
|
||||
if (first instanceof ListValue)
|
||||
{
|
||||
List<Value> listVal = ((ListValue) first).getItems();
|
||||
int offset = 0;
|
||||
BlockValue.LocatorResult locator = BlockValue.fromParamValues(cc, listVal, 0, false, false);
|
||||
requestedChunks.add(new ChunkPos(locator.block.getPos()));
|
||||
while (listVal.size() > locator.offset)
|
||||
{
|
||||
locator = BlockValue.fromParamValues(cc, listVal, locator.offset, false, false);
|
||||
requestedChunks.add(new ChunkPos(locator.block.getPos()));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
BlockValue.LocatorResult locator = BlockValue.fromParamValues(cc, Collections.singletonList(first), 0, false, false);
|
||||
requestedChunks.add(new ChunkPos(locator.block.getPos()));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
BlockValue.LocatorResult locator = BlockValue.fromParams(cc, lv, 0);
|
||||
ChunkPos from = new ChunkPos(locator.block.getPos());
|
||||
if (lv.size() > locator.offset)
|
||||
{
|
||||
locator = BlockValue.fromParams(cc, lv, locator.offset);
|
||||
ChunkPos to = new ChunkPos(locator.block.getPos());
|
||||
int xmax = Math.max(from.x, to.x);
|
||||
int zmax = Math.max(from.z, to.z);
|
||||
for (int x = Math.min(from.x, to.x); x <= xmax; x++) for (int z = Math.min(from.z, to.z); z <= zmax; z++)
|
||||
{
|
||||
requestedChunks.add(new ChunkPos(x,z));
|
||||
}
|
||||
CarpetSettings.LOG.error("Regenerating from "+Math.min(from.x, to.x)+", "+Math.min(from.z, to.z)+" to "+Math.max(from.x, to.x)+", "+Math.max(from.z, to.z));
|
||||
}
|
||||
else
|
||||
{
|
||||
requestedChunks.add(from);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ServerWorld world = cc.s.getWorld();
|
||||
BlockPos pos = locator.block.getPos();
|
||||
BlockPos temp = pos;
|
||||
if (lv.size() > locator.offset )
|
||||
{
|
||||
BlockValue.LocatorResult locator2 = BlockValue.fromParams(cc, lv, locator.offset);
|
||||
temp = locator2.block.getPos();
|
||||
}
|
||||
BlockPos toPos = temp;
|
||||
|
||||
((CarpetContext)c).s.getMinecraftServer().submitAndJoin( () ->
|
||||
{
|
||||
((ThreadedAnvilChunkStorageInterface) world.getChunkManager().threadedAnvilChunkStorage).regenerateChunkRegion(new ChunkPos(pos), new ChunkPos(toPos));
|
||||
world.getChunk(pos);
|
||||
this.forceChunkUpdate(pos, world);
|
||||
((ThreadedAnvilChunkStorageInterface) world.getChunkManager().threadedAnvilChunkStorage).regenerateChunkRegion(requestedChunks);
|
||||
for (ChunkPos chpos: requestedChunks)
|
||||
if (world.getChunk(chpos.x, chpos.z, ChunkStatus.FULL, false) != null)
|
||||
this.forceChunkUpdate(chpos.getCenterBlockPos(), world);
|
||||
});
|
||||
return LazyValue.NULL;
|
||||
});
|
||||
|
||||
@@ -188,6 +188,56 @@ public class BlockValue extends Value
|
||||
}
|
||||
}
|
||||
|
||||
public static LocatorResult fromParamValues(CarpetContext c, List<Value> params, int offset, boolean acceptString, boolean optional)
|
||||
{
|
||||
try
|
||||
{
|
||||
Value v1 = params.get(0 + offset);
|
||||
//add conditional from string name
|
||||
if (optional && v1 instanceof NullValue)
|
||||
{
|
||||
return new LocatorResult(null, 1+offset);
|
||||
}
|
||||
if (acceptString && v1 instanceof StringValue)
|
||||
{
|
||||
return new LocatorResult(fromString(v1.getString()), 1+offset);
|
||||
}
|
||||
if (v1 instanceof BlockValue)
|
||||
{
|
||||
return new LocatorResult(((BlockValue) v1), 1+offset);
|
||||
}
|
||||
if (v1 instanceof ListValue)
|
||||
{
|
||||
List<Value> args = ((ListValue) v1).getItems();
|
||||
int xpos = (int) NumericValue.asNumber(args.get(0)).getLong();
|
||||
int ypos = (int) NumericValue.asNumber(args.get(1)).getLong();
|
||||
int zpos = (int) NumericValue.asNumber(args.get(2)).getLong();
|
||||
return new LocatorResult(
|
||||
new BlockValue(
|
||||
null,
|
||||
c.s.getWorld(),
|
||||
new BlockPos(c.origin.getX() + xpos, c.origin.getY() + ypos, c.origin.getZ() + zpos)
|
||||
),
|
||||
1+offset);
|
||||
}
|
||||
int xpos = (int) NumericValue.asNumber(v1).getLong();
|
||||
int ypos = (int) NumericValue.asNumber( params.get(1 + offset)).getLong();
|
||||
int zpos = (int) NumericValue.asNumber( params.get(2 + offset)).getLong();
|
||||
return new LocatorResult(
|
||||
new BlockValue(
|
||||
null,
|
||||
c.s.getWorld(),
|
||||
new BlockPos(c.origin.getX() + xpos, c.origin.getY() + ypos, c.origin.getZ() + zpos)
|
||||
),
|
||||
3+offset
|
||||
);
|
||||
}
|
||||
catch (IndexOutOfBoundsException e)
|
||||
{
|
||||
throw new InternalExpressionException("Block should be defined either by three coordinates, a block value, or a proper string");
|
||||
}
|
||||
}
|
||||
|
||||
public BlockState getBlockState()
|
||||
{
|
||||
if (blockState != null)
|
||||
|
||||
Reference in new issue
Block a user