3
0
Mirror von https://github.com/IntellectualSites/FastAsyncWorldEdit.git synchronisiert 2024-12-27 03:12:37 +01:00

Added getLazyBlock() to Extent for performance.

Dieser Commit ist enthalten in:
sk89q 2014-03-31 18:22:44 -07:00
Ursprung dcf35e5312
Commit fa24eb60fa
11 geänderte Dateien mit 224 neuen und 109 gelöschten Zeilen

Datei anzeigen

@ -295,17 +295,36 @@ public class EditSession implements Extent {
return changeSet.size(); return changeSet.size();
} }
@Override
public BaseBlock getLazyBlock(Vector position) {
return world.getLazyBlock(position);
}
@Override @Override
public BaseBlock getBlock(Vector position) { public BaseBlock getBlock(Vector position) {
return world.getBlock(position); return world.getBlock(position);
} }
@Override /**
* Get a block type at the given position.
*
* @param position the position
* @return the block type
* @deprecated Use {@link #getLazyBlock(Vector)} or {@link #getBlock(Vector)}
*/
@Deprecated
public int getBlockType(Vector position) { public int getBlockType(Vector position) {
return world.getBlockType(position); return world.getBlockType(position);
} }
@Override /**
* Get a block data at the given position.
*
* @param position the position
* @return the block data
* @deprecated Use {@link #getLazyBlock(Vector)} or {@link #getBlock(Vector)}
*/
@Deprecated
public int getBlockData(Vector position) { public int getBlockData(Vector position) {
return world.getBlockData(position); return world.getBlockData(position);
} }

Datei anzeigen

