geforkt von Mirrors/FastAsyncWorldEdit
Make some BlockType fields lazy, to avoid early Platform dependencies
Dieser Commit ist enthalten in:
Ursprung
79a4121098
Commit
d0ea5121f2
@ -19,6 +19,8 @@
|
|||||||
|
|
||||||
package com.sk89q.worldedit.world.block;
|
package com.sk89q.worldedit.world.block;
|
||||||
|
|
||||||
|
import static com.google.common.base.Preconditions.checkArgument;
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
import com.sk89q.worldedit.WorldEdit;
|
import com.sk89q.worldedit.WorldEdit;
|
||||||
@ -34,7 +36,9 @@ import com.sk89q.worldedit.world.registry.LegacyMapper;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
@ -42,11 +46,12 @@ public class BlockType {
|
|||||||
|
|
||||||
public static final NamespacedRegistry<BlockType> REGISTRY = new NamespacedRegistry<>("block type");
|
public static final NamespacedRegistry<BlockType> REGISTRY = new NamespacedRegistry<>("block type");
|
||||||
|
|
||||||
private String id;
|
private final String id;
|
||||||
private BlockState defaultState;
|
private final Function<BlockState, BlockState> values;
|
||||||
private Map<String, ? extends Property> properties;
|
private final AtomicReference<BlockState> defaultState = new AtomicReference<>();
|
||||||
private BlockMaterial blockMaterial;
|
private final AtomicReference<Map<String, ? extends Property>> properties = new AtomicReference<>();
|
||||||
private Map<Map<Property<?>, Object>, BlockState> blockStatesMap;
|
private final AtomicReference<BlockMaterial> blockMaterial = new AtomicReference<>();
|
||||||
|
private final AtomicReference<Map<Map<Property<?>, Object>, BlockState>> blockStatesMap = new AtomicReference<>();
|
||||||
|
|
||||||
public BlockType(String id) {
|
public BlockType(String id) {
|
||||||
this(id, null);
|
this(id, null);
|
||||||
@ -58,11 +63,37 @@ public class BlockType {
|
|||||||
id = "minecraft:" + id;
|
id = "minecraft:" + id;
|
||||||
}
|
}
|
||||||
this.id = id;
|
this.id = id;
|
||||||
this.blockStatesMap = BlockState.generateStateMap(this);
|
this.values = values;
|
||||||
this.defaultState = new ArrayList<>(this.blockStatesMap.values()).get(0);
|
}
|
||||||
if (values != null) {
|
|
||||||
this.defaultState = values.apply(this.defaultState);
|
private <T> T updateField(AtomicReference<T> field, Supplier<T> value) {
|
||||||
|
T result = field.get();
|
||||||
|
if (result == null) {
|
||||||
|
// swap in new value, if someone doesn't beat us
|
||||||
|
T update = value.get();
|
||||||
|
if (field.compareAndSet(null, update)) {
|
||||||
|
// use ours
|
||||||
|
result = update;
|
||||||
|
} else {
|
||||||
|
// update to real value
|
||||||
|
result = field.get();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Map<Map<Property<?>, Object>, BlockState> getBlockStatesMap() {
|
||||||
|
return updateField(blockStatesMap, () -> BlockState.generateStateMap(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
private BlockState getDefaultStateMemoized() {
|
||||||
|
return updateField(defaultState, () -> {
|
||||||
|
BlockState defaultState = new ArrayList<>(getBlockStatesMap().values()).get(0);
|
||||||
|
if (values != null) {
|
||||||
|
defaultState = values.apply(defaultState);
|
||||||
|
}
|
||||||
|
return defaultState;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -94,11 +125,8 @@ public class BlockType {
|
|||||||
* @return The properties map
|
* @return The properties map
|
||||||
*/
|
*/
|
||||||
public Map<String, ? extends Property> getPropertyMap() {
|
public Map<String, ? extends Property> getPropertyMap() {
|
||||||
if (properties == null) {
|
return updateField(properties, () -> ImmutableMap.copyOf(WorldEdit.getInstance().getPlatformManager()
|
||||||
properties = ImmutableMap.copyOf(WorldEdit.getInstance().getPlatformManager()
|
.queryCapability(Capability.GAME_HOOKS).getRegistries().getBlockRegistry().getProperties(this)));
|
||||||
.queryCapability(Capability.GAME_HOOKS).getRegistries().getBlockRegistry().getProperties(this));
|
|
||||||
}
|
|
||||||
return this.properties;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -117,7 +145,9 @@ public class BlockType {
|
|||||||
* @return The property
|
* @return The property
|
||||||
*/
|
*/
|
||||||
public <V> Property<V> getProperty(String name) {
|
public <V> Property<V> getProperty(String name) {
|
||||||
return getPropertyMap().get(name);
|
Property<V> property = getPropertyMap().get(name);
|
||||||
|
checkArgument(property != null, "%s has no property named %s", this, name);
|
||||||
|
return property;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -126,7 +156,7 @@ public class BlockType {
|
|||||||
* @return The default state
|
* @return The default state
|
||||||
*/
|
*/
|
||||||
public BlockState getDefaultState() {
|
public BlockState getDefaultState() {
|
||||||
return this.defaultState;
|
return getDefaultStateMemoized();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -135,7 +165,7 @@ public class BlockType {
|
|||||||
* @return All possible states
|
* @return All possible states
|
||||||
*/
|
*/
|
||||||
public List<BlockState> getAllStates() {
|
public List<BlockState> getAllStates() {
|
||||||
return ImmutableList.copyOf(this.blockStatesMap.values());
|
return ImmutableList.copyOf(getBlockStatesMap().values());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -163,10 +193,8 @@ public class BlockType {
|
|||||||
* @return The material
|
* @return The material
|
||||||
*/
|
*/
|
||||||
public BlockMaterial getMaterial() {
|
public BlockMaterial getMaterial() {
|
||||||
if (this.blockMaterial == null) {
|
return updateField(blockMaterial, () -> WorldEdit.getInstance().getPlatformManager()
|
||||||
this.blockMaterial = WorldEdit.getInstance().getPlatformManager().queryCapability(Capability.GAME_HOOKS).getRegistries().getBlockRegistry().getMaterial(this);
|
.queryCapability(Capability.GAME_HOOKS).getRegistries().getBlockRegistry().getMaterial(this));
|
||||||
}
|
|
||||||
return this.blockMaterial;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren