package org.eclipse.etrice.ui.behavior.commands; import java.util.ArrayList; import java.util.HashMap; import org.eclipse.emf.ecore.EObject; import org.eclipse.etrice.core.room.ActorClass; import org.eclipse.etrice.core.room.BaseState; import org.eclipse.etrice.core.room.ChoicePoint; import org.eclipse.etrice.core.room.RefinedState; import org.eclipse.etrice.core.room.RoomFactory; import org.eclipse.etrice.core.room.State; import org.eclipse.etrice.core.room.StateGraph; import org.eclipse.etrice.core.room.TrPoint; import org.eclipse.etrice.core.room.Transition; class StateGraphContext { private ArrayList<StateGraphContext> children = new ArrayList<StateGraphContext>(); private StateGraph stateGraph; private ArrayList<State> states = new ArrayList<State>(); private ArrayList<ChoicePoint> chPoints = new ArrayList<ChoicePoint>(); private ArrayList<TrPoint> trPoints = new ArrayList<TrPoint>(); private ArrayList<Transition> transitions = new ArrayList<Transition>(); static HashMap<EObject, StateGraphContext> obj2ctx = new HashMap<EObject, StateGraphContext>(); static StateGraphContext createContextTree(ActorClass ac) { // the top level state graph is always the one of our actor class if (ac.getStateMachine()==null) ac.setStateMachine(RoomFactory.eINSTANCE.createStateGraph()); ArrayList<ActorClass> classes = new ArrayList<ActorClass>(); { ActorClass a = ac; while (a!=null) { classes.add(0, a); a = a.getBase(); } } obj2ctx.clear(); StateGraphContext tree = null; for (ActorClass cls : classes) { if (cls.getStateMachine()!=null) { if (tree==null) tree = new StateGraphContext(cls.getStateMachine()); else tree.merge(cls.getStateMachine()); } } return tree; } private StateGraphContext(StateGraph sg) { this.stateGraph = sg; init(sg); } private void init(StateGraph sg) { for (State s : sg.getStates()) { states.add(s); obj2ctx.put(s, this); } for (ChoicePoint cp : sg.getChPoints()) { chPoints.add(cp); obj2ctx.put(cp, this); } for (TrPoint tp : sg.getTrPoints()) { trPoints.add(tp); obj2ctx.put(tp, this); } for (Transition t : sg.getTransitions()) { transitions.add(t); obj2ctx.put(t, this); } // recurse for (State s : sg.getStates()) { if (s.getSubgraph()!=null) children.add(new StateGraphContext(s.getSubgraph())); } } private void merge(StateGraphContext other) { for (State s : other.getStates()) { states.add(s); obj2ctx.put(s, this); } for (ChoicePoint cp : other.getChPoints()) { chPoints.add(cp); obj2ctx.put(cp, this); } for (TrPoint tp : other.getTrPoints()) { trPoints.add(tp); obj2ctx.put(tp, this); } for (Transition t : other.getTransitions()) { transitions.add(t); obj2ctx.put(t, this); } } private void merge(StateGraph other) { // add other contents up to refined states for (State s : other.getStates()) { if (s instanceof BaseState) { states.add(s); obj2ctx.put(s, this); } } for (ChoicePoint cp : other.getChPoints()) { chPoints.add(cp); obj2ctx.put(cp, this); } for (TrPoint tp : other.getTrPoints()) { trPoints.add(tp); obj2ctx.put(tp, this); } for (Transition t : other.getTransitions()) { transitions.add(t); obj2ctx.put(t, this); } // recurse for (State s : other.getStates()) { if (s instanceof BaseState) if (s.getSubgraph()!=null) children.add(new StateGraphContext(s.getSubgraph())); } // refined states (need no recursion since refined states can only occur on the top level) for (State s : other.getStates()) { if (s instanceof RefinedState) { State base = ((RefinedState) s).getBase(); StateGraphContext ctx = obj2ctx.get(base); assert(ctx!=null): "should have visited base state already"; // remove base and put refined in place ctx.getStates().remove(base); ctx.getStates().add(s); // merge contexts StateGraphContext sub = null; if (base.getSubgraph()!=null || s.getSubgraph()!=null) { sub = new StateGraphContext(s.getSubgraph()); ctx.getChildren().add(sub); } if (base.getSubgraph()!=null) { StateGraphContext basesub = null; for (StateGraphContext bs : ctx.getChildren()) { if (bs.getParentState()==base) { basesub = bs; break; } } if (basesub!=null) { ctx.getChildren().remove(basesub); sub.merge(basesub); } else { assert(false): "context not found"; } } } } } public State getParentState() { if (stateGraph.eContainer().eContainer() instanceof State) return (State) stateGraph.eContainer().eContainer(); return null; } public ArrayList<StateGraphContext> getChildren() { return children; } public ArrayList<State> getStates() { return states; } public ArrayList<ChoicePoint> getChPoints() { return chPoints; } public StateGraph getStateGraph() { return stateGraph; } public ArrayList<TrPoint> getTrPoints() { return trPoints; } public ArrayList<Transition> getTransitions() { return transitions; } }