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 21:08:16 +08:00
parent ece2afed60
commit 95c35067ad
10 changed files with 68 additions and 150 deletions

View File

@@ -8,6 +8,7 @@ import net.momirealms.craftengine.core.util.ResourceConfigUtils;
import java.util.Map;
public record BinomialNumberProvider(NumberProvider trials, NumberProvider successProbability) implements NumberProvider {
public static final Key ID = Key.of("craftengine:binomial");
public static final NumberProviderFactory FACTORY = new Factory();
@Override
@@ -34,11 +35,6 @@ public record BinomialNumberProvider(NumberProvider trials, NumberProvider succe
return successCount;
}
@Override
public Key type() {
return NumberProviders.BINOMIAL;
}
private static class Factory implements NumberProviderFactory {
@Override

View File

@@ -11,47 +11,34 @@ import net.momirealms.craftengine.core.util.ResourceConfigUtils;
import java.util.Map;
public class ExpressionNumberProvider implements NumberProvider {
public record ExpressionNumberProvider(String expression) implements NumberProvider {
public static final Key ID = Key.of("craftengine:expression");
public static final NumberProviderFactory FACTORY = new Factory();
private final String expr;
public ExpressionNumberProvider(String expr) {
this.expr = expr;
}
@Override
public float getFloat(Context context) {
Component resultComponent = AdventureHelper.customMiniMessage().deserialize(this.expr, context.tagResolvers());
Component resultComponent = AdventureHelper.customMiniMessage().deserialize(this.expression, context.tagResolvers());
String resultString = AdventureHelper.plainTextContent(resultComponent);
Expression expression = new Expression(resultString);
try {
return expression.evaluate().getNumberValue().floatValue();
} catch (EvaluationException | ParseException e) {
throw new RuntimeException("Invalid expression: " + this.expr + " -> " + resultString + " -> Cannot parse", e);
throw new RuntimeException("Invalid expression: " + this.expression + " -> " + resultString + " -> Cannot parse", e);
}
}
@Override
public double getDouble(Context context) {
Component resultComponent = AdventureHelper.customMiniMessage().deserialize(this.expr, context.tagResolvers());
Component resultComponent = AdventureHelper.customMiniMessage().deserialize(this.expression, context.tagResolvers());
String resultString = AdventureHelper.plainTextContent(resultComponent);
Expression expression = new Expression(resultString);
try {
return expression.evaluate().getNumberValue().doubleValue();
} catch (EvaluationException | ParseException e) {
throw new RuntimeException("Invalid expression: " + this.expr + " -> " + resultString + " -> Cannot parse", e);
throw new RuntimeException("Invalid expression: " + this.expression + " -> " + resultString + " -> Cannot parse", e);
}
}
@Override
public Key type() {
return NumberProviders.EXPRESSION;
}
public String expression() {
return this.expr;
}
private static class Factory implements NumberProviderFactory {
@Override

View File

@@ -8,13 +8,9 @@ import net.momirealms.craftengine.core.util.ResourceConfigUtils;
import java.util.Map;
public class FixedNumberProvider implements NumberProvider {
public record FixedNumberProvider(double value) implements NumberProvider {
public static final Key ID = Key.of("craftengine:fixed");
public static final NumberProviderFactory FACTORY = new Factory();
private final double value;
public FixedNumberProvider(double value) {
this.value = value;
}
@Override
public float getFloat(Context context) {
@@ -26,11 +22,6 @@ public class FixedNumberProvider implements NumberProvider {
return this.value;
}
@Override
public Key type() {
return NumberProviders.FIXED;
}
public static FixedNumberProvider of(final double value) {
return new FixedNumberProvider(value);
}

View File

@@ -9,13 +9,9 @@ import java.util.Map;
import java.util.Random;
import java.util.concurrent.ThreadLocalRandom;
public class GaussianNumberProvider implements NumberProvider {
public record GaussianNumberProvider(double min, double max, double mean, double stdDev, int maxAttempts) implements NumberProvider {
public static final Key ID = Key.of("craftengine:gaussian");
public static final NumberProviderFactory FACTORY = new Factory();
private final double min;
private final double max;
private final double mean;
private final double stdDev;
private final int maxAttempts;
public GaussianNumberProvider(double min, double max, double mean, double stdDev, int maxAttempts) {
this.min = min;
@@ -57,31 +53,6 @@ public class GaussianNumberProvider implements NumberProvider {
return MiscUtils.clamp(this.mean, this.min, this.max);
}
@Override
public Key type() {
return NumberProviders.GAUSSIAN;
}
public double min() {
return min;
}
public double max() {
return max;
}
public int maxAttempts() {
return maxAttempts;
}
public double mean() {
return mean;
}
public double stdDev() {
return stdDev;
}
private static class Factory implements NumberProviderFactory {
@Override

View File

@@ -1,7 +1,6 @@
package net.momirealms.craftengine.core.plugin.context.number;
import net.momirealms.craftengine.core.plugin.context.Context;
import net.momirealms.craftengine.core.util.Key;
public interface NumberProvider {
@@ -12,6 +11,4 @@ public interface NumberProvider {
default int getInt(Context context) {
return Math.round(this.getFloat(context));
}
Key type();
}

View File

@@ -0,0 +1,6 @@
package net.momirealms.craftengine.core.plugin.context.number;
import net.momirealms.craftengine.core.util.Key;
public record NumberProviderType(Key id, NumberProviderFactory factory) {
}

View File

@@ -8,39 +8,23 @@ import net.momirealms.craftengine.core.util.Key;
import net.momirealms.craftengine.core.util.ResourceConfigUtils;
import net.momirealms.craftengine.core.util.ResourceKey;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
public final class NumberProviders {
public static final Key FIXED = Key.of("craftengine:fixed");
public static final Key CONSTANT = Key.of("craftengine:constant");
public static final Key UNIFORM = Key.of("craftengine:uniform");
public static final Key EXPRESSION = Key.of("craftengine:expression");
public static final Key GAUSSIAN = Key.of("craftengine:gaussian");
public static final Key BINOMIAL = Key.of("craftengine:binomial");
public static final NumberProviderType FIXED = register(FixedNumberProvider.ID, FixedNumberProvider.FACTORY);
public static final NumberProviderType CONSTANT = register(Key.of("craftengine:constant"), FixedNumberProvider.FACTORY);
public static final NumberProviderType UNIFORM = register(UniformNumberProvider.ID, UniformNumberProvider.FACTORY);
public static final NumberProviderType EXPRESSION = register(ExpressionNumberProvider.ID, ExpressionNumberProvider.FACTORY);
public static final NumberProviderType GAUSSIAN = register(GaussianNumberProvider.ID, GaussianNumberProvider.FACTORY);
public static final NumberProviderType BINOMIAL = register(BinomialNumberProvider.ID, BinomialNumberProvider.FACTORY);
static {
register(FIXED, FixedNumberProvider.FACTORY);
register(CONSTANT, FixedNumberProvider.FACTORY);
register(UNIFORM, UniformNumberProvider.FACTORY);
register(GAUSSIAN, GaussianNumberProvider.FACTORY);
register(EXPRESSION, ExpressionNumberProvider.FACTORY);
register(BINOMIAL, BinomialNumberProvider.FACTORY);
}
private NumberProviders() {}
public static void register(Key key, NumberProviderFactory factory) {
((WritableRegistry<NumberProviderFactory>) BuiltInRegistries.NUMBER_PROVIDER_FACTORY)
.register(ResourceKey.create(Registries.NUMBER_PROVIDER_FACTORY.location(), key), factory);
}
public static List<NumberProvider> fromMapList(List<Map<String, Object>> mapList) {
if (mapList == null || mapList.isEmpty()) return List.of();
List<NumberProvider> functions = new ArrayList<>();
for (Map<String, Object> map : mapList) {
functions.add(fromMap(map));
}
return functions;
public static NumberProviderType register(Key key, NumberProviderFactory factory) {
NumberProviderType type = new NumberProviderType(key, factory);
((WritableRegistry<NumberProviderType>) BuiltInRegistries.NUMBER_PROVIDER_TYPE)
.register(ResourceKey.create(Registries.NUMBER_PROVIDER_TYPE.location(), key), type);
return type;
}
public static NumberProvider direct(double value) {
@@ -50,43 +34,46 @@ public final class NumberProviders {
public static NumberProvider fromMap(Map<String, Object> map) {
String type = ResourceConfigUtils.requireNonEmptyStringOrThrow(map.get("type"), "warning.config.number.missing_type");
Key key = Key.withDefaultNamespace(type, Key.DEFAULT_NAMESPACE);
NumberProviderFactory factory = BuiltInRegistries.NUMBER_PROVIDER_FACTORY.getValue(key);
if (factory == null) {
NumberProviderType providerType = BuiltInRegistries.NUMBER_PROVIDER_TYPE.getValue(key);
if (providerType == null) {
throw new LocalizedResourceConfigException("warning.config.number.invalid_type", type);
}
return factory.create(map);
return providerType.factory().create(map);
}
@SuppressWarnings("unchecked")
public static NumberProvider fromObject(Object object) {
if (object == null) {
throw new LocalizedResourceConfigException("warning.config.number.missing_argument");
}
if (object instanceof Number number) {
return new FixedNumberProvider(number.floatValue());
} else if (object instanceof Boolean bool) {
return new FixedNumberProvider(bool ? 1 : 0);
} else if (object instanceof Map<?,?> map) {
return fromMap((Map<String, Object>) map);
} else {
String string = object.toString();
if (string.contains("~")) {
int first = string.indexOf('~');
int second = string.indexOf('~', first + 1);
if (second == -1) {
NumberProvider min = fromObject(string.substring(0, first));
NumberProvider max = fromObject(string.substring(first + 1));
return new UniformNumberProvider(min, max);
switch (object) {
case null -> throw new LocalizedResourceConfigException("warning.config.number.missing_argument");
case Number number -> {
return new FixedNumberProvider(number.floatValue());
}
case Boolean bool -> {
return new FixedNumberProvider(bool ? 1 : 0);
}
case Map<?, ?> map -> {
return fromMap((Map<String, Object>) map);
}
default -> {
String string = object.toString();
if (string.contains("~")) {
int first = string.indexOf('~');
int second = string.indexOf('~', first + 1);
if (second == -1) {
NumberProvider min = fromObject(string.substring(0, first));
NumberProvider max = fromObject(string.substring(first + 1));
return new UniformNumberProvider(min, max);
} else {
throw new LocalizedResourceConfigException("warning.config.number.invalid_format", string);
}
} else if (string.contains("<") && string.contains(">") && string.contains(":")) {
return new ExpressionNumberProvider(string);
} else {
throw new LocalizedResourceConfigException("warning.config.number.invalid_format", string);
}
} else if (string.contains("<") && string.contains(">") && string.contains(":")) {
return new ExpressionNumberProvider(string);
} else {
try {
return new FixedNumberProvider(Float.parseFloat(string));
} catch (NumberFormatException e) {
throw new LocalizedResourceConfigException("warning.config.number.invalid_format", e, string);
try {
return new FixedNumberProvider(Float.parseFloat(string));
} catch (NumberFormatException e) {
throw new LocalizedResourceConfigException("warning.config.number.invalid_format", e, string);
}
}
}
}

View File

@@ -7,23 +7,9 @@ import net.momirealms.craftengine.core.util.ResourceConfigUtils;
import java.util.Map;
public class UniformNumberProvider implements NumberProvider {
public record UniformNumberProvider(NumberProvider min, NumberProvider max) implements NumberProvider {
public static final Key ID = Key.of("craftengine:uniform");
public static final NumberProviderFactory FACTORY = new Factory();
private final NumberProvider min;
private final NumberProvider max;
public UniformNumberProvider(NumberProvider min, NumberProvider max) {
this.min = min;
this.max = max;
}
public NumberProvider max() {
return max;
}
public NumberProvider min() {
return min;
}
@Override
public int getInt(Context context) {
@@ -40,11 +26,6 @@ public class UniformNumberProvider implements NumberProvider {
return RandomUtils.generateRandomFloat(this.min.getFloat(context), this.max.getFloat(context));
}
@Override
public Key type() {
return NumberProviders.UNIFORM;
}
private static class Factory implements NumberProviderFactory {
@Override

View File

@@ -37,6 +37,7 @@ 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;
import net.momirealms.craftengine.core.plugin.network.codec.NetworkCodec;
@@ -51,7 +52,7 @@ public final class BuiltInRegistries {
public static final Registry<PropertyType<?>> PROPERTY_TYPE = createConstantBoundRegistry(Registries.PROPERTY_TYPE, 16);
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<NumberProviderFactory> NUMBER_PROVIDER_FACTORY = createConstantBoundRegistry(Registries.NUMBER_PROVIDER_FACTORY, 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<ItemModelType> ITEM_MODEL_TYPE = createConstantBoundRegistry(Registries.ITEM_MODEL_TYPE, 16);
public static final Registry<TintType> TINT_TYPE = createConstantBoundRegistry(Registries.TINT_TYPE, 16);

View File

@@ -37,6 +37,7 @@ 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;
import net.momirealms.craftengine.core.plugin.network.codec.NetworkCodec;
@@ -55,7 +56,7 @@ public final class Registries {
public static final ResourceKey<Registry<ItemBehaviorType>> ITEM_BEHAVIOR_TYPE = ResourceKey.create(ROOT_REGISTRY, Key.withDefaultNamespace("item_behavior_type"));
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<NumberProviderFactory>> NUMBER_PROVIDER_FACTORY = ResourceKey.create(ROOT_REGISTRY, Key.withDefaultNamespace("number_provider_factory"));
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<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"));