以下のコードのようなことができます。ただし、内部ステート マシンを初期化するのは少し面倒です。
編集: 一般的な親イベントを追加します。
import java.util.*;
interface Event {}
enum AEvent implements Event {
e1
}
enum BEvent implements Event {
e1
}
interface State {
State processEvent(Event event);
}
enum AState implements State {
s1,s2;
public State processEvent(Event event) {
return eventToState.get(event);
}
final Map<Event,State> eventToState=new TreeMap<Event,State>();
}
enum BState implements State {
s1,s2;
public State processEvent(Event event) {
return eventToState.get(event);
}
final Map<Event,State> eventToState=new TreeMap<Event,State>();
}
interface ParentEvent {}
enum ParentEvents implements ParentEvent {
e1;
}
class InnerStateMachine<St extends Enum<?> &State,Ev extends Enum<?> &Event,PEV extends Enum<?> &ParentEvent> {
public InnerStateMachine(St state) {
this.state=state;
}
St state() {
return state;
}
St processEvent(Ev event) {
State s=state.processEvent(event);
if(s instanceof Enum<?>) {
PEV pev=stateToParentEvent.get(s);
if(pev!=null)
System.out.println("fire parent event "+pev);
return state=(St)s; // unsafe cast
} else throw new RuntimeException("oops");
}
St state;
Map<St,PEV> stateToParentEvent=new TreeMap<St,PEV>();
}
public class So15804185 {
public static void main(String[] args) {
AState.s1.eventToState.put(AEvent.e1,AState.s2);
BState.s1.eventToState.put(BEvent.e1,BState.s2);
InnerStateMachine<AState,AEvent,ParentEvents> innerStateMachineA=new InnerStateMachine<AState,AEvent,ParentEvents>(AState.s1);
innerStateMachineA.stateToParentEvent.put(AState.s2,ParentEvents.e1);
innerStateMachineA.processEvent(AEvent.e1);
System.out.println(innerStateMachineA.state());
InnerStateMachine<BState,BEvent,ParentEvents> innerStateMachineB=new InnerStateMachine<BState,BEvent,ParentEvents>(BState.s1);
innerStateMachineB.processEvent(BEvent.e1);
System.out.println(innerStateMachineA.state());
}
}