Basically finish the state system. Just 1 more bug that I'm encountering.

This commit is contained in:
Matthew Miller
2018-07-18 00:42:09 +10:00
parent 4938f419ad
commit 6b5f218809
21 changed files with 158 additions and 98 deletions

View File

@ -21,6 +21,7 @@ package com.sk89q.worldedit.world.block;
import com.google.common.collect.ArrayTable;
import com.google.common.collect.HashBasedTable;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Table;
import com.sk89q.worldedit.registry.state.Property;
@ -28,8 +29,10 @@ import com.sk89q.worldedit.registry.state.Property;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
* An immutable class that represents the state a block can be in.
@ -46,7 +49,7 @@ public class BlockState implements BlockStateHolder<BlockState> {
BlockState(BlockType blockType) {
this.blockType = blockType;
this.values = new HashMap<>();
this.values = new LinkedHashMap<>();
this.fuzzy = false;
}
@ -62,6 +65,34 @@ public class BlockState implements BlockStateHolder<BlockState> {
this.fuzzy = true;
}
public static Map<Map<Property<?>, Object>, BlockState> generateStateMap(BlockType blockType) {
List<? extends Property> properties = blockType.getProperties();
List<List<Object>> valueLists = Lists.cartesianProduct(properties.stream().map(Property::getValues).collect(Collectors.toList()));
Map<Map<Property<?>, Object>, BlockState> stateMap = new LinkedHashMap<>();
for (int i = 0; i < valueLists.size(); i++) {
List<Object> valueList = valueLists.get(i);
Property<?> property = properties.get(i);
LinkedHashMap<Property<?>, Object> valueMap = new LinkedHashMap<>();
BlockState stateMaker = new BlockState(blockType);
for (Object value : valueList) {
valueMap.put(property, value);
stateMaker.setState(property, value);
}
stateMap.put(valueMap, stateMaker);
}
if (stateMap.isEmpty()) {
// No properties.
stateMap.put(new LinkedHashMap<>(), new BlockState(blockType));
}
for (BlockState state : stateMap.values()) {
state.populate(stateMap);
}
return stateMap;
}
public void populate(Map<Map<Property<?>, Object>, BlockState> stateMap) {
final Table<Property<?>, Object, BlockState> states = HashBasedTable.create();
@ -154,7 +185,7 @@ public class BlockState implements BlockStateHolder<BlockState> {
* @param value The value
* @return The blockstate, for chaining
*/
private <V> BlockState setState(final Property<V> property, final V value) {
private BlockState setState(final Property<?> property, final Object value) {
this.values.put(property, value);
return this;
}

View File

@ -19,15 +19,21 @@
package com.sk89q.worldedit.world.block;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.blocks.BlockMaterial;
import com.sk89q.worldedit.extension.platform.Capability;
import com.sk89q.worldedit.registry.NamespacedRegistry;
import com.sk89q.worldedit.registry.state.Property;
import com.sk89q.worldedit.world.item.ItemType;
import com.sk89q.worldedit.world.item.ItemTypes;
import com.sk89q.worldedit.world.registry.BundledBlockData;
import com.sk89q.worldedit.world.registry.LegacyMapper;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import javax.annotation.Nullable;
@ -38,6 +44,8 @@ public class BlockType {
private String id;
private BlockState defaultState;
private Map<String, ? extends Property> properties;
private BlockMaterial blockMaterial;
public BlockType(String id) {
this(id, null);
@ -49,7 +57,7 @@ public class BlockType {
id = "minecraft:" + id;
}
this.id = id;
this.defaultState = new BlockState(this);
this.defaultState = new ArrayList<>(BlockState.generateStateMap(this).values()).get(0);
if (values != null) {
this.defaultState = values.apply(this.defaultState);
}
@ -78,6 +86,28 @@ public class BlockType {
}
}
/**
* Gets the properties of this BlockType in a key->property mapping.
*
* @return The properties map
*/
public Map<String, ? extends Property> getPropertyMap() {
if (properties == null) {
properties = ImmutableMap.copyOf(WorldEdit.getInstance().getPlatformManager()
.queryCapability(Capability.GAME_HOOKS).getRegistries().getBlockRegistry().getProperties(this));
}
return this.properties;
}
/**
* Gets the properties of this BlockType.
*
* @return the properties
*/
public List<? extends Property> getProperties() {
return ImmutableList.copyOf(this.getPropertyMap().values());
}
/**
* Gets the default state of this block type.
*
@ -112,7 +142,10 @@ public class BlockType {
* @return The material
*/
public BlockMaterial getMaterial() {
return WorldEdit.getInstance().getPlatformManager().queryCapability(Capability.GAME_HOOKS).getRegistries().getBlockRegistry().getMaterial(this.id);
if (this.blockMaterial == null) {
this.blockMaterial = WorldEdit.getInstance().getPlatformManager().queryCapability(Capability.GAME_HOOKS).getRegistries().getBlockRegistry().getMaterial(this);
}
return this.blockMaterial;
}
/**