public abstract class StateSimple extends java.lang.Object implements InfoAppend
StateComposite
too.
The user should build states in a StateMachine
by writing derived classes of this class or of StateComposite
which contains transitions and may override the #entry(EventMsg2)
and exit()
method: class MyStateMachine extends StateMachine { class StateA extends StateSimple //one state { (add)Override protected int entry(Event,?> ev) { ...code of entry... } (add)Override protected void exit() { ...code of exit... } //Form of a transition as method which is detected by reflection: Trans checkX_DstState(Event,?> ev, Trans trans){ if(trans == null){ return new Trans(DstState.class); //called on startup, programmed the destination state(s) } else if(...condition...) { //Check any condition trans.retTrans = mEventConsumed; //if an event is used as condition trans.doExit(); ...transition action code... trans.doEntry(ev); return trans; } else return null; } //Form of a transition as instance of an derived anonymous class: Trans checkY_StateY = new Trans(StateY.class) { (add)Override protected int check(Event, ?> ev) { //overrides the trans method: if(...condition...) { retTrans = mEventConsumed; doExit(); ...transition action code... doEntry(ev); return retTrans; } else return 0; } } } }For building a
StateComposite
see there.
StateSimple.Trans
as return instance,
Modifier and Type | Class and Description |
---|---|
class |
StateSimple.PlugStateSimpleToGenState
This class is used especially in
org.vishia.stateMGen.StateMGen in the component srcJava_Zbnf
to help generate a state machine for C language. |
class |
StateSimple.Timeout
If a state contains a field of this class, a timeout is given for that state.
|
class |
StateSimple.Trans
An instance of this class represents a transition of the enclosing SimpleState to one or more destination states.
|
class |
StateSimple.TransChoice |
class |
StateSimple.TransJoin |
Modifier and Type | Field and Description |
---|---|
private StateSimple.Trans[] |
aTransitions
This array contains all transitions to handle it commonly.
|
private java.lang.Object |
auxInfo
Any additional information.
|
protected StateComposite |
compositeState
The state which is the composite state for this.
|
int |
ctEntry
Debug helper.
|
long |
dateLastEntry
Debug helper.
|
long |
durationLast
Debug helper.
|
protected StateSimple |
enclState
Reference to the enclosing state.
|
protected StateAction |
entry
Action for entry and exit.
|
(package private) TimeOrder |
evTimeout
The timeout event for this state stored also in the top state or a
StateParallel . |
protected java.lang.Runnable |
exit |
protected int |
ixCompositeState_inStatePath |
static int |
mEventConsumed
Bit in return value of a Statemachine's
#_checkTransitions(EventMsg2) or entry method for designation,
that the given Event object was used to switch. |
static int |
mEventDonotRelinquish
Bit in return value of the
processEvent(EventObject)
for designation, that the given Event object is stored in another queue, therefore it should not relinquished yet. |
static int |
mEventNotConsumed
Use this designation for
StateSimple.Trans.retTrans to signal that an event is not consumed in checkTrans(EventObject) . |
(package private) int |
millisectimeout
If set, on state entry the timer for timeout is set.
|
protected int |
modeTrans
It is either 0 or
mRunToComplete . |
static int |
mRunToComplete
Bit in return value of a Statemachine's trans and entry method for designation,
that the given State has non-event-driven transitions, therefore the trans method should be called
in the same cycle.
|
static int |
mStateEntered
Bit in return value of a Statemachine's trans and entry method for designation,
that the given State has entered yet.
|
static int |
mStateLeaved
If a composite state is leaved, any other parallel composite states don't processed then.
|
static int |
mTransit
Bit in return value of a Statemachine's trans method for designation,
that the given Transition is true.
|
static int |
notTransit
Specification of the consumed Bit in return value of a Statemachine's
#_checkTransitions(EventMsg2) or #entry(int)
method for designation, that the given Event object was not used to switch. |
protected java.lang.String |
stateId
The own identification of the state.
|
protected StateMachine |
stateMachine
Aggregation to the whole state machine.
|
protected StateSimple[] |
statePath
Path to this state from the top state.
|
(package private) StateSimple.Timeout |
transTimeout
A timeout transition created in the application.
|
static java.lang.String |
version
Version, history and license.
|
Modifier | Constructor and Description |
---|---|
protected |
StateSimple() |
Modifier and Type | Method and Description |
---|---|
(package private) int |
_checkTransitions(java.util.EventObject ev)
Check all transitions and fire one transition if true.
|
java.lang.Object |
auxInfo()
Gets the auxiliary information to that state which is set with
setAuxInfo(Object) . |
(package private) void |
buildStatePath(StateSimple enclState)
Sets the path to the state for this and all
#aSubstates , recursively call. |
(package private) void |
buildStatePathSubstates(StateSimple enclState,
int recurs)
It is overridden package-local in all derived
StateComposite , StateParallel . |
protected StateSimple.Trans |
checkTrans(java.util.EventObject ev)
This method should be overridden by the user to select a transition which should be fire with given conditions.
|
StateComposite |
compositeState()
Returns that state which is the composite state which controls the activity of that independent part of the StateMachine.
|
(package private) void |
createTransitionList(java.lang.Object stateInstance,
StateSimple.Trans parent,
int nRecurs)
Creates the list of all transitions for this state, invoked one time after constructing the statemachine.
|
(package private) void |
createTransitionListSubstate(int recurs)
Create all transition list for this state and all
#aSubstates , recursively call. |
StateSimple |
enclState()
Returns that state which is the enclosing state.
|
protected int |
entry(java.util.EventObject ev)
This method may be overridden for a entry action.
|
(package private) int |
entryTheState(java.util.EventObject ev,
boolean history)
Executes enter in this state.
|
protected void |
exit()
This method may be overridden for a exit action.
|
protected void |
exitTheState(int level)
Exits the state and all enclosing states till level.
|
java.lang.String |
getName()
Returns the name of the state, for debugging.
|
(package private) java.lang.CharSequence |
getStatePath()
Gets the path to this state.
|
java.lang.CharSequence |
infoAppend(java.lang.StringBuilder u)
Appends or returns tan information about the instance.
|
boolean |
isInState()
Check and returns true if the enclosing state has this state as active one.
|
protected boolean |
isTimeout(java.util.EventObject ev)
Checks whether the given event is the timeout event for this state.
|
private void |
prepareTransition(StateSimple.Trans trans,
int nRecurs) |
(package private) void |
prepareTransitions(StateSimple.Trans parent,
int nRecurs)
Prepares all transitions.
|
(package private) void |
prepareTransitionsSubstate(int recurs)
Prepare the own transitions.
|
private void |
printTransInfo(StateSimple.Trans trans,
java.util.EventObject ev) |
(package private) int |
processEvent(java.util.EventObject ev)
Applies an event to this state respectively processes the event with this state.
|
void |
setAuxInfo(java.lang.Object info)
Sets any auxiliary information to that state.
|
void |
setEntryAction(StateAction entry)
Sets the entry-action for this state.
|
void |
setExitAction(java.lang.Runnable exit)
Sets the exit-action for this state.
|
StateSimple[] |
statePath()
Returns the path of all states from the top state in the hierarchie of this state.
|
java.lang.String |
toString()
Returns the state Id and maybe some more debug information.
|
public static final java.lang.String version
StateSimple.Trans.exitStates
is not used anymore,
instead the StateComposite.stateAct
is taken with the statePath()
to invoke the correct exit routines.
See exitTheState(int)
.
_checkTransitions(EventObject)
now checks the transition from all enclosing but not composite states, that are StateCompositeFlat
.
That was done before in the StateComposite.processEvent(EventObject)
routine but in a more difficult algorithm. Now for debugging it is more simple.
The own checkTrans(EventObject)
is invoked firstly. If not transition is found, the checkTrans(EventObject)
of all enclosing states till a StateComposite are tested.
The transitions of an enclosing StateComposite are checked in thats StateComposite.processEvent(EventObject)
routine which calls this _checkTransitions(EventObject)
.
checkTrans(EventObject)
routine. The automatic check is removed.
Reason: A timeout event is disturbing often for debug. If it cannot be detect or prevented simply, it is adversarial. It is better to have the timeout handling
in the same routine like all other transition conditions. The isTimeout(EventObject)
routine helps to write simple code for that.
StateMachine.debugEntryExit
.
StateSimple.TransJoin
have to be quest in the checkTrans(EventObject)
routine.
The transition after the join bar can have a condition or event trigger, which is to quest in the checkTrans.
The automatically transition is removed, because it is not explicitly and cannot have conditions.
Applications should be adapted.
setAuxInfo(Object)
, auxInfo()
used for state machine generation for C/C++
org.vishia.stateMachine.StateSimpleBase
, changed concept:
Nested writing of states, less code, using reflection for missing instances and data.
#exitAction()
instead #exitTheState()
!
#entry(EventMsg2)
and the #entryAction(EventMsg2)
should get the event
from the transition. It needs adaption in users code. The general advantage is: The entry action can use data
from the event. A user algorithm does not need to process the events data only in the transition. A user code
can be executed both in a special transition to a state and as entry action. Both possibilities do not distinguish
in formal possibilities. The second advantage is: If the event is used, it should given to the next entry. If it is
not used, a 'null' should be given. The user need not pay attention in the correct usage of mEventConsumed
or not.
mStateEntered
is returned on any #entry(EventMsg2)
. If the state is not changed,
a 'return 0;' should be written in the transition code. With the new bit especially the debugging can distinguish
a state changed from a non-switching transition.
#entryAction()
is given. It is more simple to use.
public static final int notTransit
#_checkTransitions(EventMsg2)
or #entry(int)
method for designation, that the given Event object was not used to switch. The value of this is 0.public static final int mEventConsumed
#_checkTransitions(EventMsg2)
or entry method for designation,
that the given Event object was used to switch. It is 0x01.public static final int mEventDonotRelinquish
processEvent(EventObject)
for designation, that the given Event object is stored in another queue, therefore it should not relinquished yet.
See EventConsumer.mEventDonotRelinquish
public static final int mTransit
mEventConsumed
if the event forces true.
If this bit is set without mEventConsumed
though an event is given the transition has not tested the event.
In that case the event may be used in the following run-to-complete transitions.public static final int mStateEntered
#entry(EventMsg2)
action is not called.
It means a state switch has not occurred. Used for debug.public static final int mStateLeaved
public static final int mRunToComplete
public static final int mEventNotConsumed
StateSimple.Trans.retTrans
to signal that an event is not consumed in checkTrans(EventObject)
.protected StateMachine stateMachine
protected StateSimple enclState
protected StateComposite compositeState
protected int ixCompositeState_inStatePath
private java.lang.Object auxInfo
protected StateSimple[] statePath
protected java.lang.String stateId
int millisectimeout
StateSimple.Timeout transTimeout
TimeOrder evTimeout
StateParallel
.
This reference is null if this state has not a timeout transition.
If this state is the top state or a StateParallel this refers the same instance for all states of this Composite.
More as one parallel states have differen timeouts.protected final int modeTrans
mRunToComplete
. Or to the return value of entry.public int ctEntry
public long dateLastEntry
public long durationLast
protected StateAction entry
protected java.lang.Runnable exit
private StateSimple.Trans[] aTransitions
StateSimple
in a Java written state machine.
The transitions may be given with #addTransition(Trans)
instead in a State machine which is parsed and translated
for another language.public void setAuxInfo(java.lang.Object info)
org.vishia.stateMGen.StateMGen
in the component srcJava_Zbnf
to help generate a state machine for C language. But it can be used in the user's application in any way too.info
- Any object referred from this state.public java.lang.Object auxInfo()
setAuxInfo(Object)
. This method is used especially in org.vishia.stateMGen.StateMGen
in the component srcJava_Zbnf
to help generate a state machine for C language. But it can be used in the user's application in any way too.public StateSimple[] statePath()
public StateComposite compositeState()
StateCompositeFlat
and it is not the rootState.public StateSimple enclState()
compositeState()
. Otherwise it may be a
StateCompositeFlat
or a StateParallel
.
Note: If a composite state is only used to build a pool of simple states which have common transition(s) the pool-building state
is a StateCompositeFlat
and it is not the compositeState()
.public void setEntryAction(StateAction entry)
entry(EventObject)
.
This action is used only if the method entry(EventObject)
is not overridden.action
- public void setExitAction(java.lang.Runnable exit)
exit()
.
This action is used only if the method exit()
is not overridden.action
- protected boolean isTimeout(java.util.EventObject ev)
ev
- protected int entry(java.util.EventObject ev)
entry
or #entryMethod
is either not used
or it is used especially in the overridden method responsible to the user.
If this method is not overridden, a given StateAction
stored on entry
is executed.
That may be the execution of the #entryMethod
.ev
- The data of the event can be used for the entry action.mRunToComplete
if next states should be tested for conditions.protected void exit()
exit
or #exitMethod
is either not used
or it is used especially in the overridden method responsible to the user.
If this method is not overridden, a given Runnable
stored on exit
is executed.
That may be the execution of the #exitMethod
.void buildStatePathSubstates(StateSimple enclState, int recurs)
StateComposite
, StateParallel
.enclState
- final void buildStatePath(StateSimple enclState)
#aSubstates
, recursively call.enclState
- recurs
- void createTransitionListSubstate(int recurs)
#aSubstates
, recursively call.
It is overridden package-local in all derived StateComposite
, StateParallel
.recurs
- void createTransitionList(java.lang.Object stateInstance, StateSimple.Trans parent, int nRecurs)
void prepareTransitionsSubstate(int recurs)
StateCompositeFlat
etc
which checks the sub states too.recurs
- recursion for sub states.void prepareTransitions(StateSimple.Trans parent, int nRecurs)
private void prepareTransition(StateSimple.Trans trans, int nRecurs)
public final boolean isInState()
protected StateSimple.Trans checkTrans(java.util.EventObject ev)
StateMachine.processEvent(EventObject)
is called.
Q Override Trans selectTrans(Event,?> ev) { if(ev instanceof MyEvent) return trans_A; else if(otherCondition) return trans_B; else return null; }It is possible to write the action code immediately in this method. Then
StateSimple.Trans.doExit()
should be invoked before.
If StateSimple.Trans.doExit()
is not invoked the exit actions are executed after the transition code. That is not problematically
but not conform to the UML state machine definition:Q Override Trans selectTrans(Event,?> ev) { if(ev instanceof MyEvent){ trans_A.doExit(); //it exits all necessary states may be from a deeper level. users_transition_code(); return trans_A; } else if(otherCondition) { users_transition_code(); //doExit() will be invoked from the calling level. return trans_B; } else return null; }
StateSimple.Trans
which may be overridden anonymously.
Especially the StateSimple.Trans.action(EventObject)
can be overridden or the field StateSimple.Trans.action
can be set.
An overridden Trans#check(EventObject)
field Trans#check
of that transitions is not regarded.
Trans trans_A = new Trans(Destination.class); //without action Trans trans_B = new Trans(Destination.class) { protected void action(Event,?> ev) { //do action code } }; Trans trans_C = new Trans(Destination.class) { { action = ref.action; //instanceof StateAction, callback } };
ev
- The event to test.int processEvent(java.util.EventObject ev)
StateComposite.processEvent(EventObject)
with an more complex algorithm.
For a simple state it invokes only _checkTransitions(EventObject)
.ev
- The event to apply.mEventConsumed
, mTransit
, mRunToComplete
, mStateEntered
, mStateLeaved
.final int _checkTransitions(java.util.EventObject ev)
StateComposite#_processEvent(EventMsg2)
if the state is active.ev
- Given eventmRunToComplete
, 131072, mEventConsumed
, mStateEntered
to control the event processing.private void printTransInfo(StateSimple.Trans trans, java.util.EventObject ev)
final int entryTheState(java.util.EventObject ev, boolean history)
StateSimple.Trans.doEntry(EventObject)
immediately for the entry states,
in StateCompositeFlat.entryDefaultState()
or in StateComposite.entryDeepHistory(EventObject)
or StateComposite.entryShallowHistory(EventObject)
.
It enters only in this state. Enter is sub states is done in the calling routines.
StateComposite.stateAct
will be set in its compositeState()
to mark this state as current one..
compositeState()
(its composite) will be marked as StateComposite.isActive
(may be marked already).
ctEntry
+=1, dateLastEntry
=yet, durationLast
=0.
StateComposite
without history, sets the own StateComposite.stateAct
to null,
therewith forces maybe entry in the default state if an entry in a member of the composite is not done by this transition
but sets its own StateComposite.isActive
. Note: The enter in the default state is done by the next state switch.
StateComposite.stateAct
will be entered as history state
in the StateComposite.entryDeepHistory(EventObject)
or StateComposite.entryShallowHistory(EventObject)
in the StateSimple.Trans.doEntry(EventObject)
entry(EventObject)
action.
ev
- protected final void exitTheState(int level)
compositeState()
.
It means always the really current state will be exiting. See StateSimple.Trans.doExit()
.
evTimeout
then it is removed from StateMachine.theThread
. EventTimerThread.removeTimeEntry(TimeOrder)
.
StateParallel
all current parallel states are exiting.
exit()
routine is invoked, or the exit
is run, if setExitAction(Runnable)
was set.
StateMachine.debugEntryExit
is set the exit text is written with System.out().
StateMachine.permitException
is set, or a RuntimeException is forwarding.
level
- according to the statePath
the last level which is exiting. It is the index in the statepath array.java.lang.CharSequence getStatePath()
stateId
of all enclosing states
separated with a dot and at least this stateId.
For example "topStateName.compositeState.thisState".public java.lang.String getName()
public java.lang.CharSequence infoAppend(java.lang.StringBuilder u)
InfoAppend
StringBuilder u = new StringBulder(1000); u.append(something_else); myInstance.infoAppend(u); //uses this interface u.append(some_more); System.out.append(u); //output the information String savedInfo = u.toString(); //save permanent.Implementing pattern
QOverride public infoAppend(StringBuilder u) { if(u == null){ u = new StringBuilder(); } //it can be null! u.append(special_information).append(": ").append(somewhatElse); return u; }Contiguity with toString: It uses the same information, assembled in a StringBuilder:
QOverride public String toString(){ return infoAppend(null).toString()); }
infoAppend
in interface InfoAppend
u
- if not null then the info is appended to u, u is returned.
public java.lang.String toString()
toString
in class java.lang.Object
Object.toString()