新实训数据结构修改中

This commit is contained in:
joylink_zhangsai 2022-08-12 16:45:02 +08:00
parent e3fc0efeaf
commit d600df6381
14 changed files with 352 additions and 333 deletions

View File

@ -1,9 +1,13 @@
package club.joylink.rtss.entity.training2; package club.joylink.rtss.entity.training2;
import club.joylink.rtss.simulation.cbtc.training2.Expression; import club.joylink.rtss.simulation.cbtc.training2.Expression;
import lombok.Getter;
import lombok.Setter;
import java.time.LocalDateTime; import java.time.LocalDateTime;
@Getter
@Setter
public class DraftTraining2 { public class DraftTraining2 {
private Long id; private Long id;
@ -22,7 +26,7 @@ public class DraftTraining2 {
/** /**
* 实训类型单操场景 * 实训类型单操场景
*/ */
private String type; private Integer type;
/** /**
* 标签用于检索 * 标签用于检索
@ -44,10 +48,10 @@ public class DraftTraining2 {
*/ */
private Long runPlanId; private Long runPlanId;
/** // /**
* List<OperaVO>的json // * List<OperaVO>的json
*/ // */
private String operasJson; // private String operasJson;
/** /**
* List<Step2VO>的json * List<Step2VO>的json

View File

@ -0,0 +1,36 @@
package club.joylink.rtss.services.training2;
import club.joylink.rtss.entity.training2.DraftTraining2;
import club.joylink.rtss.simulation.cbtc.Simulation;
import club.joylink.rtss.simulation.cbtc.training2.Step2;
import club.joylink.rtss.simulation.cbtc.training2.Training2;
public class Training2Service {
public static final String JOB_NAME = "Training2";
public static final int RATE = 1000;
public void run(Simulation simulation) {
Training2 training2 = new Training2(null, null); //从仿真里拿到Training2
for (Step2 step : training2.getStepList()) {
if (!step.isCompletion()) {
if (!step.isTrigger()) {
if (Boolean.TRUE.equals(step.getTriggerCondition().getBoolean())) {
step.setTrigger(true);
//前端提示
}
}
if (Boolean.TRUE.equals(step.getCompletionCondition().getBoolean())) {
step.setCompletion(true);
} else {
break;
}
}
}
}
public void loadTraining(long id, Simulation simulation) {
DraftTraining2 draftTraining2 = new DraftTraining2();
Training2 training2 = new Training2(draftTraining2, simulation);
simulation.addJobIfAbsent(JOB_NAME, () -> this.run(simulation), RATE);
}
}

View File

@ -2,53 +2,73 @@ package club.joylink.rtss.simulation.cbtc.training2;
import club.joylink.rtss.exception.BusinessExceptionAssertEnum; import club.joylink.rtss.exception.BusinessExceptionAssertEnum;
import lombok.Getter; import lombok.Getter;
import lombok.NoArgsConstructor; import lombok.NonNull;
import lombok.Setter; import lombok.Setter;
import java.util.Arrays;
import java.util.Objects; import java.util.Objects;
import java.util.Optional;
/** /**
* 表达式 * 表达式
*/ */
@Getter @Getter
@Setter @Setter
@NoArgsConstructor public class Expression implements Valuable {
public class Expression<T> implements Valuable<Boolean> { Valuable v1;
Valuable<T> v1;
Operator operator; Operator operator;
Valuable<T> v2; Valuable v2;
public static void main(String[] args) {
}
public Expression(@NonNull Valuable v1, int operator, Valuable v2) {
this.v1 = v1;
this.operator = Operator.getByCode(operator);
this.v2 = v2;
}
@Override @Override
public Boolean getValue() throws IllegalAccessException { public Boolean getBoolean() {
BusinessExceptionAssertEnum.DATA_ERROR.assertNotNull(operator);
switch (operator) { switch (operator) {
//逻辑运算符 //逻辑运算符
case AND: case AND:
return (Boolean) v1.getValue() && (Boolean) v2.getValue(); return v1.getBoolean() && v2.getBoolean();
case OR: case OR:
return (Boolean) v1.getValue() || (Boolean) v2.getValue(); return v1.getBoolean() || v2.getBoolean();
case NOT: //还是觉得不要这个好 case NOT:
return !(Boolean) v1.getValue(); return !v1.getBoolean();
//关系运算符 //关系运算符
case EQUALS: case EQUALS:
return Objects.equals(v1.getValue(), v2.getValue()); return Objects.equals(v1.getObject(), v2.getObject());
case NOT_EQUALS: case NOT_EQUALS:
return !Objects.equals(v1.getValue(), v2.getValue()); return !Objects.equals(v1.getObject(), v2.getObject());
case GREATER_THAN: case GREATER_THAN:
return ((Comparable)v1.getValue()).compareTo(v2.getValue()) > 0; return v1.getComparable().compareTo(v2.getComparable()) > 0;
case GREATER_THAN_OR_EQUALS: case GREATER_THAN_OR_EQUALS:
return ((Comparable)v1.getValue()).compareTo(v2.getValue()) >= 0; return v1.getComparable().compareTo(v2.getComparable()) >= 0;
case LESS_THAN: case LESS_THAN:
return ((Comparable)v1.getValue()).compareTo(v2.getValue()) < 0; return v1.getComparable().compareTo(v2.getComparable()) < 0;
case LESS_THAN_OR_EQUALS: case LESS_THAN_OR_EQUALS:
return ((Comparable)v1.getValue()).compareTo(v2.getValue()) <= 0; return v1.getComparable().compareTo(v2.getComparable()) <= 0;
default: default:
throw new IllegalStateException("Unexpected value: " + operator); throw new IllegalStateException("Unexpected value: " + operator);
} }
} }
@Override
public Object getObject() {
return getBoolean();
}
@Override
public Comparable getComparable() {
return getBoolean();
}
public enum Operator { public enum Operator {
AND(1), AND(1),
OR(2), OR(2),
@ -65,68 +85,11 @@ public class Expression<T> implements Valuable<Boolean> {
Operator(int code) { Operator(int code) {
this.code = code; this.code = code;
} }
}
/** public static Operator getByCode(int code) {
* 逻辑表达式 Optional<Operator> any = Arrays.stream(values()).filter(e -> e.code == code).findAny();
*/ BusinessExceptionAssertEnum.ARGUMENT_ILLEGAL.assertTrue(any.isPresent(), String.format("没有code[%s]的操作符", code));
public static class Expression1 extends Expression<Boolean> { return any.get();
@Override
public Boolean getValue() throws IllegalAccessException {
BusinessExceptionAssertEnum.DATA_ERROR.assertNotNull(operator);
switch (operator) {
//逻辑运算符
case AND:
return v1.getValue() && v2.getValue();
case OR:
return v1.getValue() || v2.getValue();
case NOT: //还是觉得不要这个好
return !v1.getValue();
default:
throw new IllegalStateException("Unexpected value: " + operator);
}
}
}
/**
* 关系表达式1
*/
public static class Expression2 extends Expression<Object> {
@Override
public Boolean getValue() throws IllegalAccessException {
BusinessExceptionAssertEnum.DATA_ERROR.assertNotNull(operator);
switch (operator) {
//关系运算符
case EQUALS:
return Objects.equals(v1.getValue(), v2.getValue());
case NOT_EQUALS:
return !Objects.equals(v1.getValue(), v2.getValue());
default:
throw new IllegalStateException("Unexpected value: " + operator);
}
}
}
/**
* 关系表达式1
*/
public static class Expression3<T extends Comparable<T>> extends Expression<T> {
@Override
public Boolean getValue() throws IllegalAccessException {
BusinessExceptionAssertEnum.DATA_ERROR.assertNotNull(operator);
switch (operator) {
//关系运算符
case GREATER_THAN:
return v1.getValue().compareTo(v2.getValue()) > 0;
case GREATER_THAN_OR_EQUALS:
return v1.getValue().compareTo(v2.getValue()) >= 0;
case LESS_THAN:
return v1.getValue().compareTo(v2.getValue()) < 0;
case LESS_THAN_OR_EQUALS:
return v1.getValue().compareTo(v2.getValue()) <= 0;
default:
throw new IllegalStateException("Unexpected value: " + operator);
}
} }
} }
} }

View File

@ -1,18 +1,18 @@
package club.joylink.rtss.simulation.cbtc.training2; package club.joylink.rtss.simulation.cbtc.training2;
import club.joylink.rtss.exception.BusinessExceptionAssertEnum;
import club.joylink.rtss.simulation.cbtc.data.map.MapElement; import club.joylink.rtss.simulation.cbtc.data.map.MapElement;
import java.lang.reflect.Field; import java.lang.reflect.Field;
public class StatusValue<T> implements Valuable<T>{ public class StatusValue implements Valuable{
private MapElement element; private MapElement element;
private String fieldName; private String fieldName;
private Field field; private Field field;
public StatusValue(MapElement element, String fieldName) throws NoSuchFieldException { public StatusValue(MapElement element, String fieldName) {
this.element = element; this.element = element;
this.fieldName = fieldName; this.fieldName = fieldName;
Class<?> aClass = element.getClass(); Class<?> aClass = element.getClass();
@ -25,15 +25,45 @@ public class StatusValue<T> implements Valuable<T>{
if (field != null) if (field != null)
break; break;
aClass = aClass.getSuperclass(); aClass = aClass.getSuperclass();
if (aClass == null) { BusinessExceptionAssertEnum.SYSTEM_EXCEPTION.assertNotNull(aClass);
throw new NoSuchFieldException();
}
} }
field.setAccessible(true); field.setAccessible(true);
} }
@Override @Override
public T getValue() throws IllegalAccessException { public Boolean getBoolean() {
return (T) field.get(element); try {
Object o = field.get(element);
if (o instanceof Boolean) {
return (Boolean) o;
} else {
throw BusinessExceptionAssertEnum.SYSTEM_EXCEPTION.exception();
}
} catch (IllegalAccessException e) {
throw BusinessExceptionAssertEnum.SYSTEM_EXCEPTION.exception();
}
}
@Override
public Object getObject() {
try {
return field.get(element);
} catch (IllegalAccessException e) {
throw BusinessExceptionAssertEnum.SYSTEM_EXCEPTION.exception();
}
}
@Override
public Comparable getComparable() {
try {
Object o = field.get(element);
if (o instanceof Comparable) {
return (Comparable) o;
} else {
throw BusinessExceptionAssertEnum.SYSTEM_EXCEPTION.exception();
}
} catch (IllegalAccessException e) {
throw BusinessExceptionAssertEnum.SYSTEM_EXCEPTION.exception();
}
} }
} }

View File

@ -0,0 +1,26 @@
package club.joylink.rtss.simulation.cbtc.training2;
import club.joylink.rtss.vo.client.training2.Step2VO;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
public class Step2 {
private Integer id;
private String description;
private Valuable triggerCondition;
private Valuable completionCondition;
private boolean trigger;
private boolean completion;
public Step2(Step2VO vo) {
this.id = vo.getId();
this.description = vo.getDescription();
}
}

View File

@ -0,0 +1,75 @@
package club.joylink.rtss.simulation.cbtc.training2;
import club.joylink.rtss.entity.training2.DraftTraining2;
import club.joylink.rtss.simulation.cbtc.Simulation;
import club.joylink.rtss.util.JsonUtils;
import club.joylink.rtss.vo.client.training2.ScoringRuleVO;
import club.joylink.rtss.vo.client.training2.Step2VO;
import lombok.Getter;
import lombok.Setter;
import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;
@Getter
@Setter
public class Training2 {
private Long id;
private Long mapId;
private String name;
private String description;
private Type type;
private List<String> labels;
private String mapLocationJson;
private String bgSceneJson;
private Long runPlanId;
private List<Step2> stepList;
private List<ScoringRuleVO> scoringRules;
private String membersJson;
private String playersJson;
private Valuable failureCondition;
private Long creatorId;
private LocalDateTime createTime;
private LocalDateTime updateTime;
public Training2(DraftTraining2 draftTraining2, Simulation simulation) {
labels = JsonUtils.readCollection(draftTraining2.getLabelJson(), List.class, String.class);
List<Step2VO> step2VOS = JsonUtils.readCollection(draftTraining2.getStepsJson(), List.class, Step2VO.class);
stepList = step2VOS.stream().map(vo -> {
Step2 step2 = new Step2(vo);
Valuable triggerCondition = vo.getTriggerCondition().convert2BO(simulation.getRepository());
Valuable completionCondition = vo.getCompletionCondition().convert2BO(simulation.getRepository());
step2.setTriggerCondition(triggerCondition);
step2.setCompletionCondition(completionCondition);
return step2;
}).collect(Collectors.toList());
}
public enum Type {
SINGLE(1),
SCENE(2),
;
private final int code;
Type(int code) {
this.code = code;
}
}
}

View File

@ -1,8 +1,12 @@
package club.joylink.rtss.simulation.cbtc.training2; package club.joylink.rtss.simulation.cbtc.training2;
/** /**
* 值的 * 可以获取值的
*/ */
public interface Valuable<T> { public interface Valuable {
T getValue() throws IllegalAccessException; Boolean getBoolean();
Object getObject();
Comparable getComparable();
} }

View File

@ -1,200 +0,0 @@
package club.joylink.rtss.vo.client.training2;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
/**
* 表达式
*/
@Getter
@Setter
@NoArgsConstructor
public abstract class Expression {
public static void main(String[] args) {
// LogicalExpression rootExpression = new LogicalExpression();
RelationalExpression rootExpression = new RelationalExpression();
LogicalExpression expression1 = new LogicalExpression();
TrainPosition trainPosition1 = new TrainPosition();
trainPosition1.setHeadSectionCode("Section");
trainPosition1.setSectionCode("Section");
trainPosition1.setRelationalOperator(RelationalOperator.EQUALS.code);
TrainStop trainStop1 = new TrainStop();
trainStop1.setTrainStop(true);
trainStop1.setStop(true);
trainStop1.setRelationalOperator(RelationalOperator.EQUALS.code);
expression1.setExpression(trainPosition1);
expression1.setLogicalOperator(LogicalOperator.OR.code);
expression1.setNextExpression(trainStop1);
LogicalExpression expression2 = new LogicalExpression();
TrainPosition trainPosition2 = new TrainPosition();
trainPosition2.setHeadSectionCode("Section");
trainPosition2.setSectionCode("Section");
trainPosition2.setRelationalOperator(RelationalOperator.EQUALS.code);
TrainStop trainStop2 = new TrainStop();
trainStop2.setTrainStop(true);
trainStop2.setStop(false);
trainStop2.setRelationalOperator(RelationalOperator.EQUALS.code);
expression2.setExpression(trainPosition2);
expression2.setLogicalOperator(LogicalOperator.AND.code);
expression2.setNextExpression(trainStop2);
rootExpression.setExpression(expression1);
rootExpression.setRelationalOperator(RelationalOperator.NOT_EQUALS.code);
rootExpression.setNextExpression(expression2);
System.out.println(rootExpression.getValue());
}
Expression expression;
Expression nextExpression;
int type;
public abstract boolean getValue();
public enum Type {
LOGICAL_EXP(1, LogicalExpression.class),
RELATIONAL_EXP(2, RelationalExpression.class),
;
private final int code;
private final Class<? extends Object> cls;
Type(int code, Class<? extends Object> cls) {
this.code = code;
this.cls = cls;
}
}
/**
* 逻辑运算符
*/
public enum LogicalOperator {
AND(1),
OR(2),
;
private final int code;
LogicalOperator(int code) {
this.code = code;
}
}
public enum RelationalOperator {
EQUALS(1),
NOT_EQUALS(2),
GREATER_THAN(3),
GREATER_THAN_OR_EQUALS(4),
LESS_THAN(5),
LESS_THAN_OR_EQUALS(6),
;
private final int code;
RelationalOperator(int code) {
this.code = code;
}
}
/**
* 逻辑表达式
*/
@Getter
@Setter
@NoArgsConstructor
public static class LogicalExpression extends Expression {
private Integer logicalOperator;
@Override
public boolean getValue() {
if (logicalOperator != null) {
switch (logicalOperator) {
case 1:
return expression.getValue() && nextExpression.getValue();
case 2:
return expression.getValue() || nextExpression.getValue();
default:
throw new IllegalStateException("Unexpected value: " + logicalOperator);
}
} else {
return expression.getValue();
}
}
}
/**
* 关系表达式
*/
@Getter
@Setter
public static class RelationalExpression extends Expression {
Integer relationalOperator;
public RelationalExpression() {
type = Type.RELATIONAL_EXP.code;
}
@Override
public boolean getValue() {
if (relationalOperator != null) {
switch (relationalOperator) {
case 1:
return expression.getValue() == nextExpression.getValue();
case 2:
return expression.getValue() != nextExpression.getValue();
default:
throw new IllegalStateException("Unexpected value: " + relationalOperator);
}
} else {
return expression.getValue();
}
}
}
@Getter
@Setter
@NoArgsConstructor
public static class TrainPosition extends RelationalExpression {
private String groupNumber;
private String headSectionCode;
private String sectionCode;
@Override
public boolean getValue() {
switch (relationalOperator) {
case 1:
return sectionCode.equals(headSectionCode);
case 2:
return !sectionCode.equals(headSectionCode);
default:
throw new IllegalStateException("Unexpected value: " + relationalOperator);
}
}
}
@Getter
@Setter
@NoArgsConstructor
public static class TrainStop extends RelationalExpression {
private boolean trainStop;
private boolean stop;
@Override
public boolean getValue() {
switch (relationalOperator) {
case 1:
return trainStop == stop;
case 2:
return trainStop != stop;
default:
throw new IllegalStateException("Unexpected value: " + relationalOperator);
}
}
}
}

View File

@ -0,0 +1,27 @@
package club.joylink.rtss.vo.client.training2;
import club.joylink.rtss.simulation.cbtc.data.SimulationDataRepository;
import club.joylink.rtss.simulation.cbtc.training2.Expression;
import club.joylink.rtss.simulation.cbtc.training2.Valuable;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
/**
* 表达式
*/
@Getter
@Setter
@NoArgsConstructor
public class ExpressionVO implements ValuableVO{
ValuableVO v1;
private int operator;
ValuableVO v2;
@Override
public Valuable convert2BO(SimulationDataRepository repository) {
return new Expression(v1.convert2BO(repository), operator, v2.convert2BO(repository));
}
}

View File

@ -0,0 +1,22 @@
package club.joylink.rtss.vo.client.training2;
import club.joylink.rtss.simulation.cbtc.data.SimulationDataRepository;
import club.joylink.rtss.simulation.cbtc.training2.StatusValue;
import club.joylink.rtss.simulation.cbtc.training2.Valuable;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
@Getter
@Setter
@NoArgsConstructor
public class StatusValueVO implements ValuableVO{
private String elementCode;
private String filedName;
@Override
public Valuable convert2BO(SimulationDataRepository repository) {
return new StatusValue(repository.getByCode(elementCode), filedName);
}
}

View File

@ -4,15 +4,17 @@ import lombok.Getter;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import lombok.Setter; import lombok.Setter;
import java.util.List;
@Getter @Getter
@Setter @Setter
@NoArgsConstructor @NoArgsConstructor
public class Step2VO { public class Step2VO {
private String id; private Integer id;
private String description; private String description;
private List<String> operaIds; // private List<String> operaIds;
private ValuableVO triggerCondition;
private ValuableVO completionCondition;
} }

View File

@ -0,0 +1,50 @@
package club.joylink.rtss.vo.client.training2;
import club.joylink.rtss.util.JsonUtils;
import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.annotation.JsonTypeName;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
@Getter
@Setter
@NoArgsConstructor
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "type")
@JsonSubTypes({
@JsonSubTypes.Type(value = Test.class),
@JsonSubTypes.Type(value = Test.T1.class),
@JsonSubTypes.Type(value = Test.T2.class),
})
public class Test {
private Test v1;
private Test v2;
public static void main(String[] args) {
Test test = new Test();
test.setV1(new T1());
test.setV2(new T2());
String json = JsonUtils.writeValueAsString(test);
System.out.println(json);
Test read = JsonUtils.read(json, Test.class);
System.out.println();
}
@Getter
@Setter
@NoArgsConstructor
@JsonTypeName("T1")
public static class T1 extends Test{
private String name = "TTT";
}
@Getter
@Setter
@NoArgsConstructor
@JsonTypeName("T2")
public static class T2 extends Test {
private Integer age = 111;
}
}

View File

@ -1,35 +0,0 @@
package club.joylink.rtss.vo.client.training2;
import club.joylink.rtss.vo.map.graph.Point;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import java.util.List;
@Getter
@Setter
@NoArgsConstructor
public class Training2VO {
private Long id;
private Long mapId;
private String name;
private String description;
private Type type;
/**
* 标签列表
*/
private List<String> labels;
private Point mapLocation;
public enum Type {
OPERATION,
SCENE,
}
}

View File

@ -0,0 +1,15 @@
package club.joylink.rtss.vo.client.training2;
import club.joylink.rtss.simulation.cbtc.data.SimulationDataRepository;
import club.joylink.rtss.simulation.cbtc.training2.Valuable;
import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.WRAPPER_ARRAY, property = "t")
@JsonSubTypes({
@JsonSubTypes.Type(value = ExpressionVO.class, name = "E"),
@JsonSubTypes.Type(value = StatusValueVO.class, name = "S"),
})
public interface ValuableVO {
Valuable convert2BO(SimulationDataRepository repository);
}