Procházet zdrojové kódy

修改计算器bug

xiuwei před 3 roky
rodič
revize
45fb640a99
1 změnil soubory, kde provedl 30 přidání a 37 odebrání
  1. 30 37
      src/main/java/PointDataCalculator.java

+ 30 - 37
src/main/java/PointDataCalculator.java

@@ -1,13 +1,14 @@
-import com.alibaba.fastjson.JSON;
 import com.googlecode.aviator.AviatorEvaluator;
 import com.googlecode.aviator.Expression;
 import com.googlecode.aviator.Options;
 import com.googlecode.aviator.exception.ExpressionSyntaxErrorException;
-import lombok.Getter;
+import com.googlecode.aviator.runtime.function.AbstractFunction;
+import com.googlecode.aviator.runtime.type.AviatorLong;
+import com.googlecode.aviator.runtime.type.AviatorObject;
+import com.googlecode.aviator.runtime.type.AviatorRuntimeJavaType;
+import com.googlecode.aviator.runtime.type.AviatorType;
 import lombok.extern.slf4j.Slf4j;
 
-import java.math.BigDecimal;
-import java.util.HashMap;
 import java.util.Map;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
@@ -17,8 +18,6 @@ import java.util.regex.Pattern;
 public class PointDataCalculator extends BasePointData {
 
 
-    private static final Pattern PAR_EXPR = Pattern.compile("P\\(\\d+\\)");
-
     private static final Pattern RANDOM_EXPR = Pattern.compile("R\\((\\d+)?\\)");
 
     private static final Pattern TIME_EXPR = Pattern.compile("T\\(\\)");
@@ -26,6 +25,7 @@ public class PointDataCalculator extends BasePointData {
 
     static {
         AviatorEvaluator.setOption(Options.ALWAYS_PARSE_FLOATING_POINT_NUMBER_INTO_DECIMAL, true);
+        AviatorEvaluator.addFunction(new PFunction());
     }
 
     /**
@@ -33,30 +33,20 @@ public class PointDataCalculator extends BasePointData {
      */
     Expression compiledExp;
 
-    /**
-     * 计算所需参数
-     */
-    private Map<String, Integer> calculatingParameters;
-
     public PointDataCalculator(Integer point, String formula) {
-        super(point,formula);
+        super(point, formula);
         getOrInitCompiledExp();
     }
 
     public Object calculate() {
-        Map<String, Object> values = new HashMap<>();
-        for (Map.Entry<String, Integer> e : getCalculatingParameters().entrySet()) {
-            values.put(e.getKey(), protocolDataContainer.getData(e.getValue()));
-        }
         Object o = null;
         try {
-            o=getOrInitCompiledExp().execute(values);
+            o = getOrInitCompiledExp().execute();
         } catch (ArithmeticException e) {
             log.error("除数为0,计算公式为:{},请检查数据池内是否有该点位是否有数据", getValue());
         } catch (Exception e) {
             log.error("数据计算{}时发生异常", getValue(), e);
-            log.info(JSON.toJSONString(values));
-            throw new RuntimeException("计算器计算数据时发生异常,公式为:" +getValue());
+            throw new RuntimeException("计算器计算数据时发生异常,公式为:" + getValue());
         }
         return o;
     }
@@ -94,27 +84,30 @@ public class PointDataCalculator extends BasePointData {
         return this.compiledExp;
     }
 
-    /**
-     * 对计算所需的参数进行整理
-     *
-     * @return P_(点位)_P  替换成真实的数据   字段--数值
-     */
-    public Map<String, Integer> getCalculatingParameters() {
-        if (this.calculatingParameters == null) {
-            this.calculatingParameters = new HashMap<>();
-            Matcher matcher = PAR_EXPR.matcher(getValue());
-            while (matcher.find()) {
-                String s = matcher.group();
-                s = s.substring(1, s.length() - 1);
-                this.calculatingParameters.put("P_" + s + "_P", Integer.parseInt(s));
-            }
-        }
-        return this.calculatingParameters;
-    }
-
 
     @Override
     public void joinRealTimeData() {
         protocolDataContainer.addCalculator(this);
     }
+
+
+    public static class PFunction extends AbstractFunction {
+
+
+        private static final long serialVersionUID = -7377110880312266008L;
+
+        @Override
+        public String getName() {
+            return "P";
+        }
+
+        public AviatorObject call(Map<String, Object> env, AviatorObject arg) {
+            if (AviatorType.Long == arg.getAviatorType()) {
+                return AviatorRuntimeJavaType.valueOf(ProtocolDataContainer.getInstance().getData(((AviatorLong) arg).toBigInt().intValue()));
+            }
+            return AviatorRuntimeJavaType.valueOf(null);
+
+        }
+
+    }
 }