Add a new block metadata framework and fix //rotate and //flip.

Remove the previous Mapping interfaces.
This commit is contained in:
sk89q
2014-07-09 14:14:17 -07:00
parent 22dceb5614
commit 56b349ead8
29 changed files with 7425 additions and 319 deletions

View File

@ -28,8 +28,8 @@ import com.sk89q.worldedit.entity.Entity;
import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldedit.util.Location;
import com.sk89q.worldedit.util.TreeGenerator.TreeType;
import com.sk89q.worldedit.world.mapping.NullResolver;
import com.sk89q.worldedit.world.mapping.Resolver;
import com.sk89q.worldedit.world.registry.LegacyWorldData;
import com.sk89q.worldedit.world.registry.WorldData;
import javax.annotation.Nullable;
import java.util.Collections;
@ -94,6 +94,11 @@ public class NullWorld extends AbstractWorld {
return false;
}
@Override
public WorldData getWorldData() {
return LegacyWorldData.getInstance();
}
@Override
public BaseBlock getBlock(Vector position) {
return new BaseBlock(BlockID.AIR);
@ -104,34 +109,6 @@ public class NullWorld extends AbstractWorld {
return new BaseBlock(BlockID.AIR);
}
@Override
public Resolver<BaseBlock> getBlockMapping() {
return new NullResolver<BaseBlock>();
}
@Override
public Resolver<BaseEntity> getEntityMapping() {
return new NullResolver<BaseEntity>();
}
@Nullable
@Override
public <T> T getMetaData(BaseBlock block, Class<T> metaDataClass) {
return null;
}
@Nullable
@Override
public <T> T getMetaData(Entity entity, Class<T> metaDataClass) {
return null;
}
@Nullable
@Override
public <T> T getMetaData(BaseEntity entity, Class<T> metaDataClass) {
return null;
}
@Override
public List<Entity> getEntities() {
return Collections.emptyList();

View File

@ -19,7 +19,16 @@
package com.sk89q.worldedit.world;
import com.sk89q.worldedit.*;
import com.sk89q.worldedit.BiomeType;
import com.sk89q.worldedit.BlockVector2D;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.EntityType;
import com.sk89q.worldedit.LocalEntity;
import com.sk89q.worldedit.LocalWorld;
import com.sk89q.worldedit.MaxChangedBlocksException;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.Vector2D;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.blocks.BaseItemStack;
import com.sk89q.worldedit.extension.platform.Platform;
@ -28,12 +37,12 @@ import com.sk89q.worldedit.function.mask.Mask;
import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldedit.util.TreeGenerator;
import com.sk89q.worldedit.util.TreeGenerator.TreeType;
import com.sk89q.worldedit.world.mapping.Mapping;
import com.sk89q.worldedit.world.registry.WorldData;
/**
* Represents a world (dimension).
*/
public interface World extends Extent, Mapping {
public interface World extends Extent {
/**
* Get the name of the world.
@ -346,6 +355,13 @@ public interface World extends Extent, Mapping {
*/
boolean queueBlockBreakEffect(Platform server, Vector position, int blockId, double priority);
/**
* Get the data for blocks and so on for this world.
*
* @return the world data
*/
WorldData getWorldData();
@Override
boolean equals(Object other);

View File

@ -1,114 +0,0 @@
/*
* 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.world.mapping;
import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.entity.BaseEntity;
import com.sk89q.worldedit.entity.Entity;
import com.sk89q.worldedit.entity.metadata.Tameable;
import javax.annotation.Nullable;
/**
* A mapping can create state objects (such as {@link BaseBlock})
* from implementation-independent identifiers (such as "minecraft.stone"),
* as well as perform the opposite task of retrieving
* the identifier for a given state object (whenever possible at least, because
* a mapping may not be compatible with a set of state objects that may have
* come from another implementation). In addition, a mapping may be able to
* retrieve a variety of metadata objects (such as {@link Tameable}) to
* describe a given state object.
* </p>
* However, it may be possible that a mapping be "dumb" and not be able to,
* for example, return a {@link Tameable} for a "Horse" entity, simply because
* it has not be implemented. Any code that queries a mapping must be
* aware of this and act accordingly.
*/
public interface Mapping {
/**
* Get the mapping for block identifiers.
*
* @return a block mapping
*/
Resolver<BaseBlock> getBlockMapping();
/**
* Get the mapping for entity identifiers.
*
* @return an entity mapping
*/
Resolver<BaseEntity> getEntityMapping();
/**
* Attempt to return an instance of the given class for the given block.
* For example, {@code getMetaData(block, Inventory.class)} might return
* an instance if the block happens to contain an inventory.
* </p>
* If the given block is not of the given class (i.e. a dirt block does
* not have an inventory) or if the information is simply not available,
* {@code null} will be returned.
* </p>
* Mutator methods on the returned instance should change the block.
*
* @param block the block
* @param metaDataClass the metadata class for the returned instance
* @param <T> the metadata class
* @return an instance of the given class, otherwise null
*/
@Nullable <T> T getMetaData(BaseBlock block, Class<T> metaDataClass);
/**
* Attempt to return an instance of the given class for the given entity.
* For example, {@code getMetaData(entity, Creature.class)} might return
* an instance if the entity happens to be a creature.
* </p>
* If the given entity is not of the given class (i.e. a painting is
* not a creature) or if the information is simply not available,
* {@code null} will be returned.
* </p>
* Mutator methods on the returned instance should change the entity.
*
* @param entity the entity
* @param metaDataClass the metadata class for the returned instance
* @param <T> the metadata class
* @return an instance of the given class, otherwise null
*/
@Nullable <T> T getMetaData(Entity entity, Class<T> metaDataClass);
/**
* Attempt to return an instance of the given class for the given entity.
* For example, {@code getMetaData(entity, Creature.class)} might return
* an instance if the entity happens to be a creature.
* </p>
* If the given entity is not of the given class (i.e. a painting is
* not a creature) or if the information is simply not available,
* {@code null} will be returned.
* </p>
* Mutator methods on the returned instance should change the entity.
*
* @param entity the entity
* @param metaDataClass the metadata class for the returned instance
* @param <T> the metadata class
* @return an instance of the given class, otherwise null
*/
@Nullable <T> T getMetaData(BaseEntity entity, Class<T> metaDataClass);
}

View File

@ -0,0 +1,69 @@
/*
* 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.world.registry;
import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.blocks.BlockMaterial;
import javax.annotation.Nullable;
import java.util.Map;
/**
* Provides information on blocks and provides methods to create them.
*/
public interface BlockRegistry {
/**
* Create a new block using its ID.
*
* @param id the id
* @return the block, which may be null if no block exists
*/
@Nullable
BaseBlock createFromId(String id);
/**
* Create a new block using its legacy numeric ID.
*
* @param id the id
* @return the block, which may be null if no block exists
*/
@Nullable
BaseBlock createFromId(int id);
/**
* Get the material for the given block.
*
* @param block the block
* @return the material, or null if the material information is not known
*/
@Nullable
BlockMaterial getMaterial(BaseBlock block);
/**
* Get an unmodifiable map of states for this block.
*
* @param block the block
* @return a map of states where the key is the state's ID
*/
@Nullable
Map<String, ? extends State> getStates(BaseBlock block);
}

View File

@ -0,0 +1,189 @@
/*
* 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.world.registry;
import com.google.common.io.Resources;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.reflect.TypeToken;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.blocks.BlockMaterial;
import com.sk89q.worldedit.util.gson.VectorAdapter;
import gnu.trove.map.TIntObjectMap;
import gnu.trove.map.hash.TIntObjectHashMap;
import javax.annotation.Nullable;
import java.io.IOException;
import java.net.URL;
import java.nio.charset.Charset;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* Provides block data based on the built-in block database that is bundled
* with WorldEdit.
*
* <p>A new instance cannot be created. Use {@link #getInstance()} to get
* an instance.</p>
*
* <p>The data is read from a JSON file that is bundled with WorldEdit. If
* reading fails (which occurs when this class is first instantiated), then
* the methods will return {@code null}s for all blocks.</p>
*/
public class BundledBlockData {
private static final Logger log = Logger.getLogger(BundledBlockData.class.getCanonicalName());
private static final BundledBlockData INSTANCE = new BundledBlockData();
private final Map<String, BlockEntry> idMap = new HashMap<String, BlockEntry>();
private final TIntObjectMap<BlockEntry> legacyMap = new TIntObjectHashMap<BlockEntry>();
/**
* Create a new instance.
*/
private BundledBlockData() {
try {
loadFromResource();
} catch (IOException e) {
log.log(Level.WARNING, "Failed to load the built-in block registry", e);
}
}
/**
* Attempt to load the data from file.
*
* @throws IOException thrown on I/O error
*/
private void loadFromResource() throws IOException {
GsonBuilder gsonBuilder = new GsonBuilder();
gsonBuilder.registerTypeAdapter(Vector.class, new VectorAdapter());
Gson gson = gsonBuilder.create();
URL url = BundledBlockData.class.getResource("blocks.json");
if (url == null) {
throw new IOException("Could not find blocks.json");
}
String data = Resources.toString(url, Charset.defaultCharset());
List<BlockEntry> entries = gson.fromJson(data, new TypeToken<List<BlockEntry>>() {}.getType());
for (BlockEntry entry : entries) {
entry.postDeserialization();
idMap.put(entry.id, entry);
legacyMap.put(entry.legacyId, entry);
}
}
/**
* Return the entry for the given block ID.
*
* @param id the ID
* @return the entry, or null
*/
@Nullable
private BlockEntry findById(String id) {
return idMap.get(id);
}
/**
* Return the entry for the given block legacy numeric ID.
*
* @param id the ID
* @return the entry, or null
*/
@Nullable
private BlockEntry findById(int id) {
return legacyMap.get(id);
}
/**
* Convert the given string ID to a legacy numeric ID.
*
* @param id the ID
* @return the legacy ID, which may be null if the block does not have a legacy ID
*/
@Nullable
public Integer toLegacyId(String id) {
BlockEntry entry = findById(id);
if (entry != null) {
return entry.legacyId;
} else {
return null;
}
}
/**
* Get the material properties for the given block.
*
* @param id the legacy numeric ID
* @return the material's properties, or null
*/
@Nullable
public BlockMaterial getMaterialById(int id) {
BlockEntry entry = findById(id);
if (entry != null) {
return entry.material;
} else {
return null;
}
}
/**
* Get the states for the given block.
*
* @param id the legacy numeric ID
* @return the block's states, or null if no information is available
*/
@Nullable
public Map<String, ? extends State> getStatesById(int id) {
BlockEntry entry = findById(id);
if (entry != null) {
return entry.states;
} else {
return null;
}
}
/**
* Get a singleton instance of this object.
*
* @return the instance
*/
public static BundledBlockData getInstance() {
return INSTANCE;
}
private static class BlockEntry {
private int legacyId;
private String id;
private String unlocalizedName;
private List<String> aliases;
private Map<String, SimpleState> states = new HashMap<String, SimpleState>();
private SimpleBlockMaterial material = new SimpleBlockMaterial();
void postDeserialization() {
for (SimpleState state : states.values()) {
state.postDeserialization();
}
}
}
}

View File

@ -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.world.registry;
import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.blocks.BlockMaterial;
import javax.annotation.Nullable;
import java.util.Map;
/**
* A block registry that uses {@link BundledBlockData} to serve information
* about blocks.
*/
public class LegacyBlockRegistry implements BlockRegistry {
@Nullable
@Override
public BaseBlock createFromId(String id) {
Integer legacyId = BundledBlockData.getInstance().toLegacyId(id);
if (legacyId != null) {
return createFromId(legacyId);
} else {
return null;
}
}
@Nullable
@Override
public BaseBlock createFromId(int id) {
return new BaseBlock(id);
}
@Nullable
@Override
public BlockMaterial getMaterial(BaseBlock block) {
return BundledBlockData.getInstance().getMaterialById(block.getId());
}
@Nullable
@Override
public Map<String, ? extends State> getStates(BaseBlock block) {
return BundledBlockData.getInstance().getStatesById(block.getId());
}
}

View File

@ -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.world.registry;
/**
* An implementation of {@link WorldData} that uses legacy numeric IDs and
* a built-in block database.
*/
public final class LegacyWorldData implements WorldData {
private static final LegacyWorldData INSTANCE = new LegacyWorldData();
private final LegacyBlockRegistry blockRegistry = new LegacyBlockRegistry();
/**
* Create a new instance.
*/
private LegacyWorldData() {
}
@Override
public BlockRegistry getBlockRegistry() {
return blockRegistry;
}
/**
* Get a singleton instance.
*
* @return an instance
*/
public static LegacyWorldData getInstance() {
return INSTANCE;
}
}

View File

@ -0,0 +1,246 @@
/*
* 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.world.registry;
import com.sk89q.worldedit.blocks.BlockMaterial;
class SimpleBlockMaterial implements BlockMaterial {
private boolean renderedAsNormalBlock;
private boolean fullCube;
private boolean opaque;
private boolean powerSource;
private boolean liquid;
private boolean solid;
private float hardness;
private float resistance;
private float slipperiness;
private boolean grassBlocking;
private float ambientOcclusionLightValue;
private int lightOpacity;
private int lightValue;
private boolean fragileWhenPushed;
private boolean unpushable;
private boolean adventureModeExempt;
private boolean ticksRandomly;
private boolean usingNeighborLight;
private boolean movementBlocker;
private boolean burnable;
private boolean toolRequired;
private boolean replacedDuringPlacement;
@Override
public boolean isRenderedAsNormalBlock() {
return renderedAsNormalBlock;
}
public void setRenderedAsNormalBlock(boolean renderedAsNormalBlock) {
this.renderedAsNormalBlock = renderedAsNormalBlock;
}
@Override
public boolean isFullCube() {
return fullCube;
}
public void setFullCube(boolean fullCube) {
this.fullCube = fullCube;
}
@Override
public boolean isOpaque() {
return opaque;
}
public void setOpaque(boolean opaque) {
this.opaque = opaque;
}
@Override
public boolean isPowerSource() {
return powerSource;
}
public void setPowerSource(boolean powerSource) {
this.powerSource = powerSource;
}
@Override
public boolean isLiquid() {
return liquid;
}
public void setLiquid(boolean liquid) {
this.liquid = liquid;
}
@Override
public boolean isSolid() {
return solid;
}
public void setSolid(boolean solid) {
this.solid = solid;
}
@Override
public float getHardness() {
return hardness;
}
public void setHardness(float hardness) {
this.hardness = hardness;
}
@Override
public float getResistance() {
return resistance;
}
public void setResistance(float resistance) {
this.resistance = resistance;
}
@Override
public float getSlipperiness() {
return slipperiness;
}
public void setSlipperiness(float slipperiness) {
this.slipperiness = slipperiness;
}
@Override
public boolean isGrassBlocking() {
return grassBlocking;
}
public void setGrassBlocking(boolean grassBlocking) {
this.grassBlocking = grassBlocking;
}
@Override
public float getAmbientOcclusionLightValue() {
return ambientOcclusionLightValue;
}
public void setAmbientOcclusionLightValue(float ambientOcclusionLightValue) {
this.ambientOcclusionLightValue = ambientOcclusionLightValue;
}
@Override
public int getLightOpacity() {
return lightOpacity;
}
public void setLightOpacity(int lightOpacity) {
this.lightOpacity = lightOpacity;
}
@Override
public int getLightValue() {
return lightValue;
}
public void setLightValue(int lightValue) {
this.lightValue = lightValue;
}
@Override
public boolean isFragileWhenPushed() {
return fragileWhenPushed;
}
public void setFragileWhenPushed(boolean fragileWhenPushed) {
this.fragileWhenPushed = fragileWhenPushed;
}
@Override
public boolean isUnpushable() {
return unpushable;
}
public void setUnpushable(boolean unpushable) {
this.unpushable = unpushable;
}
@Override
public boolean isAdventureModeExempt() {
return adventureModeExempt;
}
public void setAdventureModeExempt(boolean adventureModeExempt) {
this.adventureModeExempt = adventureModeExempt;
}
@Override
public boolean isTicksRandomly() {
return ticksRandomly;
}
public void setTicksRandomly(boolean ticksRandomly) {
this.ticksRandomly = ticksRandomly;
}
@Override
public boolean isUsingNeighborLight() {
return usingNeighborLight;
}
public void setUsingNeighborLight(boolean usingNeighborLight) {
this.usingNeighborLight = usingNeighborLight;
}
@Override
public boolean isMovementBlocker() {
return movementBlocker;
}
public void setMovementBlocker(boolean movementBlocker) {
this.movementBlocker = movementBlocker;
}
@Override
public boolean isBurnable() {
return burnable;
}
public void setBurnable(boolean burnable) {
this.burnable = burnable;
}
@Override
public boolean isToolRequired() {
return toolRequired;
}
public void setToolRequired(boolean toolRequired) {
this.toolRequired = toolRequired;
}
@Override
public boolean isReplacedDuringPlacement() {
return replacedDuringPlacement;
}
public void setReplacedDuringPlacement(boolean replacedDuringPlacement) {
this.replacedDuringPlacement = replacedDuringPlacement;
}
}

View File

@ -0,0 +1,71 @@
/*
* 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.world.registry;
import com.sk89q.worldedit.blocks.BaseBlock;
import javax.annotation.Nullable;
import java.util.Collections;
import java.util.Map;
class SimpleState implements State {
private Byte dataMask;
private Map<String, SimpleStateValue> values;
@Override
public Map<String, SimpleStateValue> valueMap() {
return Collections.unmodifiableMap(values);
}
@Nullable
@Override
public StateValue getValue(BaseBlock block) {
for (StateValue value : values.values()) {
if (value.isSet(block)) {
return value;
}
}
return null;
}
byte getDataMask() {
return dataMask != null ? dataMask : 0xF;
}
@Override
public boolean hasDirection() {
for (SimpleStateValue value : values.values()) {
if (value.getDirection() != null) {
return true;
}
}
return false;
}
void postDeserialization() {
for (SimpleStateValue v : values.values()) {
v.setState(this);
}
}
}

View File

@ -0,0 +1,55 @@
/*
* 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.world.registry;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.blocks.BaseBlock;
class SimpleStateValue implements StateValue {
private SimpleState state;
private Byte data;
private Vector direction;
void setState(SimpleState state) {
this.state = state;
}
@Override
public boolean isSet(BaseBlock block) {
return data != null && (block.getData() & state.getDataMask()) == data;
}
@Override
public boolean set(BaseBlock block) {
if (data != null) {
block.setData((block.getData() & ~state.getDataMask()) | data);
return true;
} else {
return false;
}
}
@Override
public Vector getDirection() {
return direction;
}
}

View File

@ -17,40 +17,45 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.world.mapping;
package com.sk89q.worldedit.world.registry;
import com.sk89q.worldedit.blocks.BaseBlock;
import javax.annotation.Nullable;
import java.util.Map;
/**
* A resolver can create state objects (such as {@link BaseBlock}) from
* universal identifiers, but also get the universal identifier for
* a given state object (at least when it is known).
* </p>
* Identifiers may be case-sensitive. Routines that work with IDs should
* not make changes to the casing of the IDs or perform case-insensitive
* comparisons. Implementations may normalize the casing of IDs if it
* is appropriate.
* Describes a state property of a block.
*
* @param <E> the type of state object
* <p>Example states include "variant" (indicating material or type) and
* "facing" (indicating orientation).</p>
*/
public interface Resolver<E> {
public interface State {
/**
* Create an instance of the state object from the given ID.
* Return a map of available values for this state.
*
* @param id the ID
* @return an instance, otherwise null if an instance cannot be created
* <p>Keys are the value of state and map values describe that
* particular state value.</p>
*
* @return the map of state values
*/
@Nullable E create(String id);
Map<String, ? extends StateValue> valueMap();
/**
* Get the ID for the given object.
* Get the value that the block is set to.
*
* @param object the object
* @return the ID, otherwise null if it is not known
* @param block the block
* @return the state, otherwise null if the block isn't set to any of the values
*/
@Nullable String getId(E object);
@Nullable
StateValue getValue(BaseBlock block);
/**
* Returns whether this state contains directional data.
*
* @return true if directional data is available
*/
boolean hasDirection();
}

View File

@ -0,0 +1,56 @@
/*
* 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.world.registry;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.blocks.BaseBlock;
import javax.annotation.Nullable;
/**
* Describes a possible value for a {@code State}.
*/
public interface StateValue {
/**
* Return whether this state is set on the given block.
*
* @param block the block
* @return true if this value is set
*/
boolean isSet(BaseBlock block);
/**
* Set the state to this value on the given block.
*
* @param block the block to change
* @return true if the value was set successfully
*/
boolean set(BaseBlock block);
/**
* Return the direction associated with this value.
*
* @return the direction, otherwise null
*/
@Nullable
Vector getDirection();
}

View File

@ -17,28 +17,19 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.world.mapping;
import javax.annotation.Nullable;
package com.sk89q.worldedit.world.registry;
/**
* An implementation of a {@link Resolver} that knows nothing and returns
* {@code null} in all cases.
*
* @param <E> the object to resolve
* Describes the necessary data for blocks, entities, and other objects
* on a world.
*/
public class NullResolver<E> implements Resolver<E> {
public interface WorldData {
@Nullable
@Override
public E create(String id) {
return null;
}
@Nullable
@Override
public String getId(E object) {
return null;
}
/**
* Get the block registry.
*
* @return the block registry
*/
BlockRegistry getBlockRegistry();
}