mirror of
https://github.com/Flowsqy/ShopChest.git
synced 2025-02-03 11:41:20 +01:00
Add calculation detection
This commit is contained in:
parent
1eaab510eb
commit
eba62d5960
@ -6,9 +6,10 @@ import java.util.function.Function;
|
||||
/**
|
||||
* Represents a hologram calculation
|
||||
*/
|
||||
public interface Calculation<P> {
|
||||
@FunctionalInterface
|
||||
public interface Calculation<P> extends Function<P, Double> {
|
||||
|
||||
double calculate(P provider);
|
||||
Double apply(P provider);
|
||||
|
||||
abstract class AbstractCalculation<P> implements Calculation<P> {
|
||||
|
||||
@ -48,7 +49,7 @@ public interface Calculation<P> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public double calculate(P values) {
|
||||
public Double apply(P values) {
|
||||
return this.firstArgProvider.apply(values) + secondArgProvider.apply(values);
|
||||
}
|
||||
|
||||
@ -68,7 +69,7 @@ public interface Calculation<P> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public double calculate(P values) {
|
||||
public Double apply(P values) {
|
||||
return this.firstArgProvider.apply(values) - secondArgProvider.apply(values);
|
||||
}
|
||||
|
||||
@ -88,7 +89,7 @@ public interface Calculation<P> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public double calculate(P values) {
|
||||
public Double apply(P values) {
|
||||
return this.firstArgProvider.apply(values) * secondArgProvider.apply(values);
|
||||
}
|
||||
|
||||
@ -108,7 +109,7 @@ public interface Calculation<P> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public double calculate(P values) {
|
||||
public Double apply(P values) {
|
||||
return this.firstArgProvider.apply(values) / secondArgProvider.apply(values);
|
||||
}
|
||||
|
||||
@ -128,7 +129,7 @@ public interface Calculation<P> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public double calculate(P values) {
|
||||
public Double apply(P values) {
|
||||
return this.firstArgProvider.apply(values) % secondArgProvider.apply(values);
|
||||
}
|
||||
|
||||
|
@ -5,6 +5,7 @@ import java.util.function.Predicate;
|
||||
/**
|
||||
* Represents a hologram requirement condition
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface Condition<P> extends Predicate<P> {
|
||||
|
||||
}
|
||||
|
@ -1,8 +1,10 @@
|
||||
package de.epiceric.shopchest.config.hologram.parser;
|
||||
|
||||
import de.epiceric.shopchest.config.hologram.calculation.Calculation;
|
||||
import de.epiceric.shopchest.config.hologram.condition.Condition;
|
||||
import de.epiceric.shopchest.config.hologram.condition.ProviderCondition;
|
||||
import de.epiceric.shopchest.config.hologram.condition.ReverseCondition;
|
||||
import de.epiceric.shopchest.config.hologram.provider.ConstantProvider;
|
||||
import de.epiceric.shopchest.config.hologram.provider.MapProvider;
|
||||
|
||||
import java.util.*;
|
||||
@ -193,9 +195,13 @@ public class FormatParser {
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private <T> T cast(Object o) {
|
||||
return (T) o;
|
||||
}
|
||||
|
||||
private Token<List<Token<?>>> getTypedNoteToken(Token<?> token) {
|
||||
if (token.getType() == Token.NODE) {
|
||||
return (Token<List<Token<?>>>) token;
|
||||
return cast(token);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@ -271,7 +277,93 @@ public class FormatParser {
|
||||
reverseChain = reverseChain.getAfter();
|
||||
}
|
||||
|
||||
// Calculation
|
||||
Chain<Token<?>> calculationChain = tokensChain;
|
||||
while (calculationChain != null) {
|
||||
final Token<?> token = calculationChain.getValue();
|
||||
// Operator check
|
||||
if (token.getType() == Token.CALCULATION_OPERATOR) {
|
||||
final Chain<Token<?>> previousChain = calculationChain.getBefore();
|
||||
final Chain<Token<?>> nextChain = calculationChain.getAfter();
|
||||
// First member does not exist
|
||||
if (previousChain == null) {
|
||||
throw new RuntimeException("Try to apply a calculation operator without first member");
|
||||
}
|
||||
// Second member does not exist
|
||||
if (nextChain == null) {
|
||||
throw new RuntimeException("Try to apply a calculation operator without second member");
|
||||
}
|
||||
final Function<P, Double> previousProvider = checkNumeric(previousChain, providerFunction, providerTypes);
|
||||
final Function<P, Double> nextProvider = checkNumeric(nextChain, providerFunction, providerTypes);
|
||||
|
||||
// Create the calculation
|
||||
final Calculation<P> calculation;
|
||||
final Token.CalculationOperator operator = (Token.CalculationOperator) token.getValue();
|
||||
switch (operator) {
|
||||
case ADDITION:
|
||||
calculation = new Calculation.Addition<>(previousProvider, nextProvider);
|
||||
break;
|
||||
case SUBTRACTION:
|
||||
calculation = new Calculation.Subtraction<>(previousProvider, nextProvider);
|
||||
break;
|
||||
case MULTIPLICATION:
|
||||
calculation = new Calculation.Multiplication<>(previousProvider, nextProvider);
|
||||
break;
|
||||
case DIVISION:
|
||||
calculation = new Calculation.Division<>(previousProvider, nextProvider);
|
||||
break;
|
||||
case MODULO:
|
||||
calculation = new Calculation.Modulo<>(previousProvider, nextProvider);
|
||||
break;
|
||||
default:
|
||||
throw new RuntimeException("Can not figure out what is the calculation operator");
|
||||
}
|
||||
|
||||
// Set the chain
|
||||
final Chain<Token<?>> afterCalculationChain = nextChain.getAfter();
|
||||
previousChain.setValue(new Token<>(Token.CALCULATION, calculation));
|
||||
if (afterCalculationChain != null) {
|
||||
afterCalculationChain.setBefore(previousChain);
|
||||
previousChain.setAfter(afterCalculationChain);
|
||||
} else {
|
||||
previousChain.setAfter(null);
|
||||
}
|
||||
}
|
||||
calculationChain = calculationChain.getAfter();
|
||||
}
|
||||
|
||||
return tokensChain == null ? null : tokensChain.getValue();
|
||||
}
|
||||
|
||||
private <P> Function<P, Double> checkNumeric(
|
||||
Chain<Token<?>> chain,
|
||||
Function<String, P> providerFunction,
|
||||
Map<P, Class<?>> providerTypes
|
||||
) {
|
||||
final Token<?> token = chain.getValue();
|
||||
if (token.getType() == Token.VALUE) {
|
||||
final String value = (String) token.getValue();
|
||||
final P provided = providerFunction.apply(value);
|
||||
// It uses a valid provided value
|
||||
if (provided != null) {
|
||||
final Class<?> providedClass = providerTypes.get(provided);
|
||||
// The provided value is a number
|
||||
if (providedClass == Double.class) {
|
||||
// Return the provided key
|
||||
return cast(new MapProvider.DoubleMapProvider<>(provided));
|
||||
} else {
|
||||
throw new RuntimeException("'" + value + "' can not be used as a number");
|
||||
}
|
||||
} else {
|
||||
throw new RuntimeException("'" + value + "' does not exist");
|
||||
}
|
||||
} else if (token.getType() == Token.CALCULATION) {
|
||||
return cast(token.getValue());
|
||||
} else if (token.getType() == Token.DOUBLE) {
|
||||
return new ConstantProvider<>((Double) token.getValue());
|
||||
}
|
||||
|
||||
throw new RuntimeException("Try to apply calculation operator on something that does not represent a number");
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user