9
0
mirror of https://github.com/Xiao-MoMi/craft-engine.git synced 2025-12-31 21:06:31 +00:00

重构模板参数注册

This commit is contained in:
XiaoMoMi
2025-12-27 22:45:44 +08:00
parent 95c35067ad
commit 988f709c57
19 changed files with 143 additions and 138 deletions

View File

@@ -13,7 +13,7 @@ public final class EnumProperty<T extends Enum<T>> extends Property<T> {
private final int[] ordinalToIndex;
private final int[] idLookupTable;
public EnumProperty(String name, Class<T> type, List<T> values, T defaultValue) {
private EnumProperty(String name, Class<T> type, List<T> values, T defaultValue) {
super(name, type, defaultValue);
this.values = List.copyOf(values);
T[] enums = type.getEnumConstants();

View File

@@ -16,7 +16,7 @@ public final class StringProperty extends Property<String> {
private final List<String> values;
private final ImmutableMap<String, String> names;
public StringProperty(String name, List<String> values, String defaultValue) {
private StringProperty(String name, List<String> values, String defaultValue) {
super(name, String.class, defaultValue);
this.values = List.copyOf(values);

View File

@@ -311,9 +311,9 @@ public class TemplateManagerImpl implements TemplateManager {
Object processedPlaceholderValue = processUnknownValue(argumentEntry.getValue(), result);
switch (processedPlaceholderValue) {
case Map<?, ?> map -> result.put(placeholder, TemplateArguments.fromMap(MiscUtils.castToMap(map, false)));
case List<?> listArgument -> result.put(placeholder, new ListTemplateArgument((List<Object>) listArgument));
case List<?> listArgument -> result.put(placeholder, ListTemplateArgument.list((List<Object>) listArgument));
case null -> result.put(placeholder, NullTemplateArgument.INSTANCE);
default -> result.put(placeholder, new ObjectTemplateArgument(processedPlaceholderValue));
default -> result.put(placeholder, ObjectTemplateArgument.object(processedPlaceholderValue));
}
}
return result;

View File

@@ -5,17 +5,21 @@ import net.momirealms.craftengine.core.util.ResourceConfigUtils;
import java.util.Map;
public class ConditionTemplateArgument implements TemplateArgument {
public static final Factory FACTORY = new Factory();
public final class ConditionTemplateArgument implements TemplateArgument {
public static final Key ID = Key.of("craftengine:condition");
public static final TemplateArgumentFactory FACTORY = new Factory();
private final TemplateArgument result;
private ConditionTemplateArgument(TemplateArgument result) {
this.result = result;
}
@Override
public Key type() {
return TemplateArguments.CONDITION;
public TemplateArgument result() {
return this.result;
}
public static ConditionTemplateArgument condition(final TemplateArgument result) {
return new ConditionTemplateArgument(result);
}
@Override
@@ -23,7 +27,7 @@ public class ConditionTemplateArgument implements TemplateArgument {
return this.result.get(arguments);
}
public static class Factory implements TemplateArgumentFactory {
private static class Factory implements TemplateArgumentFactory {
@Override
public TemplateArgument create(Map<String, Object> arguments) {

View File

@@ -10,12 +10,13 @@ import java.util.Map;
import java.util.Optional;
import java.util.function.Function;
public class ExpressionTemplateArgument implements TemplateArgument {
public static final Factory FACTORY = new Factory();
public final class ExpressionTemplateArgument implements TemplateArgument {
public static final Key ID = Key.of("craftengine:expression");
public static final TemplateArgumentFactory FACTORY = new Factory();
private final ArgumentString expression;
private final ValueType valueType;
protected ExpressionTemplateArgument(String expression, ValueType valueType) {
private ExpressionTemplateArgument(String expression, ValueType valueType) {
this.expression = ArgumentString.preParse(expression);
this.valueType = valueType;
}
@@ -31,11 +32,6 @@ public class ExpressionTemplateArgument implements TemplateArgument {
}
}
@Override
public Key type() {
return TemplateArguments.EXPRESSION;
}
protected enum ValueType {
INT(e -> e.getNumberValue().intValue()),
LONG(e -> e.getNumberValue().longValue()),
@@ -56,7 +52,8 @@ public class ExpressionTemplateArgument implements TemplateArgument {
}
}
public static class Factory implements TemplateArgumentFactory {
private static class Factory implements TemplateArgumentFactory {
@Override
public TemplateArgument create(Map<String, Object> arguments) {
return new ExpressionTemplateArgument(

View File

@@ -7,25 +7,25 @@ import java.util.List;
import java.util.Map;
import java.util.function.Supplier;
public class ListTemplateArgument implements TemplateArgument {
public static final Factory FACTORY = new Factory();
public final class ListTemplateArgument implements TemplateArgument {
public static final Key ID = Key.of("craftengine:list");
public static final TemplateArgumentFactory FACTORY = new Factory();
private final List<Object> value;
public ListTemplateArgument(List<Object> value) {
private ListTemplateArgument(List<Object> value) {
this.value = value;
}
public static ListTemplateArgument list(List<Object> value) {
return new ListTemplateArgument(value);
}
@Override
public List<Object> get(Map<String, TemplateArgument> arguments) {
return value;
return this.value;
}
@Override
public Key type() {
return TemplateArguments.LIST;
}
public static class Factory implements TemplateArgumentFactory {
private static class Factory implements TemplateArgumentFactory {
@Override
public TemplateArgument create(Map<String, Object> arguments) {

View File

@@ -5,25 +5,29 @@ import net.momirealms.craftengine.core.util.MiscUtils;
import java.util.Map;
public class MapTemplateArgument implements TemplateArgument {
public static final Factory FACTORY = new Factory();
public final class MapTemplateArgument implements TemplateArgument {
public static final Key ID = Key.of("craftengine:map");
public static final TemplateArgumentFactory FACTORY = new Factory();
private final Map<String, Object> value;
public MapTemplateArgument(Map<String, Object> value) {
private MapTemplateArgument(Map<String, Object> value) {
this.value = value;
}
public static MapTemplateArgument map(Map<String, Object> value) {
return new MapTemplateArgument(value);
}
public Map<String, Object> value() {
return this.value;
}
@Override
public Map<String, Object> get(Map<String, TemplateArgument> arguments) {
return value;
return this.value;
}
@Override
public Key type() {
return TemplateArguments.MAP;
}
public static class Factory implements TemplateArgumentFactory {
private static class Factory implements TemplateArgumentFactory {
@Override
public TemplateArgument create(Map<String, Object> arguments) {

View File

@@ -4,24 +4,20 @@ import net.momirealms.craftengine.core.util.Key;
import java.util.Map;
public class NullTemplateArgument implements TemplateArgument {
public final class NullTemplateArgument implements TemplateArgument {
public static final Key ID = Key.of("craftengine:null");
public static final NullTemplateArgument INSTANCE = new NullTemplateArgument();
public static final Factory FACTORY = new Factory();
public static final TemplateArgumentFactory FACTORY = new Factory();
private NullTemplateArgument() {
}
@Override
public Key type() {
return TemplateArguments.NULL;
}
@Override
public Object get(Map<String, TemplateArgument> arguments) {
return null;
}
public static class Factory implements TemplateArgumentFactory {
private static class Factory implements TemplateArgumentFactory {
@Override
public TemplateArgument create(Map<String, Object> arguments) {

View File

@@ -4,24 +4,28 @@ import net.momirealms.craftengine.core.util.Key;
import java.util.Map;
public class ObjectTemplateArgument implements TemplateArgument {
public final class ObjectTemplateArgument implements TemplateArgument {
public static final Key ID = Key.of("craftengine:object");
public static final TemplateArgumentFactory FACTORY = new Factory();
private final Object value;
public ObjectTemplateArgument(Object value) {
private ObjectTemplateArgument(Object value) {
this.value = value;
}
public static ObjectTemplateArgument of(Object value) {
public static ObjectTemplateArgument object(Object value) {
return new ObjectTemplateArgument(value);
}
@Override
public Key type() {
return TemplateArguments.OBJECT;
}
@Override
public Object get(Map<String, TemplateArgument> arguments) {
return this.value;
}
private static class Factory implements TemplateArgumentFactory {
@Override
public TemplateArgument create(Map<String, Object> arguments) {
return new ObjectTemplateArgument(arguments.get("value"));
}
}
}

View File

@@ -4,29 +4,29 @@ import net.momirealms.craftengine.core.util.Key;
import java.util.Map;
public class PlainStringTemplateArgument implements TemplateArgument {
public static final Factory FACTORY = new Factory();
public final class PlainStringTemplateArgument implements TemplateArgument {
public static final Key ID = Key.of("craftengine:plain");
public static final TemplateArgumentFactory FACTORY = new Factory();
private final String value;
public PlainStringTemplateArgument(String value) {
private PlainStringTemplateArgument(String value) {
this.value = value;
}
public String value() {
return this.value;
}
public static PlainStringTemplateArgument plain(final String value) {
return new PlainStringTemplateArgument(value);
}
@Override
public String get(Map<String, TemplateArgument> arguments) {
return value;
return this.value;
}
@Override
public Key type() {
return TemplateArguments.PLAIN;
}
public static class Factory implements TemplateArgumentFactory {
private static class Factory implements TemplateArgumentFactory {
@Override
public TemplateArgument create(Map<String, Object> arguments) {
return new PlainStringTemplateArgument(arguments.getOrDefault("value", "").toString());

View File

@@ -6,8 +6,9 @@ import net.momirealms.craftengine.core.util.ResourceConfigUtils;
import java.util.Map;
public class SelfIncreaseIntTemplateArgument implements TemplateArgument {
public static final Factory FACTORY = new Factory();
public final class SelfIncreaseIntTemplateArgument implements TemplateArgument {
public static final Key ID = Key.of("craftengine:self_increase_int");
public static final TemplateArgumentFactory FACTORY = new Factory();
private final int min;
private final int max;
private int current;
@@ -38,15 +39,6 @@ public class SelfIncreaseIntTemplateArgument implements TemplateArgument {
return value;
}
@Override
public Key type() {
return TemplateArguments.SELF_INCREASE_INT;
}
public int current() {
return this.current;
}
public int min() {
return this.min;
}
@@ -55,6 +47,10 @@ public class SelfIncreaseIntTemplateArgument implements TemplateArgument {
return this.max;
}
public int current() {
return this.current;
}
public int step() {
return this.step;
}
@@ -67,7 +63,8 @@ public class SelfIncreaseIntTemplateArgument implements TemplateArgument {
return this.callCount;
}
public static class Factory implements TemplateArgumentFactory {
private static class Factory implements TemplateArgumentFactory {
@Override
public TemplateArgument create(Map<String, Object> arguments) {
int from = ResourceConfigUtils.getAsInt(arguments.get("from"), "from");

View File

@@ -1,12 +1,8 @@
package net.momirealms.craftengine.core.plugin.config.template.argument;
import net.momirealms.craftengine.core.util.Key;
import java.util.Map;
public interface TemplateArgument {
Key type();
Object get(Map<String, TemplateArgument> arguments);
}

View File

@@ -0,0 +1,6 @@
package net.momirealms.craftengine.core.plugin.config.template.argument;
import net.momirealms.craftengine.core.util.Key;
public record TemplateArgumentType(Key id, TemplateArgumentFactory factory) {
}

View File

@@ -9,58 +9,49 @@ import net.momirealms.craftengine.core.util.ResourceKey;
import java.util.List;
import java.util.Map;
public class TemplateArguments {
public static final Key PLAIN = Key.of("craftengine:plain");
public static final Key SELF_INCREASE_INT = Key.of("craftengine:self_increase_int");
public static final Key MAP = Key.of("craftengine:map");
public static final Key LIST = Key.of("craftengine:list");
public static final Key NULL = Key.of("craftengine:null");
public static final Key CONDITION = Key.of("craftengine:condition");
public static final Key EXPRESSION = Key.of("craftengine:expression");
public static final Key OBJECT = Key.of("craftengine:object"); // No Factory, internal use
public static final Key TO_UPPER_CASE = Key.of("craftengine:to_upper_case");
public static final Key TO_LOWER_CASE = Key.of("craftengine:to_lower_case");
public static final Key WHEN = Key.of("craftengine:when");
public final class TemplateArguments {
public static final TemplateArgumentType PLAIN = register(PlainStringTemplateArgument.ID, PlainStringTemplateArgument.FACTORY);
public static final TemplateArgumentType SELF_INCREASE_INT = register(SelfIncreaseIntTemplateArgument.ID, SelfIncreaseIntTemplateArgument.FACTORY);
public static final TemplateArgumentType MAP = register(MapTemplateArgument.ID, MapTemplateArgument.FACTORY);
public static final TemplateArgumentType LIST = register(ListTemplateArgument.ID, ListTemplateArgument.FACTORY);
public static final TemplateArgumentType NULL = register(NullTemplateArgument.ID, NullTemplateArgument.FACTORY);
public static final TemplateArgumentType EXPRESSION = register(ExpressionTemplateArgument.ID, ExpressionTemplateArgument.FACTORY);
public static final TemplateArgumentType CONDITION = register(ConditionTemplateArgument.ID, ConditionTemplateArgument.FACTORY);
public static final TemplateArgumentType TO_UPPER_CASE = register(ToUpperCaseTemplateArgument.ID, ToUpperCaseTemplateArgument.FACTORY);
public static final TemplateArgumentType TO_LOWER_CASE = register(ToLowerCaseTemplateArgument.ID, ToLowerCaseTemplateArgument.FACTORY);
public static final TemplateArgumentType OBJECT = register(ObjectTemplateArgument.ID, ObjectTemplateArgument.FACTORY);
public static final TemplateArgumentType WHEN = register(WhenTemplateArgument.ID, WhenTemplateArgument.FACTORY);
public static void register(Key key, TemplateArgumentFactory factory) {
((WritableRegistry<TemplateArgumentFactory>) BuiltInRegistries.TEMPLATE_ARGUMENT_FACTORY)
.register(ResourceKey.create(Registries.TEMPLATE_ARGUMENT_FACTORY.location(), key), factory);
}
private TemplateArguments() {}
static {
register(PLAIN, PlainStringTemplateArgument.FACTORY);
register(SELF_INCREASE_INT, SelfIncreaseIntTemplateArgument.FACTORY);
register(MAP, MapTemplateArgument.FACTORY);
register(LIST, ListTemplateArgument.FACTORY);
register(NULL, NullTemplateArgument.FACTORY);
register(EXPRESSION, ExpressionTemplateArgument.FACTORY);
register(CONDITION, ConditionTemplateArgument.FACTORY);
register(TO_UPPER_CASE, ToUpperCaseTemplateArgument.FACTORY);
register(TO_LOWER_CASE, ToLowerCaseTemplateArgument.FACTORY);
register(WHEN, WhenTemplateArgument.FACTORY);
public static TemplateArgumentType register(Key key, TemplateArgumentFactory factory) {
TemplateArgumentType type = new TemplateArgumentType(key, factory);
((WritableRegistry<TemplateArgumentType>) BuiltInRegistries.TEMPLATE_ARGUMENT_TYPE)
.register(ResourceKey.create(Registries.TEMPLATE_ARGUMENT_TYPE.location(), key), type);
return type;
}
@SuppressWarnings("unchecked")
public static TemplateArgument fromObject(Object object) {
return switch (object) {
case null -> NullTemplateArgument.INSTANCE;
case List<?> list -> new ListTemplateArgument((List<Object>) list);
case List<?> list -> ListTemplateArgument.list((List<Object>) list);
case Map<?, ?> map -> fromMap((Map<String, Object>) map);
default -> new ObjectTemplateArgument(object);
default -> ObjectTemplateArgument.object(object);
};
}
public static TemplateArgument fromMap(Map<String, Object> map) {
Object type = map.get("type");
if (!(type instanceof String type0) || map.containsKey("__skip_template_argument__")) {
return new MapTemplateArgument(map);
return MapTemplateArgument.map(map);
} else {
Key key = Key.withDefaultNamespace(type0, Key.DEFAULT_NAMESPACE);
TemplateArgumentFactory factory = BuiltInRegistries.TEMPLATE_ARGUMENT_FACTORY.getValue(key);
if (factory == null) {
TemplateArgumentType argumentType = BuiltInRegistries.TEMPLATE_ARGUMENT_TYPE.getValue(key);
if (argumentType == null) {
throw new IllegalArgumentException("Unknown argument type: " + type);
}
return factory.create(map);
return argumentType.factory().create(map);
}
}
}

View File

@@ -8,17 +8,21 @@ import net.momirealms.craftengine.core.util.ResourceConfigUtils;
import java.util.Locale;
import java.util.Map;
public class ToLowerCaseTemplateArgument implements TemplateArgument {
public static final Factory FACTORY = new Factory();
public final class ToLowerCaseTemplateArgument implements TemplateArgument {
public static final Key ID = Key.of("craftengine:to_lower_case");
public static final TemplateArgumentFactory FACTORY = new Factory();
private final String result;
private ToLowerCaseTemplateArgument(String result) {
this.result = result;
}
@Override
public Key type() {
return TemplateArguments.TO_LOWER_CASE;
public static ToLowerCaseTemplateArgument toLowerCase(String result) {
return new ToLowerCaseTemplateArgument(result.toLowerCase(Locale.ROOT));
}
public String result() {
return this.result;
}
@Override
@@ -26,7 +30,7 @@ public class ToLowerCaseTemplateArgument implements TemplateArgument {
return this.result;
}
public static class Factory implements TemplateArgumentFactory {
private static class Factory implements TemplateArgumentFactory {
@Override
public TemplateArgument create(Map<String, Object> arguments) {

View File

@@ -8,17 +8,21 @@ import net.momirealms.craftengine.core.util.ResourceConfigUtils;
import java.util.Locale;
import java.util.Map;
public class ToUpperCaseTemplateArgument implements TemplateArgument {
public static final Factory FACTORY = new Factory();
public final class ToUpperCaseTemplateArgument implements TemplateArgument {
public static final Key ID = Key.of("craftengine:to_upper_case");
public static final TemplateArgumentFactory FACTORY = new Factory();
private final String result;
private ToUpperCaseTemplateArgument(String result) {
this.result = result;
}
@Override
public Key type() {
return TemplateArguments.TO_UPPER_CASE;
public static ToUpperCaseTemplateArgument toUpperCase(String result) {
return new ToUpperCaseTemplateArgument(result.toUpperCase(Locale.ROOT));
}
public String result() {
return this.result;
}
@Override
@@ -26,7 +30,7 @@ public class ToUpperCaseTemplateArgument implements TemplateArgument {
return this.result;
}
public static class Factory implements TemplateArgumentFactory {
private static class Factory implements TemplateArgumentFactory {
@Override
public TemplateArgument create(Map<String, Object> arguments) {

View File

@@ -5,17 +5,21 @@ import net.momirealms.craftengine.core.util.ResourceConfigUtils;
import java.util.Map;
public class WhenTemplateArgument implements TemplateArgument {
public static final Factory FACTORY = new Factory();
public final class WhenTemplateArgument implements TemplateArgument {
public static final Key ID = Key.of("craftengine:when");
public static final TemplateArgumentFactory FACTORY = new Factory();
private final TemplateArgument result;
private WhenTemplateArgument(TemplateArgument result) {
this.result = result;
}
@Override
public Key type() {
return TemplateArguments.WHEN;
public static WhenTemplateArgument when(TemplateArgument result) {
return new WhenTemplateArgument(result);
}
public TemplateArgument result() {
return this.result;
}
@Override
@@ -23,7 +27,7 @@ public class WhenTemplateArgument implements TemplateArgument {
return this.result.get(arguments);
}
public static class Factory implements TemplateArgumentFactory {
private static class Factory implements TemplateArgumentFactory {
@Override
public TemplateArgument create(Map<String, Object> arguments) {

View File

@@ -32,11 +32,10 @@ import net.momirealms.craftengine.core.pack.model.definition.rangedisptach.Range
import net.momirealms.craftengine.core.pack.model.definition.select.SelectPropertyType;
import net.momirealms.craftengine.core.pack.model.definition.special.SpecialModelType;
import net.momirealms.craftengine.core.pack.model.definition.tint.TintType;
import net.momirealms.craftengine.core.plugin.config.template.argument.TemplateArgumentFactory;
import net.momirealms.craftengine.core.plugin.config.template.argument.TemplateArgumentType;
import net.momirealms.craftengine.core.plugin.context.Context;
import net.momirealms.craftengine.core.plugin.context.condition.ConditionFactory;
import net.momirealms.craftengine.core.plugin.context.function.FunctionFactory;
import net.momirealms.craftengine.core.plugin.context.number.NumberProviderFactory;
import net.momirealms.craftengine.core.plugin.context.number.NumberProviderType;
import net.momirealms.craftengine.core.plugin.context.selector.PlayerSelectorFactory;
import net.momirealms.craftengine.core.plugin.network.ModPacket;
@@ -53,7 +52,7 @@ public final class BuiltInRegistries {
public static final Registry<LootFunctionType<?>> LOOT_FUNCTION_TYPE = createConstantBoundRegistry(Registries.LOOT_FUNCTION_TYPE, 32);
public static final Registry<LootEntryContainerType<?>> LOOT_ENTRY_CONTAINER_TYPE = createConstantBoundRegistry(Registries.LOOT_ENTRY_CONTAINER_TYPE, 16);
public static final Registry<NumberProviderType> NUMBER_PROVIDER_TYPE = createConstantBoundRegistry(Registries.NUMBER_PROVIDER_TYPE, 16);
public static final Registry<TemplateArgumentFactory> TEMPLATE_ARGUMENT_FACTORY = createConstantBoundRegistry(Registries.TEMPLATE_ARGUMENT_FACTORY, 16);
public static final Registry<TemplateArgumentType> TEMPLATE_ARGUMENT_TYPE = createConstantBoundRegistry(Registries.TEMPLATE_ARGUMENT_TYPE, 16);
public static final Registry<ItemModelType> ITEM_MODEL_TYPE = createConstantBoundRegistry(Registries.ITEM_MODEL_TYPE, 16);
public static final Registry<TintType> TINT_TYPE = createConstantBoundRegistry(Registries.TINT_TYPE, 16);
public static final Registry<SpecialModelType> SPECIAL_MODEL_TYPE = createConstantBoundRegistry(Registries.SPECIAL_MODEL_TYPE, 16);

View File

@@ -32,11 +32,10 @@ import net.momirealms.craftengine.core.pack.model.definition.rangedisptach.Range
import net.momirealms.craftengine.core.pack.model.definition.select.SelectPropertyType;
import net.momirealms.craftengine.core.pack.model.definition.special.SpecialModelType;
import net.momirealms.craftengine.core.pack.model.definition.tint.TintType;
import net.momirealms.craftengine.core.plugin.config.template.argument.TemplateArgumentFactory;
import net.momirealms.craftengine.core.plugin.config.template.argument.TemplateArgumentType;
import net.momirealms.craftengine.core.plugin.context.Context;
import net.momirealms.craftengine.core.plugin.context.condition.ConditionFactory;
import net.momirealms.craftengine.core.plugin.context.function.FunctionFactory;
import net.momirealms.craftengine.core.plugin.context.number.NumberProviderFactory;
import net.momirealms.craftengine.core.plugin.context.number.NumberProviderType;
import net.momirealms.craftengine.core.plugin.context.selector.PlayerSelectorFactory;
import net.momirealms.craftengine.core.plugin.network.ModPacket;
@@ -57,7 +56,7 @@ public final class Registries {
public static final ResourceKey<Registry<LootFunctionType<?>>> LOOT_FUNCTION_TYPE = ResourceKey.create(ROOT_REGISTRY, Key.withDefaultNamespace("loot_function_type"));
public static final ResourceKey<Registry<LootEntryContainerType<?>>> LOOT_ENTRY_CONTAINER_TYPE = ResourceKey.create(ROOT_REGISTRY, Key.withDefaultNamespace("loot_entry_container_type"));
public static final ResourceKey<Registry<NumberProviderType>> NUMBER_PROVIDER_TYPE = ResourceKey.create(ROOT_REGISTRY, Key.withDefaultNamespace("number_provider_type"));
public static final ResourceKey<Registry<TemplateArgumentFactory>> TEMPLATE_ARGUMENT_FACTORY = ResourceKey.create(ROOT_REGISTRY, Key.withDefaultNamespace("template_argument_factory"));
public static final ResourceKey<Registry<TemplateArgumentType>> TEMPLATE_ARGUMENT_TYPE = ResourceKey.create(ROOT_REGISTRY, Key.withDefaultNamespace("template_argument_type"));
public static final ResourceKey<Registry<ItemModelType>> ITEM_MODEL_TYPE = ResourceKey.create(ROOT_REGISTRY, Key.withDefaultNamespace("item_model_type"));
public static final ResourceKey<Registry<TintType>> TINT_TYPE = ResourceKey.create(ROOT_REGISTRY, Key.withDefaultNamespace("tint_type"));
public static final ResourceKey<Registry<SpecialModelType>> SPECIAL_MODEL_TYPE = ResourceKey.create(ROOT_REGISTRY, Key.withDefaultNamespace("special_model_type"));