@ -93,6 +93,7 @@ public abstract class LocalWorld implements World, Extent {
* @param pt * @param pt
* @return * @return
*/ */
@Deprecated
public abstract int getBlockType(Vector pt); public abstract int getBlockType(Vector pt);
/** /**
@ -162,6 +163,7 @@ public abstract class LocalWorld implements World, Extent {
* @param pt * @param pt
* @return * @return
*/ */
@Deprecated
public abstract int getBlockData(Vector pt); public abstract int getBlockData(Vector pt);
/** /**
@ -548,6 +550,11 @@ public abstract class LocalWorld implements World, Extent {
return successful; return successful;
} }
@Override
public BaseBlock getLazyBlock(Vector position) {
return getBlock(position);
}
@Override @Override
public BaseBlock getBlock(Vector pt) { public BaseBlock getBlock(Vector pt) {
checkLoadedChunk(pt); checkLoadedChunk(pt);

Datei anzeigen

@ -0,0 +1,105 @@
/*
* 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 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.blocks;
import com.sk89q.jnbt.CompoundTag;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.data.DataException;
import com.sk89q.worldedit.extent.Extent;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* A implementation of a lazy block for {@link Extent#getLazyBlock(Vector)}
* that takes the block's ID and metadata, but will defer loading of NBT
* data until time of access.
* </p>
* NBT data is later loaded using a call to {@link Extent#getBlock(Vector)}
* with a stored {@link Extent} and location.
* </p>
* All mutators on this object will throw an
* {@link UnsupportedOperationException}.
*/
public class LazyBlock extends BaseBlock {
private final Extent extent;
private final Vector position;
private boolean loaded = false;
/**
* Create a new lazy block.
*
* @param type the block type
* @param extent the extent to later load the full block data from
* @param position the position to later load the full block data from
*/
public LazyBlock(int type, Extent extent, Vector position) {
super(type);
checkNotNull(extent);
checkNotNull(position);
this.extent = extent;
this.position = position;
}
/**
* Create a new lazy block.
*
* @param type the block type
* @param data the data value
* @param extent the extent to later load the full block data from
* @param position the position to later load the full block data from
*/
public LazyBlock(int type, int data, Extent extent, Vector position) {
super(type, data);
checkNotNull(extent);
checkNotNull(position);
this.extent = extent;
this.position = position;
}
@Override
public void setId(int id) {
throw new UnsupportedOperationException("This object is immutable");
}
@Override
public void setData(int data) {
throw new UnsupportedOperationException("This object is immutable");
}
@Override
public CompoundTag getNbtData() {
if (!loaded) {
BaseBlock loadedBlock = extent.getBlock(position);
try {
super.setNbtData(loadedBlock.getNbtData());
} catch (DataException e) {
throw new RuntimeException(e);
}
}
return super.getNbtData();
}
@Override
public void setNbtData(CompoundTag nbtData) throws DataException {
throw new UnsupportedOperationException("This object is immutable");
}
}

Datei anzeigen

@ -19,83 +19,33 @@
package com.sk89q.worldedit.bukkit; package com.sk89q.worldedit.bukkit;
import java.io.ByteArrayOutputStream; import com.sk89q.worldedit.*;
import java.io.File; import com.sk89q.worldedit.EntityType;
import java.io.InputStream; import com.sk89q.worldedit.Vector;
import java.lang.reflect.Method; import com.sk89q.worldedit.blocks.*;
import java.net.URL; import com.sk89q.worldedit.blocks.ContainerBlock;
import java.util.ArrayList; import com.sk89q.worldedit.blocks.NoteBlock;
import java.util.EnumMap; import com.sk89q.worldedit.bukkit.entity.BukkitEntity;
import java.util.HashMap; import com.sk89q.worldedit.regions.Region;
import java.util.HashSet; import com.sk89q.worldedit.util.TreeGenerator;
import java.util.List; import org.bukkit.*;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.bukkit.Bukkit;
import org.bukkit.Effect;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.Material; import org.bukkit.block.*;
import org.bukkit.SkullType;
import org.bukkit.TreeType;
import org.bukkit.World;
import org.bukkit.block.Biome;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.block.BlockState;
import org.bukkit.block.Chest;
import org.bukkit.block.CreatureSpawner;
import org.bukkit.block.Furnace;
import org.bukkit.block.Sign;
import org.bukkit.block.Skull;
import org.bukkit.enchantments.Enchantment; import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.Ambient; import org.bukkit.entity.*;
import org.bukkit.entity.Animals;
import org.bukkit.entity.Boat;
import org.bukkit.entity.Entity;
import org.bukkit.entity.ExperienceOrb;
import org.bukkit.entity.FallingBlock;
import org.bukkit.entity.Golem;
import org.bukkit.entity.Hanging;
import org.bukkit.entity.HumanEntity;
import org.bukkit.entity.Item;
import org.bukkit.entity.ItemFrame;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Minecart;
import org.bukkit.entity.Painting;
import org.bukkit.entity.Projectile;
import org.bukkit.entity.TNTPrimed;
import org.bukkit.entity.Tameable;
import org.bukkit.entity.Villager;
import org.bukkit.inventory.DoubleChestInventory; import org.bukkit.inventory.DoubleChestInventory;
import org.bukkit.inventory.Inventory; import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.bukkit.plugin.Plugin; import org.bukkit.plugin.Plugin;
import com.sk89q.worldedit.BiomeType; import java.io.ByteArrayOutputStream;
import com.sk89q.worldedit.BlockVector2D; import java.io.File;
import com.sk89q.worldedit.EditSession; import java.io.InputStream;
import com.sk89q.worldedit.EntityType; import java.lang.reflect.Method;
import com.sk89q.worldedit.LocalEntity; import java.net.URL;
import com.sk89q.worldedit.LocalWorld; import java.util.*;
import com.sk89q.worldedit.Vector; import java.util.logging.Level;
import com.sk89q.worldedit.Vector2D; import java.util.logging.Logger;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.blocks.BaseItemStack;
import com.sk89q.worldedit.blocks.BlockID;
import com.sk89q.worldedit.blocks.ContainerBlock;
import com.sk89q.worldedit.blocks.FurnaceBlock;
import com.sk89q.worldedit.blocks.MobSpawnerBlock;
import com.sk89q.worldedit.blocks.NoteBlock;
import com.sk89q.worldedit.blocks.SignBlock;
import com.sk89q.worldedit.blocks.SkullBlock;
import com.sk89q.worldedit.bukkit.entity.BukkitEntity;
import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldedit.util.TreeGenerator;
public class BukkitWorld extends LocalWorld { public class BukkitWorld extends LocalWorld {
@ -1355,6 +1305,13 @@ public class BukkitWorld extends LocalWorld {
return super.getBlock(pt); return super.getBlock(pt);
} }
@SuppressWarnings("deprecation")
@Override
public BaseBlock getLazyBlock(Vector position) {
Block bukkitBlock = world.getBlockAt(position.getBlockX(), position.getBlockY(), position.getBlockZ());
return new LazyBlock(bukkitBlock.getTypeId(), bukkitBlock.getData(), this, position);
}
@Override @Override
public boolean setBlock(Vector pt, com.sk89q.worldedit.foundation.Block block, boolean notifyAdjacent) { public boolean setBlock(Vector pt, com.sk89q.worldedit.foundation.Block block, boolean notifyAdjacent) {
if (!skipNmsSafeSet) { if (!skipNmsSafeSet) {

Datei anzeigen

@ -47,27 +47,36 @@ public interface Extent {
* Calls to this method can actually be quite expensive, so cache results * Calls to this method can actually be quite expensive, so cache results
* whenever it is possible, while being aware of the mutability aspect. * whenever it is possible, while being aware of the mutability aspect.
* The cost, however, depends on the implementation and particular extent. * The cost, however, depends on the implementation and particular extent.
* If only basic information about the block is required, then use of
* {@link #getLazyBlock(Vector)} is recommended.
* *
* @param position position of the block * @param position position of the block
* @return the block, or null if the block does not exist * @return the block
*/ */
BaseBlock getBlock(Vector position); BaseBlock getBlock(Vector position);
/** /**
* Get the block ID at the given location. * Get a lazy, immutable snapshot of the block at the given location that only
* immediately contains information about the block's type (and metadata).
* </p>
* Further information (such as NBT data) will be available <strong>by the
* time of access</strong>. Therefore, it is not recommended that
* this method is used if the world is being simulated at the time of
* call. If the block needs to be stored for future use, then this method should
* definitely not be used. Moreover, the block that is returned is immutable (or
* should be), and therefore modifications should not be attempted on it. If a
* modifiable copy is required, then the block should be cloned.
* </p>
* This method exists because it is sometimes important to inspect the block
* at a given location, but {@link #getBlock(Vector)} may be too expensive in
* the underlying implementation. It is also not possible to implement
* caching if the returned object is mutable, so this methods allows caching
* implementations to be used.
* *
* @param position position of the block * @param position position of the block
* @return the block ID * @return the block
*/ */
int getBlockType(Vector position); BaseBlock getLazyBlock(Vector position);
/**
* Get the data value of the block at the given location.
*
* @param position position of the block
* @return the block data value
*/
int getBlockData(Vector position);
/** /**
* Change the block at the given location to the given block. The operation may * Change the block at the given location to the given block. The operation may

Datei anzeigen

@ -56,18 +56,13 @@ public class ExtentDelegate implements Extent {
} }
@Override @Override
public BaseBlock getBlock(Vector location) { public BaseBlock getBlock(Vector position) {
return extent.getBlock(location); return extent.getBlock(position);
} }
@Override @Override
public int getBlockType(Vector location) { public BaseBlock getLazyBlock(Vector position) {
return extent.getBlockType(location); return extent.getLazyBlock(position);
}
@Override
public int getBlockData(Vector location) {
return extent.getBlockData(location);
} }
@Override @Override

Datei anzeigen

@ -83,6 +83,8 @@ public class SimpleBlockReorder extends ExtentDelegate {
@Override @Override
public boolean setBlock(Vector location, BaseBlock block) throws WorldEditException { public boolean setBlock(Vector location, BaseBlock block) throws WorldEditException {
BaseBlock lazyBlock = getLazyBlock(location);
if (!enabled) { if (!enabled) {
return super.setBlock(location, block); return super.setBlock(location, block);
} }
@ -90,18 +92,18 @@ public class SimpleBlockReorder extends ExtentDelegate {
if (BlockType.shouldPlaceLast(block.getType())) { if (BlockType.shouldPlaceLast(block.getType())) {
// Place torches, etc. last // Place torches, etc. last
stage2.put(location.toBlockVector(), block); stage2.put(location.toBlockVector(), block);
return !(getBlockType(location) == block.getType() && getBlockData(location) == block.getData()); return !(lazyBlock.getType() == block.getType() && lazyBlock.getData() == block.getData());
} else if (BlockType.shouldPlaceFinal(block.getType())) { } else if (BlockType.shouldPlaceFinal(block.getType())) {
// Place signs, reed, etc even later // Place signs, reed, etc even later
stage3.put(location.toBlockVector(), block); stage3.put(location.toBlockVector(), block);
return !(getBlockType(location) == block.getType() && getBlockData(location) == block.getData()); return !(lazyBlock.getType() == block.getType() && lazyBlock.getData() == block.getData());
} else if (BlockType.shouldPlaceLast(getBlockType(location))) { } else if (BlockType.shouldPlaceLast(lazyBlock.getType())) {
// Destroy torches, etc. first // Destroy torches, etc. first
super.setBlock(location, new BaseBlock(BlockID.AIR)); super.setBlock(location, new BaseBlock(BlockID.AIR));
return super.setBlock(location, block); return super.setBlock(location, block);
} else { } else {
stage1.put(location.toBlockVector(), block); stage1.put(location.toBlockVector(), block);
return !(getBlockType(location) == block.getType() && getBlockData(location) == block.getData()); return !(lazyBlock.getType() == block.getType() && lazyBlock.getData() == block.getData());
} }
} }

Datei anzeigen

@ -74,8 +74,8 @@ public class Block implements TileEntityBlock {
* @see #setId(int) * @see #setId(int)
*/ */
public Block(int id) { public Block(int id) {
setId(id); internalSetId(id);
setData(0); internalSetData(0);
} }
/** /**
@ -87,8 +87,8 @@ public class Block implements TileEntityBlock {
* @see #setData(int) * @see #setData(int)
*/ */
public Block(int id, int data) { public Block(int id, int data) {
setId(id); internalSetId(id);
setData(data); internalSetData(data);
} }
/** /**
@ -116,13 +116,13 @@ public class Block implements TileEntityBlock {
public int getId() { public int getId() {
return id; return id;
} }
/** /**
* Set the block ID. * Set the block ID.
* *
* @param id block id (between 0 and {@link #MAX_ID}). * @param id block id (between 0 and {@link #MAX_ID}).
*/ */
public void setId(int id) { protected final void internalSetId(int id) {
if (id > MAX_ID) { if (id > MAX_ID) {
throw new IllegalArgumentException("Can't have a block ID above " throw new IllegalArgumentException("Can't have a block ID above "
+ MAX_ID + " (" + id + " given)"); + MAX_ID + " (" + id + " given)");
@ -131,9 +131,18 @@ public class Block implements TileEntityBlock {
if (id < 0) { if (id < 0) {
throw new IllegalArgumentException("Can't have a block ID below 0"); throw new IllegalArgumentException("Can't have a block ID below 0");
} }
this.id = (short) id; this.id = (short) id;
} }
/**
* Set the block ID.
*
* @param id block id (between 0 and {@link #MAX_ID}).
*/
public void setId(int id) {
internalSetId(id);
}
/** /**
* Get the block's data value. * Get the block's data value.
@ -149,7 +158,7 @@ public class Block implements TileEntityBlock {
* *
* @param data block data value (between 0 and {@link #MAX_DATA}). * @param data block data value (between 0 and {@link #MAX_DATA}).
*/ */
public void setData(int data) { protected final void internalSetData(int data) {
if (data > MAX_DATA) { if (data > MAX_DATA) {
throw new IllegalArgumentException( throw new IllegalArgumentException(
"Can't have a block data value above " + MAX_DATA + " (" "Can't have a block data value above " + MAX_DATA + " ("
@ -162,6 +171,15 @@ public class Block implements TileEntityBlock {
this.data = (short) data; this.data = (short) data;
} }
/**
* Set the block's data value.
*
* @param data block data value (between 0 and {@link #MAX_DATA}).
*/
public void setData(int data) {
internalSetData(data);
}
/** /**
* Set both the block's ID and data value. * Set both the block's ID and data value.

Datei anzeigen

@ -40,7 +40,7 @@ public class ExistingBlockMask extends AbstractExtentMask {
@Override @Override
public boolean test(Vector vector) { public boolean test(Vector vector) {
return getExtent().getBlockType(vector) != BlockID.AIR; return getExtent().getLazyBlock(vector).getType() != BlockID.AIR;
} }
} }

Datei anzeigen

@ -39,7 +39,8 @@ public class FuzzyBlockMask extends BlockMask {
public boolean test(Vector vector) { public boolean test(Vector vector) {
Extent extent = getExtent(); Extent extent = getExtent();
Collection<BaseBlock> blocks = getBlocks(); Collection<BaseBlock> blocks = getBlocks();
BaseBlock compare = new BaseBlock(extent.getBlockType(vector), extent.getBlockData(vector)); BaseBlock lazyBlock = extent.getLazyBlock(vector);
BaseBlock compare = new BaseBlock(lazyBlock.getType(), lazyBlock.getData());
return BaseBlock.containsFuzzy(blocks, compare); return BaseBlock.containsFuzzy(blocks, compare);
} }
} }

Datei anzeigen

@ -19,6 +19,7 @@
package com.sk89q.worldedit.function.mask; package com.sk89q.worldedit.function.mask;
import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.extent.Extent; import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.Vector; import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.blocks.BlockType; import com.sk89q.worldedit.blocks.BlockType;
@ -32,7 +33,8 @@ public class SolidBlockMask extends AbstractExtentMask {
@Override @Override
public boolean test(Vector vector) { public boolean test(Vector vector) {
Extent extent = getExtent(); Extent extent = getExtent();
return !BlockType.canPassThrough(extent.getBlockType(vector), extent.getBlockData(vector)); BaseBlock lazyBlock = extent.getLazyBlock(vector);
return !BlockType.canPassThrough(lazyBlock.getType(), lazyBlock.getData());
} }
} }