Add model predicate flattening
This commit is contained in:
parent
6b28cb5ebc
commit
f2de12329e
|
|
@ -35,6 +35,7 @@ public class ModernFixEarlyConfig {
|
||||||
this.addMixinRule("perf.parallel_blockstate_cache_rebuild", true);
|
this.addMixinRule("perf.parallel_blockstate_cache_rebuild", true);
|
||||||
this.addMixinRule("perf.compress_biome_container", true);
|
this.addMixinRule("perf.compress_biome_container", true);
|
||||||
this.addMixinRule("perf.nuke_empty_chunk_sections", true);
|
this.addMixinRule("perf.nuke_empty_chunk_sections", true);
|
||||||
|
this.addMixinRule("perf.flatten_model_predicates", true);
|
||||||
this.addMixinRule("perf.deduplicate_location", true);
|
this.addMixinRule("perf.deduplicate_location", true);
|
||||||
this.addMixinRule("safety", true);
|
this.addMixinRule("safety", true);
|
||||||
this.addMixinRule("launch.transformer_cache", false);
|
this.addMixinRule("launch.transformer_cache", false);
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,32 @@
|
||||||
|
package org.embeddedt.modernfix.mixin.perf.flatten_model_predicates;
|
||||||
|
|
||||||
|
import com.google.common.collect.Streams;
|
||||||
|
import net.minecraft.block.Block;
|
||||||
|
import net.minecraft.block.BlockState;
|
||||||
|
import net.minecraft.client.renderer.model.multipart.AndCondition;
|
||||||
|
import net.minecraft.client.renderer.model.multipart.ICondition;
|
||||||
|
import net.minecraft.state.StateContainer;
|
||||||
|
import org.embeddedt.modernfix.predicate.StatePropertyPredicateHelper;
|
||||||
|
import org.spongepowered.asm.mixin.Final;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.Overwrite;
|
||||||
|
import org.spongepowered.asm.mixin.Shadow;
|
||||||
|
|
||||||
|
import java.util.function.Predicate;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
@Mixin(AndCondition.class)
|
||||||
|
public class AndConditionMixin {
|
||||||
|
@Shadow @Final private Iterable<? extends ICondition> conditions;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author JellySquid
|
||||||
|
* @reason Flatten predicates
|
||||||
|
*/
|
||||||
|
@Overwrite
|
||||||
|
public Predicate<BlockState> getPredicate(StateContainer<Block, BlockState> stateManager) {
|
||||||
|
return StatePropertyPredicateHelper.allMatch(Streams.stream(this.conditions).map((multipartModelSelector) -> {
|
||||||
|
return multipartModelSelector.getPredicate(stateManager);
|
||||||
|
}).collect(Collectors.toList()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,32 @@
|
||||||
|
package org.embeddedt.modernfix.mixin.perf.flatten_model_predicates;
|
||||||
|
|
||||||
|
import com.google.common.collect.Streams;
|
||||||
|
import net.minecraft.block.Block;
|
||||||
|
import net.minecraft.block.BlockState;
|
||||||
|
import net.minecraft.client.renderer.model.multipart.ICondition;
|
||||||
|
import net.minecraft.client.renderer.model.multipart.OrCondition;
|
||||||
|
import net.minecraft.state.StateContainer;
|
||||||
|
import org.embeddedt.modernfix.predicate.StatePropertyPredicateHelper;
|
||||||
|
import org.spongepowered.asm.mixin.Final;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.Overwrite;
|
||||||
|
import org.spongepowered.asm.mixin.Shadow;
|
||||||
|
|
||||||
|
import java.util.function.Predicate;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
@Mixin(OrCondition.class)
|
||||||
|
public class OrConditionMixin {
|
||||||
|
@Shadow @Final private Iterable<? extends ICondition> conditions;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author JellySquid
|
||||||
|
* @reason Flatten predicates
|
||||||
|
*/
|
||||||
|
@Overwrite
|
||||||
|
public Predicate<BlockState> getPredicate(StateContainer<Block, BlockState> stateManager) {
|
||||||
|
return StatePropertyPredicateHelper.anyMatch(Streams.stream(this.conditions).map((multipartModelSelector) -> {
|
||||||
|
return multipartModelSelector.getPredicate(stateManager);
|
||||||
|
}).collect(Collectors.toList()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,77 @@
|
||||||
|
package org.embeddedt.modernfix.mixin.perf.flatten_model_predicates;
|
||||||
|
|
||||||
|
import com.google.common.base.Splitter;
|
||||||
|
import net.minecraft.block.Block;
|
||||||
|
import net.minecraft.block.BlockState;
|
||||||
|
import net.minecraft.client.renderer.model.multipart.PropertyValueCondition;
|
||||||
|
import net.minecraft.state.Property;
|
||||||
|
import net.minecraft.state.StateContainer;
|
||||||
|
import org.embeddedt.modernfix.predicate.single.SingleMatchAny;
|
||||||
|
import org.embeddedt.modernfix.predicate.single.SingleMatchOne;
|
||||||
|
import org.spongepowered.asm.mixin.Final;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.Overwrite;
|
||||||
|
import org.spongepowered.asm.mixin.Shadow;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.function.Predicate;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
@Mixin(PropertyValueCondition.class)
|
||||||
|
public class PropertyValueConditionMixin {
|
||||||
|
@Shadow @Final private String key;
|
||||||
|
|
||||||
|
@Shadow @Final private String value;
|
||||||
|
|
||||||
|
@Shadow @Final private static Splitter PIPE_SPLITTER;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author JellySquid
|
||||||
|
* @reason De-duplication
|
||||||
|
*/
|
||||||
|
@Overwrite
|
||||||
|
public Predicate<BlockState> getPredicate(StateContainer<Block, BlockState> stateManager) {
|
||||||
|
Property<?> property = stateManager.getProperty(this.key);
|
||||||
|
|
||||||
|
if (property == null) {
|
||||||
|
throw new RuntimeException(String.format("Unknown property '%s' on '%s'", this.key, stateManager.getOwner().toString()));
|
||||||
|
}
|
||||||
|
|
||||||
|
String valueString = this.value;
|
||||||
|
boolean negate = !valueString.isEmpty() && valueString.charAt(0) == '!';
|
||||||
|
|
||||||
|
if (negate) {
|
||||||
|
valueString = valueString.substring(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
List<String> split = PIPE_SPLITTER.splitToList(valueString);
|
||||||
|
|
||||||
|
if (split.isEmpty()) {
|
||||||
|
throw new RuntimeException(String.format("Empty value '%s' for property '%s' on '%s'", this.value, this.key, stateManager.getOwner().toString()));
|
||||||
|
}
|
||||||
|
|
||||||
|
Predicate<BlockState> predicate;
|
||||||
|
|
||||||
|
if (split.size() == 1) {
|
||||||
|
predicate = new SingleMatchOne(property, this.getPropertyValue(stateManager, property, valueString));
|
||||||
|
} else {
|
||||||
|
predicate = SingleMatchAny.create(property, split.stream()
|
||||||
|
.map(str -> this.getPropertyValue(stateManager, property, str))
|
||||||
|
.collect(Collectors.toList()));
|
||||||
|
}
|
||||||
|
|
||||||
|
return negate ? predicate.negate() : predicate;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Object getPropertyValue(StateContainer<Block, BlockState> stateFactory, Property<?> property, String valueString) {
|
||||||
|
Object value = property.getValue(valueString)
|
||||||
|
.orElse(null);
|
||||||
|
|
||||||
|
if (value == null) {
|
||||||
|
throw new RuntimeException(String.format("Unknown value '%s' for property '%s' on '%s' in '%s'",
|
||||||
|
valueString, this.key, stateFactory.getOwner().toString(), this.value));
|
||||||
|
}
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,22 @@
|
||||||
|
package org.embeddedt.modernfix.predicate;
|
||||||
|
|
||||||
|
import java.util.function.Predicate;
|
||||||
|
|
||||||
|
public class AllPredicate<T> implements Predicate<T> {
|
||||||
|
private final Predicate<T>[] predicates;
|
||||||
|
|
||||||
|
public AllPredicate(Predicate<T>[] predicates) {
|
||||||
|
this.predicates = predicates;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean test(T t) {
|
||||||
|
for (Predicate<T> predicate : this.predicates) {
|
||||||
|
if (!predicate.test(t)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,22 @@
|
||||||
|
package org.embeddedt.modernfix.predicate;
|
||||||
|
|
||||||
|
import java.util.function.Predicate;
|
||||||
|
|
||||||
|
public class AnyPredicate<T> implements Predicate<T> {
|
||||||
|
private final Predicate<T>[] predicates;
|
||||||
|
|
||||||
|
public AnyPredicate(Predicate<T>[] predicates) {
|
||||||
|
this.predicates = predicates;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean test(T t) {
|
||||||
|
for (Predicate<T> predicate : this.predicates) {
|
||||||
|
if (predicate.test(t)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,33 @@
|
||||||
|
package org.embeddedt.modernfix.predicate;
|
||||||
|
|
||||||
|
import me.jellysquid.mods.hydrogen.common.state.all.AllMatchOneBoolean;
|
||||||
|
import net.minecraft.block.BlockState;
|
||||||
|
import org.embeddedt.modernfix.predicate.all.AllMatchOneObject;
|
||||||
|
import org.embeddedt.modernfix.predicate.any.AllMatchAnyObject;
|
||||||
|
import org.embeddedt.modernfix.predicate.single.SingleMatchAny;
|
||||||
|
import org.embeddedt.modernfix.predicate.single.SingleMatchOne;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.function.Predicate;
|
||||||
|
|
||||||
|
public class StatePropertyPredicateHelper {
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public static Predicate<BlockState> allMatch(List<Predicate<BlockState>> predicates) {
|
||||||
|
if (SingleMatchOne.areOfType(predicates)) {
|
||||||
|
if (SingleMatchOne.valuesMatchType(predicates, Boolean.class)) {
|
||||||
|
return new AllMatchOneBoolean(predicates);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new AllMatchOneObject(predicates);
|
||||||
|
} else if (SingleMatchAny.areOfType(predicates)) {
|
||||||
|
return new AllMatchAnyObject(predicates);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new AllPredicate<>(predicates.toArray(new Predicate[0]));
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public static Predicate<BlockState> anyMatch(List<Predicate<BlockState>> predicates) {
|
||||||
|
return new AnyPredicate<>(predicates.toArray(new Predicate[0]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,47 @@
|
||||||
|
package me.jellysquid.mods.hydrogen.common.state.all;
|
||||||
|
|
||||||
|
import net.minecraft.block.BlockState;
|
||||||
|
import net.minecraft.state.Property;
|
||||||
|
import org.embeddedt.modernfix.predicate.single.SingleMatchOne;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.function.Predicate;
|
||||||
|
|
||||||
|
public class AllMatchOneBoolean implements Predicate<BlockState> {
|
||||||
|
private final Property<?>[] properties;
|
||||||
|
private final boolean[] values;
|
||||||
|
|
||||||
|
public AllMatchOneBoolean(List<Predicate<BlockState>> list) {
|
||||||
|
int size = list.size();
|
||||||
|
|
||||||
|
this.properties = new Property[size];
|
||||||
|
this.values = new boolean[size];
|
||||||
|
|
||||||
|
for (int i = 0; i < size; i++) {
|
||||||
|
SingleMatchOne predicate = (SingleMatchOne) list.get(i);
|
||||||
|
|
||||||
|
this.properties[i] = predicate.property;
|
||||||
|
this.values[i] = (boolean) predicate.value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean canReplace(List<Predicate<BlockState>> list) {
|
||||||
|
return list.stream()
|
||||||
|
.allMatch(p -> {
|
||||||
|
return p instanceof SingleMatchOne && ((SingleMatchOne) p).value instanceof Boolean;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean test(BlockState blockState) {
|
||||||
|
for (int i = 0; i < this.properties.length; i++) {
|
||||||
|
Boolean value = (Boolean) blockState.getValue(this.properties[i]);
|
||||||
|
|
||||||
|
if (value != this.values[i]) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,38 @@
|
||||||
|
package org.embeddedt.modernfix.predicate.all;
|
||||||
|
|
||||||
|
import net.minecraft.block.BlockState;
|
||||||
|
import net.minecraft.state.Property;
|
||||||
|
import org.embeddedt.modernfix.predicate.single.SingleMatchOne;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.function.Predicate;
|
||||||
|
|
||||||
|
public class AllMatchOneObject implements Predicate<BlockState> {
|
||||||
|
private final Property<?>[] properties;
|
||||||
|
private final Object[] values;
|
||||||
|
|
||||||
|
public AllMatchOneObject(List<Predicate<BlockState>> list) {
|
||||||
|
int size = list.size();
|
||||||
|
|
||||||
|
this.properties = new Property[size];
|
||||||
|
this.values = new Object[size];
|
||||||
|
|
||||||
|
for (int i = 0; i < size; i++) {
|
||||||
|
SingleMatchOne predicate = (SingleMatchOne) list.get(i);
|
||||||
|
|
||||||
|
this.properties[i] = predicate.property;
|
||||||
|
this.values[i] = predicate.value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean test(BlockState blockState) {
|
||||||
|
for (int i = 0; i < this.properties.length; i++) {
|
||||||
|
if (blockState.getValue(this.properties[i]) != this.values[i]) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,39 @@
|
||||||
|
package org.embeddedt.modernfix.predicate.any;
|
||||||
|
|
||||||
|
import net.minecraft.block.BlockState;
|
||||||
|
import net.minecraft.state.Property;
|
||||||
|
import org.apache.commons.lang3.ArrayUtils;
|
||||||
|
import org.embeddedt.modernfix.predicate.single.SingleMatchAny;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.function.Predicate;
|
||||||
|
|
||||||
|
public class AllMatchAnyObject implements Predicate<BlockState> {
|
||||||
|
private final Property<?>[] properties;
|
||||||
|
private final Object[][] values;
|
||||||
|
|
||||||
|
public AllMatchAnyObject(List<Predicate<BlockState>> list) {
|
||||||
|
int size = list.size();
|
||||||
|
|
||||||
|
this.properties = new Property[size];
|
||||||
|
this.values = new Object[size][];
|
||||||
|
|
||||||
|
for (int i = 0; i < size; i++) {
|
||||||
|
SingleMatchAny predicate = (SingleMatchAny) list.get(i);
|
||||||
|
|
||||||
|
this.properties[i] = predicate.property;
|
||||||
|
this.values[i] = predicate.values;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean test(BlockState blockState) {
|
||||||
|
for (int i = 0; i < this.properties.length; i++) {
|
||||||
|
if (!ArrayUtils.contains(this.values[i], blockState.getValue(this.properties[i]))) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,63 @@
|
||||||
|
package org.embeddedt.modernfix.predicate.single;
|
||||||
|
|
||||||
|
import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet;
|
||||||
|
import net.minecraft.block.BlockState;
|
||||||
|
import net.minecraft.state.Property;
|
||||||
|
import org.apache.commons.lang3.ArrayUtils;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.function.Predicate;
|
||||||
|
|
||||||
|
public class SingleMatchAny implements Predicate<BlockState> {
|
||||||
|
public static final ObjectOpenHashSet<SingleMatchAny> PREDICATES = new ObjectOpenHashSet<>();
|
||||||
|
|
||||||
|
public final Property<?> property;
|
||||||
|
public final Object[] values;
|
||||||
|
|
||||||
|
private SingleMatchAny(Property<?> property, List<Object> values) {
|
||||||
|
this.property = property;
|
||||||
|
this.values = values.toArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static SingleMatchAny create(Property<?> property, List<Object> values) {
|
||||||
|
return PREDICATES.addOrGet(new SingleMatchAny(property, values));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean areOfType(List<Predicate<BlockState>> predicates) {
|
||||||
|
return predicates.stream()
|
||||||
|
.allMatch(p -> {
|
||||||
|
return p instanceof SingleMatchAny;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean valuesMatchType(List<Predicate<BlockState>> predicates, Class<?> type) {
|
||||||
|
return predicates.stream()
|
||||||
|
.allMatch(p -> {
|
||||||
|
return p instanceof SingleMatchAny &&
|
||||||
|
Arrays.stream(((SingleMatchAny) p).values).allMatch(t -> type.isInstance(p));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean test(BlockState blockState) {
|
||||||
|
return ArrayUtils.contains(this.values, blockState.getValue(this.property));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) return true;
|
||||||
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
|
SingleMatchAny that = (SingleMatchAny) o;
|
||||||
|
return Objects.equals(property, that.property) &&
|
||||||
|
Arrays.equals(values, that.values);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
int result = Objects.hash(property);
|
||||||
|
result = 31 * result + Arrays.hashCode(values);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,36 @@
|
||||||
|
package org.embeddedt.modernfix.predicate.single;
|
||||||
|
|
||||||
|
import net.minecraft.block.BlockState;
|
||||||
|
import net.minecraft.state.Property;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.function.Predicate;
|
||||||
|
|
||||||
|
public class SingleMatchOne implements Predicate<BlockState> {
|
||||||
|
public final Property<?> property;
|
||||||
|
public final Object value;
|
||||||
|
|
||||||
|
public SingleMatchOne(Property<?> property, Object value) {
|
||||||
|
this.property = property;
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean areOfType(List<Predicate<BlockState>> predicates) {
|
||||||
|
return predicates.stream()
|
||||||
|
.allMatch(p -> {
|
||||||
|
return p instanceof SingleMatchOne;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean valuesMatchType(List<Predicate<BlockState>> predicates, Class<?> type) {
|
||||||
|
return predicates.stream()
|
||||||
|
.allMatch(p -> {
|
||||||
|
return p instanceof SingleMatchOne && type.isInstance(((SingleMatchOne) p).value);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean test(BlockState blockState) {
|
||||||
|
return blockState.getValue(this.property) == this.value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -7,7 +7,6 @@
|
||||||
"refmap": "modernfix.refmap.json",
|
"refmap": "modernfix.refmap.json",
|
||||||
"mixins": [
|
"mixins": [
|
||||||
"bugfix.edge_chunk_not_saved.ChunkManagerMixin",
|
"bugfix.edge_chunk_not_saved.ChunkManagerMixin",
|
||||||
"feature.measure_time.MinecraftMixin",
|
|
||||||
"perf.remove_biome_temperature_cache.BiomeMixin",
|
"perf.remove_biome_temperature_cache.BiomeMixin",
|
||||||
"perf.resourcepacks.ModFileResourcePackMixin",
|
"perf.resourcepacks.ModFileResourcePackMixin",
|
||||||
"perf.resourcepacks.VanillaPackMixin",
|
"perf.resourcepacks.VanillaPackMixin",
|
||||||
|
|
@ -28,6 +27,7 @@
|
||||||
"perf.nuke_empty_chunk_sections.MixinChunk"
|
"perf.nuke_empty_chunk_sections.MixinChunk"
|
||||||
],
|
],
|
||||||
"client": [
|
"client": [
|
||||||
|
"feature.measure_time.MinecraftMixin",
|
||||||
"perf.skip_first_datapack_reload.MinecraftMixin",
|
"perf.skip_first_datapack_reload.MinecraftMixin",
|
||||||
"bugfix.concurrency.RenderTypeMixin",
|
"bugfix.concurrency.RenderTypeMixin",
|
||||||
"bugfix.concurrency.MinecraftMixin",
|
"bugfix.concurrency.MinecraftMixin",
|
||||||
|
|
@ -40,7 +40,10 @@
|
||||||
"perf.async_jei.PluginCallerMixin",
|
"perf.async_jei.PluginCallerMixin",
|
||||||
"perf.async_jei.RecipeManagerInternalMixin",
|
"perf.async_jei.RecipeManagerInternalMixin",
|
||||||
"perf.thread_priorities.IntegratedServerMixin",
|
"perf.thread_priorities.IntegratedServerMixin",
|
||||||
"safety.BlockColorsMixin"
|
"safety.BlockColorsMixin",
|
||||||
|
"perf.flatten_model_predicates.AndConditionMixin",
|
||||||
|
"perf.flatten_model_predicates.OrConditionMixin",
|
||||||
|
"perf.flatten_model_predicates.PropertyValueConditionMixin"
|
||||||
],
|
],
|
||||||
"injectors": {
|
"injectors": {
|
||||||
"defaultRequire": 1
|
"defaultRequire": 1
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user