mirror of
https://github.com/hneemann/Digital.git
synced 2025-09-08 12:25:22 -04:00
better init state handling
This commit is contained in:
parent
37ddaf01f6
commit
b8ab4a526e
@ -26,9 +26,10 @@ public class FSM {
|
||||
|
||||
private ArrayList<State> states;
|
||||
private ArrayList<Transition> transitions;
|
||||
private transient boolean initChecked;
|
||||
private transient boolean modified;
|
||||
private transient ModifiedListener modifiedListener;
|
||||
private transient boolean isInitialChecked;
|
||||
private transient Transition initialTransition;
|
||||
|
||||
/**
|
||||
* Creates a proper configured XStream instance
|
||||
@ -134,6 +135,7 @@ public class FSM {
|
||||
state.setNumber(states.size());
|
||||
state.setFSM(this);
|
||||
states.add(state);
|
||||
resetInitInitialization();
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -146,6 +148,7 @@ public class FSM {
|
||||
public FSM add(Transition transition) {
|
||||
transitions.add(transition);
|
||||
transition.setFSM(this);
|
||||
resetInitInitialization();
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -230,10 +233,6 @@ public class FSM {
|
||||
* @param gr the Graphic instance to draw to
|
||||
*/
|
||||
public void drawTo(Graphic gr) {
|
||||
if (!initChecked) {
|
||||
checkInitState();
|
||||
initChecked = true;
|
||||
}
|
||||
for (State s : states)
|
||||
s.drawTo(gr);
|
||||
for (Transition t : transitions)
|
||||
@ -241,6 +240,9 @@ public class FSM {
|
||||
}
|
||||
|
||||
private void checkInitState() {
|
||||
initialTransition = null;
|
||||
isInitialChecked = true;
|
||||
|
||||
int count = 0;
|
||||
Transition found = null;
|
||||
for (Transition t : transitions) {
|
||||
@ -248,17 +250,33 @@ public class FSM {
|
||||
count++;
|
||||
found = t;
|
||||
}
|
||||
if (t.getTargetState().getNumber() == 0)
|
||||
return;
|
||||
}
|
||||
try {
|
||||
if (count == 1 && !found.hasCondition()) {
|
||||
found.getStartState().setInitial();
|
||||
found.setInitial();
|
||||
}
|
||||
if (count == 1 && !found.hasCondition())
|
||||
initialTransition = found;
|
||||
} catch (FiniteStateMachineException e) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
|
||||
void resetInitInitialization() {
|
||||
isInitialChecked = false;
|
||||
}
|
||||
|
||||
boolean isInitial(State state) {
|
||||
if (!isInitialChecked)
|
||||
checkInitState();
|
||||
return initialTransition != null && state.getNumber() == 0;
|
||||
}
|
||||
|
||||
boolean isInitial(Transition transition) {
|
||||
if (!isInitialChecked)
|
||||
checkInitState();
|
||||
return transition == initialTransition;
|
||||
}
|
||||
|
||||
/**
|
||||
* Moved the elements
|
||||
*
|
||||
@ -286,8 +304,8 @@ public class FSM {
|
||||
double delta = 2 * Math.PI / states.size();
|
||||
double rad = 0;
|
||||
for (State s : states)
|
||||
if (s.getRadius() > rad)
|
||||
rad = s.getRadius();
|
||||
if (s.getVisualRadius() > rad)
|
||||
rad = s.getVisualRadius();
|
||||
|
||||
rad *= 4;
|
||||
double phi = 0;
|
||||
@ -354,6 +372,7 @@ public class FSM {
|
||||
public void remove(Transition transition) {
|
||||
transitions.remove(transition);
|
||||
wasModified();
|
||||
resetInitInitialization();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -365,6 +384,7 @@ public class FSM {
|
||||
states.remove(state);
|
||||
transitions.removeIf(t -> t.getStartState() == state || t.getTargetState() == state);
|
||||
wasModified();
|
||||
resetInitInitialization();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -18,6 +18,7 @@ public class State extends Movable {
|
||||
|
||||
private static final int RAD = 70;
|
||||
private static final float REACH = 2000;
|
||||
private static final int INIT_RADIUS = 20;
|
||||
|
||||
private int number = -1;
|
||||
private String name;
|
||||
@ -25,7 +26,6 @@ public class State extends Movable {
|
||||
private String values = "";
|
||||
|
||||
private transient TreeMap<String, Integer> valueMap;
|
||||
private transient boolean isInitial;
|
||||
|
||||
/**
|
||||
* Creates a new state
|
||||
@ -119,8 +119,8 @@ public class State extends Movable {
|
||||
* @param gr the Graphic instance to draw to
|
||||
*/
|
||||
public void drawTo(Graphic gr) {
|
||||
if (isInitial) {
|
||||
VectorInterface rad = new Vector(radius, radius);
|
||||
if (isInitialState()) {
|
||||
VectorInterface rad = new Vector(INIT_RADIUS, INIT_RADIUS);
|
||||
gr.drawCircle(getPos().sub(rad), getPos().add(rad), Style.FILLED);
|
||||
} else {
|
||||
VectorInterface rad = new Vector(radius, radius);
|
||||
@ -144,6 +144,20 @@ public class State extends Movable {
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isInitialState() {
|
||||
return getFsm() != null && getFsm().isInitial(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the radius of the state
|
||||
*/
|
||||
float getVisualRadius() {
|
||||
if (isInitialState())
|
||||
return INIT_RADIUS;
|
||||
else
|
||||
return radius;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the radius of the state
|
||||
*/
|
||||
@ -161,6 +175,8 @@ public class State extends Movable {
|
||||
if (this.number != number) {
|
||||
this.number = number;
|
||||
wasModified();
|
||||
if (getFsm() != null)
|
||||
getFsm().resetInitInitialization();
|
||||
}
|
||||
return this;
|
||||
}
|
||||
@ -202,11 +218,4 @@ public class State extends Movable {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes this state the initial state
|
||||
*/
|
||||
public void setInitial() {
|
||||
isInitial = true;
|
||||
radius = 20;
|
||||
}
|
||||
}
|
||||
|
@ -27,7 +27,6 @@ public class Transition extends Movable {
|
||||
private String condition = "";
|
||||
private String values = "";
|
||||
private transient Expression conditionExpression;
|
||||
private transient boolean isInitial;
|
||||
private transient TreeMap<String, Integer> valuesMap;
|
||||
|
||||
|
||||
@ -53,9 +52,7 @@ public class Transition extends Movable {
|
||||
* @param transitions the transitions
|
||||
*/
|
||||
public void calcForce(List<State> states, List<Transition> transitions) {
|
||||
float preferredDist = 20;
|
||||
if (!isInitial)
|
||||
preferredDist = Math.max(fromState.getRadius(), toState.getRadius()) * 5;
|
||||
float preferredDist = Math.max(fromState.getVisualRadius(), toState.getVisualRadius()) * 5;
|
||||
calcForce(preferredDist, states, transitions);
|
||||
}
|
||||
|
||||
@ -81,7 +78,7 @@ public class Transition extends Movable {
|
||||
VectorFloat center = fromState.getPos().add(toState.getPos()).mul(0.5f);
|
||||
addAttractiveTo(center, 1);
|
||||
|
||||
if (!isInitial) {
|
||||
if (!isInitialTransition()) {
|
||||
for (State s : states)
|
||||
addRepulsive(s.getPos(), 2000);
|
||||
|
||||
@ -91,6 +88,10 @@ public class Transition extends Movable {
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isInitialTransition() {
|
||||
return getFsm() != null && getFsm().isInitial(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPos(VectorFloat position) {
|
||||
if (fromState != toState) {
|
||||
@ -120,9 +121,9 @@ public class Transition extends Movable {
|
||||
anchorTo = anchorTo.sub(dif);
|
||||
}
|
||||
|
||||
VectorFloat difFrom = anchorFrom.sub(fromState.getPos()).norm().mul(fromState.getRadius() + Style.MAXLINETHICK);
|
||||
VectorFloat difTo = anchorTo.sub(toState.getPos()).norm().mul(toState.getRadius() + Style.MAXLINETHICK + 2);
|
||||
VectorFloat difToTip = anchorTo.sub(toState.getPos()).norm().mul(toState.getRadius() + Style.MAXLINETHICK);
|
||||
VectorFloat difFrom = anchorFrom.sub(fromState.getPos()).norm().mul(fromState.getVisualRadius() + Style.MAXLINETHICK);
|
||||
VectorFloat difTo = anchorTo.sub(toState.getPos()).norm().mul(toState.getVisualRadius() + Style.MAXLINETHICK + 2);
|
||||
VectorFloat difToTip = anchorTo.sub(toState.getPos()).norm().mul(toState.getVisualRadius() + Style.MAXLINETHICK);
|
||||
|
||||
final VectorFloat start = fromState.getPos().add(difFrom);
|
||||
final VectorFloat end = toState.getPos().add(difTo);
|
||||
@ -167,6 +168,8 @@ public class Transition extends Movable {
|
||||
this.condition = condition;
|
||||
wasModified();
|
||||
conditionExpression = null;
|
||||
if (getFsm()!=null)
|
||||
getFsm().resetInitInitialization();
|
||||
}
|
||||
}
|
||||
|
||||
@ -268,10 +271,4 @@ public class Transition extends Movable {
|
||||
return fromState + " --[" + condition + "]-> " + toState;
|
||||
}
|
||||
|
||||
/**
|
||||
* Mark this transition as initial transition
|
||||
*/
|
||||
public void setInitial() {
|
||||
isInitial = true;
|
||||
}
|
||||
}
|
||||
|
@ -263,6 +263,7 @@ public class FSMFrame extends JFrame implements ClosingWindowListener.ConfirmSav
|
||||
moveControl.setSelectedIndex(0);
|
||||
setFSM(FSM.loadFSM(file));
|
||||
setFilename(file);
|
||||
lastModified=fsm.isModified();
|
||||
} catch (IOException e) {
|
||||
new ErrorMessage(Lang.get("msg_fsm_errorLoadingFile")).addCause(e).show(this);
|
||||
}
|
||||
@ -273,6 +274,7 @@ public class FSMFrame extends JFrame implements ClosingWindowListener.ConfirmSav
|
||||
fsm.save(file);
|
||||
setFilename(file);
|
||||
save.setEnabled(false);
|
||||
lastModified=fsm.isModified();
|
||||
} catch (IOException e) {
|
||||
new ErrorMessage(Lang.get("msg_fsm_errorStoringFile")).addCause(e).show(this);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user