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