Skip to content

Commit

Permalink
Make some BlockType fields lazy, to avoid early Platform dependencies
Browse files Browse the repository at this point in the history
  • Loading branch information
octylFractal committed Oct 5, 2018
1 parent 79a4121 commit d0ea512
Showing 1 changed file with 49 additions and 21 deletions.
Expand Up @@ -19,6 +19,8 @@

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.ImmutableMap;
import com.sk89q.worldedit.WorldEdit;
Expand All @@ -34,19 +36,22 @@
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Function;
import java.util.function.Supplier;

import javax.annotation.Nullable;

public class BlockType {

public static final NamespacedRegistry<BlockType> REGISTRY = new NamespacedRegistry<>("block type");

private String id;
private BlockState defaultState;
private Map<String, ? extends Property> properties;
private BlockMaterial blockMaterial;
private Map<Map<Property<?>, Object>, BlockState> blockStatesMap;
private final String id;
private final Function<BlockState, BlockState> values;
private final AtomicReference<BlockState> defaultState = new AtomicReference<>();
private final AtomicReference<Map<String, ? extends Property>> properties = new AtomicReference<>();
private final AtomicReference<BlockMaterial> blockMaterial = new AtomicReference<>();
private final AtomicReference<Map<Map<Property<?>, Object>, BlockState>> blockStatesMap = new AtomicReference<>();

public BlockType(String id) {
this(id, null);
Expand All @@ -58,11 +63,37 @@ public BlockType(String id, Function<BlockState, BlockState> values) {
id = "minecraft:" + id;
}
this.id = id;
this.blockStatesMap = BlockState.generateStateMap(this);
this.defaultState = new ArrayList<>(this.blockStatesMap.values()).get(0);
if (values != null) {
this.defaultState = values.apply(this.defaultState);
this.values = values;
}

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;
});
}

/**
Expand Down Expand Up @@ -94,11 +125,8 @@ public String getName() {
* @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;
return updateField(properties, () -> ImmutableMap.copyOf(WorldEdit.getInstance().getPlatformManager()
.queryCapability(Capability.GAME_HOOKS).getRegistries().getBlockRegistry().getProperties(this)));
}

/**
Expand All @@ -117,7 +145,9 @@ public List<? extends Property> getProperties() {
* @return The property
*/
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;
}

/**
Expand All @@ -126,7 +156,7 @@ public <V> Property<V> getProperty(String name) {
* @return The default state
*/
public BlockState getDefaultState() {
return this.defaultState;
return getDefaultStateMemoized();
}

/**
Expand All @@ -135,7 +165,7 @@ public BlockState getDefaultState() {
* @return All possible states
*/
public List<BlockState> getAllStates() {
return ImmutableList.copyOf(this.blockStatesMap.values());
return ImmutableList.copyOf(getBlockStatesMap().values());
}

/**
Expand Down Expand Up @@ -163,10 +193,8 @@ public ItemType getItemType() {
* @return The material
*/
public BlockMaterial getMaterial() {
if (this.blockMaterial == null) {
this.blockMaterial = WorldEdit.getInstance().getPlatformManager().queryCapability(Capability.GAME_HOOKS).getRegistries().getBlockRegistry().getMaterial(this);
}
return this.blockMaterial;
return updateField(blockMaterial, () -> WorldEdit.getInstance().getPlatformManager()
.queryCapability(Capability.GAME_HOOKS).getRegistries().getBlockRegistry().getMaterial(this));
}

/**
Expand Down

0 comments on commit d0ea512

Please sign in to comment.