Lazily initialize block tags

This commit is contained in:
Hannes Greule 2020-05-04 16:24:04 +02:00 committed by dordsor21
parent a8621a15ad
commit 2c060db9c0
3 changed files with 52 additions and 14 deletions

View File

@ -42,6 +42,7 @@ import com.plotsquared.core.plot.flag.FlagContainer;
import com.plotsquared.core.plot.flag.FlagParseException; import com.plotsquared.core.plot.flag.FlagParseException;
import com.plotsquared.core.plot.flag.GlobalFlagContainer; import com.plotsquared.core.plot.flag.GlobalFlagContainer;
import com.plotsquared.core.plot.flag.PlotFlag; import com.plotsquared.core.plot.flag.PlotFlag;
import com.plotsquared.core.plot.flag.types.BlockTypeListFlag;
import com.plotsquared.core.util.MainUtil; import com.plotsquared.core.util.MainUtil;
import com.plotsquared.core.util.StringMan; import com.plotsquared.core.util.StringMan;
import com.plotsquared.core.util.task.RunnableVal; import com.plotsquared.core.util.task.RunnableVal;
@ -1962,6 +1963,7 @@ public class SQLManager implements AbstractDB {
try (final ResultSet resultSet = statement try (final ResultSet resultSet = statement
.executeQuery("SELECT * FROM `" + this.prefix + "plot_flags`")) { .executeQuery("SELECT * FROM `" + this.prefix + "plot_flags`")) {
BlockTypeListFlag.skipCategoryVerification = true; // allow invalid tags, as initialized lazily
final ArrayList<Integer> toDelete = new ArrayList<>(); final ArrayList<Integer> toDelete = new ArrayList<>();
final Map<Plot, Collection<PlotFlag<?, ?>>> invalidFlags = new HashMap<>(); final Map<Plot, Collection<PlotFlag<?, ?>>> invalidFlags = new HashMap<>();
while (resultSet.next()) { while (resultSet.next()) {
@ -1979,6 +1981,7 @@ public class SQLManager implements AbstractDB {
try { try {
plot.getFlagContainer().addFlag(plotFlag.parse(value)); plot.getFlagContainer().addFlag(plotFlag.parse(value));
} catch (final FlagParseException e) { } catch (final FlagParseException e) {
e.printStackTrace();
PlotSquared PlotSquared
.debug("Plot with ID " + id + " has an invalid value:"); .debug("Plot with ID " + id + " has an invalid value:");
PlotSquared.debug(Captions.FLAG_PARSE_ERROR.getTranslated() PlotSquared.debug(Captions.FLAG_PARSE_ERROR.getTranslated()
@ -1998,6 +2001,7 @@ public class SQLManager implements AbstractDB {
+ " in `plot_flags` does not exist. Create this plot or set `database-purger: true` in the settings.yml."); + " in `plot_flags` does not exist. Create this plot or set `database-purger: true` in the settings.yml.");
} }
} }
BlockTypeListFlag.skipCategoryVerification = false; // don't allow invalid tags anymore
if (Settings.Enabled_Components.DATABASE_PURGER) { if (Settings.Enabled_Components.DATABASE_PURGER) {
for (final Map.Entry<Plot, Collection<PlotFlag<?, ?>>> plotFlagEntry : invalidFlags for (final Map.Entry<Plot, Collection<PlotFlag<?, ?>>> plotFlagEntry : invalidFlags
.entrySet()) { .entrySet()) {

View File

@ -42,6 +42,8 @@ import java.util.stream.Collectors;
public abstract class BlockTypeListFlag<F extends ListFlag<BlockTypeWrapper, F>> public abstract class BlockTypeListFlag<F extends ListFlag<BlockTypeWrapper, F>>
extends ListFlag<BlockTypeWrapper, F> { extends ListFlag<BlockTypeWrapper, F> {
public static boolean skipCategoryVerification = false;
protected BlockTypeListFlag(List<BlockTypeWrapper> blockTypeList, Caption description) { protected BlockTypeListFlag(List<BlockTypeWrapper> blockTypeList, Caption description) {
super(blockTypeList, Captions.FLAG_CATEGORY_BLOCK_LIST, description); super(blockTypeList, Captions.FLAG_CATEGORY_BLOCK_LIST, description);
} }
@ -57,15 +59,7 @@ public abstract class BlockTypeListFlag<F extends ListFlag<BlockTypeWrapper, F>>
final BlockState blockState = BlockUtil.get(blockString); final BlockState blockState = BlockUtil.get(blockString);
if (blockState == null) { if (blockState == null) {
// If it's not a block state, we assume it's a block category // If it's not a block state, we assume it's a block category
final BlockCategory blockCategory; blockTypeWrapper = getCategory(blockString);
if (!blockString.startsWith("#")
|| (blockCategory = BlockCategory.REGISTRY.get(blockString.substring(1)))
== null) {
throw new FlagParseException(this, blockString,
Captions.FLAG_ERROR_INVALID_BLOCK);
} else {
blockTypeWrapper = BlockTypeWrapper.get(blockCategory);
}
} else { } else {
blockTypeWrapper = BlockTypeWrapper.get(blockState.getBlockType()); blockTypeWrapper = BlockTypeWrapper.get(blockState.getBlockType());
} }
@ -91,4 +85,24 @@ public abstract class BlockTypeListFlag<F extends ListFlag<BlockTypeWrapper, F>>
return tabCompletions; return tabCompletions;
} }
private BlockTypeWrapper getCategory(final String blockString) throws FlagParseException {
if (!blockString.startsWith("#")) {
throw new FlagParseException(this, blockString,
Captions.FLAG_ERROR_INVALID_BLOCK);
}
String categoryId = blockString.substring(1);
BlockTypeWrapper blockTypeWrapper;
if (skipCategoryVerification) {
blockTypeWrapper = BlockTypeWrapper.get(categoryId);
} else {
BlockCategory blockCategory = BlockCategory.REGISTRY.get(categoryId);
if (blockCategory == null) {
throw new FlagParseException(this, blockString,
Captions.FLAG_ERROR_INVALID_BLOCK);
}
blockTypeWrapper = BlockTypeWrapper.get(blockCategory);
}
return blockTypeWrapper;
}
} }

View File

@ -44,16 +44,25 @@ import java.util.Map;
public class BlockTypeWrapper { public class BlockTypeWrapper {
@Nullable @Getter private final BlockType blockType; @Nullable @Getter private final BlockType blockType;
@Nullable @Getter private final BlockCategory blockCategory; @Nullable private BlockCategory blockCategory;
@Nullable private final String blockCategoryId;
private BlockTypeWrapper(@NotNull final BlockType blockType) { private BlockTypeWrapper(@NotNull final BlockType blockType) {
this.blockType = Preconditions.checkNotNull(blockType); this.blockType = Preconditions.checkNotNull(blockType);
this.blockCategory = null; this.blockCategory = null;
this.blockCategoryId = null;
} }
private BlockTypeWrapper(@NotNull final BlockCategory blockCategory) { private BlockTypeWrapper(@NotNull final BlockCategory blockCategory) {
this.blockType = null; this.blockType = null;
this.blockCategory = Preconditions.checkNotNull(blockCategory); this.blockCategory = Preconditions.checkNotNull(blockCategory);
this.blockCategoryId = null;
}
public BlockTypeWrapper(@Nullable String blockCategoryId) {
this.blockType = null;
this.blockCategoryId = blockCategoryId;
this.blockCategory = null;
} }
@Override public String toString() { @Override public String toString() {
@ -64,8 +73,8 @@ public class BlockTypeWrapper {
} else { } else {
return key; return key;
} }
} else if (this.blockCategory != null) { } else if (this.getBlockCategory() != null) { // calling the method will initialize it lazily
final String key = this.blockCategory.toString(); final String key = this.getBlockCategory().toString();
if (key.startsWith("minecraft:")) { if (key.startsWith("minecraft:")) {
return '#' + key.substring(10); return '#' + key.substring(10);
} else { } else {
@ -86,15 +95,26 @@ public class BlockTypeWrapper {
} }
} }
public BlockCategory getBlockCategory() {
if (this.blockCategory == null && this.blockCategoryId != null) { // only if name is available
this.blockCategory = Preconditions.checkNotNull(BlockCategory.REGISTRY.get(this.blockCategoryId));
}
return this.blockCategory;
}
private static final Map<BlockType, BlockTypeWrapper> blockTypes = new HashMap<>(); private static final Map<BlockType, BlockTypeWrapper> blockTypes = new HashMap<>();
private static final Map<BlockCategory, BlockTypeWrapper> blockCategories = new HashMap<>(); private static final Map<String, BlockTypeWrapper> blockCategories = new HashMap<>();
public static BlockTypeWrapper get(final BlockType blockType) { public static BlockTypeWrapper get(final BlockType blockType) {
return blockTypes.computeIfAbsent(blockType, BlockTypeWrapper::new); return blockTypes.computeIfAbsent(blockType, BlockTypeWrapper::new);
} }
public static BlockTypeWrapper get(final BlockCategory blockCategory) { public static BlockTypeWrapper get(final BlockCategory blockCategory) {
return blockCategories.computeIfAbsent(blockCategory, BlockTypeWrapper::new); return blockCategories.computeIfAbsent(blockCategory.getId(), id -> new BlockTypeWrapper(blockCategory));
}
public static BlockTypeWrapper get(final String blockCategoryId) {
return blockCategories.computeIfAbsent(blockCategoryId, BlockTypeWrapper::new);
} }
} }