Skip to main content
aboutsummaryrefslogtreecommitdiffstats
blob: 0a88f76c53fdda903b631c2f0c61bf47a0c8e161 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
/*******************************************************************************
 * Copyright (c) 2014 protos software gmbh (http://www.protos.de).
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 * 
 * CONTRIBUTORS:
 * 		Henrik Rentz-Reichert (initial contribution)
 * 
 *******************************************************************************/

package org.eclipse.etrice.generator.fsm.generic

import org.eclipse.etrice.core.fsm.fSM.Transition
import org.eclipse.etrice.core.genmodel.fsm.fsmgen.ExpandedModelComponent
import java.util.List
import org.eclipse.etrice.core.fsm.fSM.State
import java.util.ArrayList
import org.eclipse.etrice.core.fsm.fSM.StateGraph
import org.eclipse.etrice.core.fsm.fSM.TransitionPoint
import org.eclipse.etrice.core.fsm.fSM.ModelComponent
import org.eclipse.etrice.core.fsm.util.FSMHelpers
import com.google.inject.Inject
import org.eclipse.etrice.core.fsm.fSM.DetailCode
import org.eclipse.etrice.core.fsm.fSM.Guard
import org.eclipse.etrice.core.fsm.fSM.CPBranchTransition

/**
 * @author Henrik Rentz-Reichert
 *
 */
class FSMExtensions {
	
	@Inject protected extension FSMHelpers
	
	//-------------------------------------------------------
	// union methods
	
	/**
	 * the template type is T
	 * @param l an iterable of type T
	 * @param e a single element of type T
	 * @return the union of the iterable and the element as new list
	 */
	def <T> List<T> union(Iterable<T> l, T e) {
		var ret = new ArrayList<T>()
		ret.addAll(l)
		ret.add(e)
		return ret
	}
	
	/**
	 * the template type is T
	 * @param l1 an iterable of type T
	 * @param l2 a second iterable of type T
	 * @return the union of the two iterables as new list
	 */
	def <T> List<T> union(Iterable<T> l1, Iterable<T> l2) {
		var ret = new ArrayList<T>()
		ret.addAll(l1)
		ret.addAll(l2)
		return ret
	}
	
	/**
	 * the template type is T
	 * @param l1 a list of elements of type T
	 * @param l2 a second list of elements of type T
	 * @return a new list with the contents of l1 
	 */
	def <T> List<T> minus(List<T> l1, List<T> l2){
		var ret = new ArrayList<T>(l1)
		ret.removeAll(l2)
		return ret;
	}

    //-------------------------------------------------------
    // state graph related methods

	/**
	 * @param ac an {@link ExpandedActorClass}
	 * @param s a {@link State}
	 * @return a list of {@link Transition}s starting at the state and going up in the hierarchy
	 * 		following the logic of evaluation of firing conditions
	 */
	def List<Transition> getOutgoingTransitionsHierarchical(ExpandedModelComponent ac, State s) {
		var result = new ArrayList<Transition>()
		
		// own transitions
		result.addAll(ac.getOutgoingTransitions(s))

		// transition points on same level
		var sg = s.eContainer() as StateGraph
		for (tp : sg.getTrPoints()) {
			if (tp instanceof TransitionPoint)
				result.addAll(ac.getOutgoingTransitions(tp))
		}
		
		// recurse to super states
		if (sg.eContainer() instanceof State) {
			result.addAll(getOutgoingTransitionsHierarchical(ac, sg.eContainer() as State))
		}
		
		return result;
	}

    /**
     * @param states a list of {@link State}s
     * @return a list ordered such that leaf states are last
     */
    def getLeafStatesLast(List<State> states) {
        val leaf = states.filter(s|s.leaf)
        val nonLeaf = states.filter(s|!s.leaf)
        
        nonLeaf.union(leaf)
    }

    /**
     * @param ac an {@link ActorClass}
     * @return a list of all leaf states
     */
    def List<State> getAllLeafStates(ModelComponent mc) {
        mc.stateMachine.leafStateList
    }

    /**
     * @param ac an {@link ActorClass}
     * @return a list of simple states with leaf states last
     */
    def List<State> getAllBaseStatesLeavesLast(ModelComponent mc) {
        mc.allBaseStates.getLeafStatesLast
    }

    /**
     * @param ac an {@link ModelComponent}
     * @return the number of all inherited states
     */
    def int getNumberOfInheritedStates(ModelComponent mc) {
        if (mc.base==null)
            return 0
        else
            return mc.base.stateMachine.stateList.size+mc.base.numberOfInheritedStates
    }
    
    /**
     * @param ac an {@link ModelComponent}
     * @return the number of all inherited base (or simple) states
     */
    def int getNumberOfInheritedBaseStates(ModelComponent ac) {
        if (ac.base==null)
            return 0
        else
            return ac.base.stateMachine.baseStateList.size+ac.base.numberOfInheritedBaseStates
    }
	
	def boolean isConditionOrGuard(DetailCode dc) {
        val parent = dc.eContainer
        switch (parent) {
            Guard: true
            CPBranchTransition: parent.condition==dc
            default:
                false
        }
	}
}

Back to the top