Skip to content
Permalink
Browse files

Add placement buffers + pipeline system

  • Loading branch information...
kenzierocks committed Jul 19, 2019
1 parent fcea33e commit 69a068b0847b711e7fb0d93d983782e5364b40a3
@@ -0,0 +1,44 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

package com.sk89q.worldedit.reorder.arrange;

import com.sk89q.worldedit.reorder.buffer.PlacementBuffer;

/**
* (Re-)Arranges placement actions.
*/
public interface Arranger {

/**
* Re-arrange the given placements.
*
* @param stream the stream to pass re-arranged placements to
* @param buffer the new placements to arrange
*/
void onWrite(PlacementOutputStream stream, PlacementBuffer buffer);

/**
* Called when a group of blocks ends.
*
* @param stream the stream to pass re-arranged placements to
*/
void onFlush(PlacementOutputStream stream);

}
@@ -0,0 +1,51 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

package com.sk89q.worldedit.reorder.arrange;

import java.util.List;

/**
* A sequential list of Arrangers.
*
* <p>
* The last Arranger <strong>MUST</strong> not touch its output stream.
* Instead, it should handle the actual placements.
* </p>
*/
public interface ArrangerPipeline {

static ArrangerPipeline create() {
return new ArrangerPipelineImpl();
}

/**
* The list of Arrangers. Use this to add to the pipeline.
*
* @return a mutable list of Arrangers
*/
List<Arranger> arrangers();

/**
* Create a new stream to write messages to. It will use the Arrangers listed at this
* moment, copying them into the stream object.
*/
PlacementOutputStream openStream();

}
@@ -0,0 +1,78 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

package com.sk89q.worldedit.reorder.arrange;

import com.sk89q.worldedit.reorder.buffer.PlacementBuffer;

import java.lang.reflect.Proxy;
import java.util.List;
import java.util.ListIterator;
import java.util.concurrent.CopyOnWriteArrayList;

import static com.google.common.base.Preconditions.checkState;

class ArrangerPipelineImpl implements ArrangerPipeline {

// Make a stream that any interaction with will kill the parent stream.
private static final PlacementOutputStream UNUSABLE_PLACEMENT_OUTPUT_STREAM =
(PlacementOutputStream) Proxy.newProxyInstance(ArrangerPipelineImpl.class.getClassLoader(),
new Class[] { PlacementOutputStream.class }, (proxy, method, args) -> {
throw new IllegalStateException("Last Arranger interacted with output stream.");
});

private final List<Arranger> arrangers = new CopyOnWriteArrayList<>();

@Override
public List<Arranger> arrangers() {
return arrangers;
}

@Override
public PlacementOutputStream openStream() {
checkState(arrangers.size() > 0, "No Arrangers registered.");
ListIterator<Arranger> revIter = arrangers.listIterator(arrangers.size());
PlacementOutputStream prev = UNUSABLE_PLACEMENT_OUTPUT_STREAM;
while (revIter.hasPrevious()) {
prev = new PlacementOutputStreamImpl(revIter.previous(), prev);
}
return prev;
}

private static final class PlacementOutputStreamImpl implements PlacementOutputStream {
private final Arranger next;
private final PlacementOutputStream nextContext;

private PlacementOutputStreamImpl(Arranger next, PlacementOutputStream nextContext) {
this.next = next;
this.nextContext = nextContext;
}

@Override
public void write(PlacementBuffer buffer) {
next.onWrite(nextContext, buffer);
}

@Override
public void flush() {
next.onFlush(nextContext);
}
}

}
@@ -0,0 +1,46 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

package com.sk89q.worldedit.reorder.arrange;

import com.sk89q.worldedit.reorder.buffer.PlacementBuffer;

/**
* Output interface for placements.
*/
public interface PlacementOutputStream {

/**
* Store or pass the given buffer to the next Arranger.
*
* <p>
* To ensure all data is written to the next Arranger, you <strong>must</strong> call
* {@link #flush()}!
* </p>
*
* @param buffer the placement buffer
*/
void write(PlacementBuffer buffer);

/**
* Flush stored buffers to the next Arranger.
*/
void flush();

}
@@ -0,0 +1,63 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

package com.sk89q.worldedit.reorder.buffer;

import java.nio.BufferOverflowException;
import java.nio.BufferUnderflowException;

public class BufferConditions {

public static int checkWithin(int a, int b) {
if (a < 0 || a > b) {
throw new IllegalArgumentException();
}
return a;
}

public static void checkBounds(int dstLen, int off, int len) {
if (off < 0 || off > dstLen || len < 0 || len > (dstLen - off)) {
throw new IndexOutOfBoundsException();
}
}

public static int checkReadPosition(int position, int limit) {
if (position < 0 || position >= limit) {
throw new BufferUnderflowException();
}
return position;
}

public static int checkWritePosition(int position, int limit) {
if (position < 0 || position >= limit) {
throw new BufferOverflowException();
}
return position;
}

public static int checkIndex(int index, int limit) {
if (index < 0 || index >= limit) {
throw new IndexOutOfBoundsException();
}
return index;
}

private BufferConditions() {
}
}

0 comments on commit 69a068b

Please sign in to comment.
You can’t perform that action at this time.