Init basesystem source codes.
[staging/basesystem.git] / nsframework / framework_unified / client / NS_FrameworkCore / src / statemachine / frameworkunified_sm_externaltransition.cpp
1 /*
2  * @copyright Copyright (c) 2016-2020 TOYOTA MOTOR CORPORATION.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 ///////////////////////////////////////////////////////////////////////////////////////////////////
18 /// \defgroup <<Group Tag>> <<Group Name>>
19 /// \ingroup  tag_NSFramework
20 /// .
21 ///////////////////////////////////////////////////////////////////////////////////////////////////
22
23 ///////////////////////////////////////////////////////////////////////////////////////////////////
24 /// \ingroup  tag_NSFramework
25 /// \brief
26 ///
27 /// This file has the CFrameworkunifiedExternalTransition class definitions. CFrameworkunifiedExternalTransition is derived
28 /// from CFrameworkunifiedTransition class.This class implements the FrameworkunifiedReaction interface to support transition
29 /// from one state to another state.
30 ///
31 ///////////////////////////////////////////////////////////////////////////////////////////////////
32
33 ///////////////////////////////////////////////////////////////////////////////////////////////////
34 // Include Files
35 ///////////////////////////////////////////////////////////////////////////////////////////////////
36 #include <native_service/frameworkunified_sm_externaltransition.h>
37 #include <native_service/frameworkunified_sm_state.h>
38 #include <native_service/frameworkunified_sm_framework_types.h>
39 #include <native_service/frameworkunified_sm_guard.h>
40 #include <native_service/frameworkunified_sm_action.h>
41 #include <vector>
42 ///////////////////////////////////////////////////////////////////////////////////////////
43 /// CFrameworkunifiedState
44 /// Parameterized constructor
45 ///////////////////////////////////////////////////////////////////////////////////////////
46 CFrameworkunifiedExternalTransition::CFrameworkunifiedExternalTransition(CFrameworkunifiedState *f_pTargetState): CFrameworkunifiedTransition(f_pTargetState) {
47   m_pGuard = NULL;
48
49   // Create the condition list
50   m_pActionList = new std::vector<CFrameworkunifiedAction * >();  // LCOV_EXCL_BR_LINE 11:except branch
51 }
52
53 ///////////////////////////////////////////////////////////////////////////////////////////
54 /// ~CFrameworkunifiedState
55 /// Class destructor
56 ///////////////////////////////////////////////////////////////////////////////////////////
57 CFrameworkunifiedExternalTransition::~CFrameworkunifiedExternalTransition() {
58   FRAMEWORKUNIFIEDLOG(ZONE_NS_INFO, __FUNCTION__, "+");
59   if (m_pActionList) {
60     TActionListIterator l_itActionList =  m_pActionList->begin();
61
62     while (m_pActionList->end() != l_itActionList) {
63       if (NULL != *l_itActionList) {
64         delete *l_itActionList;
65         *l_itActionList = NULL;
66       }
67       l_itActionList++;
68     }
69     // clear condition list
70     m_pActionList->clear();
71     delete m_pActionList;
72     m_pActionList = NULL;
73   }
74 }
75
76 ///////////////////////////////////////////////////////////////////////////////////////////
77 /// FrameworkunifiedReaction
78 /// The reaction for an event is implemented in this function. For external transition, Exit
79 /// of the source state is called and entry of the target state is called recursively.
80 ///////////////////////////////////////////////////////////////////////////////////////////
81 CFrameworkunifiedState *CFrameworkunifiedExternalTransition::FrameworkunifiedReaction(CFrameworkunifiedState *f_pSourceState, CEventDataPtr f_pData) {
82   CFrameworkunifiedState *l_pActiveState = NULL;
83   BOOL l_bAllowTransition = FALSE;
84
85   try {
86     CHKNULL(f_pSourceState);
87     CHKNULL(m_pTargetState);
88
89     // Check if External transition has Guard condition
90     if (m_pGuard) {
91       // Evaluate guard condition
92       l_bAllowTransition = m_pGuard->FrameworkunifiedEvaluate();
93     } else {
94       // If Guard is not available then allow transition
95       l_bAllowTransition = TRUE;
96     }
97
98     if (l_bAllowTransition) {
99       l_pActiveState = ExecuteTransition(f_pSourceState, f_pData);  // LCOV_EXCL_BR_LINE 11:except branch
100
101     } else {
102       // No state changed
103       FRAMEWORKUNIFIEDLOG(ZONE_NS_SM_USR_INFO, __FUNCTION__, "Guard condition for External Transition "
104         "from state %s to state %s failed"
105         , f_pSourceState->m_strStateName.c_str(), m_pTargetState->m_strStateName.c_str());
106
107       l_pActiveState = f_pSourceState;
108     }
109   } catch (std::exception &e) {
110     FRAMEWORKUNIFIEDLOG(ZONE_NS_ERR, __FUNCTION__, "Exception %s", e.what());
111     return NULL;
112   }
113
114   return l_pActiveState;
115 }
116
117 EFrameworkunifiedStatus CFrameworkunifiedExternalTransition::FrameworkunifiedSetGuard(CFrameworkunifiedGuard *f_pGuard) {
118   EFrameworkunifiedStatus l_eFrameworkunifiedStatus = eFrameworkunifiedStatusOK;
119   try {
120     CHKNULL(f_pGuard);
121     m_pGuard = f_pGuard;
122   } catch (std::exception &e) {
123     FRAMEWORKUNIFIEDLOG(ZONE_NS_ERR, __FUNCTION__, "Exception %s", e.what());
124     l_eFrameworkunifiedStatus = eFrameworkunifiedStatusNullPointer;
125   }
126
127   return l_eFrameworkunifiedStatus;
128 }
129
130 CFrameworkunifiedState *CFrameworkunifiedExternalTransition::ExecuteTransition(CFrameworkunifiedState *f_pSourceState, CEventDataPtr f_pData) {
131   CFrameworkunifiedState *l_pActiveState = NULL;
132   try {
133     CHKNULL(m_pTargetState);
134     CHKNULL(f_pSourceState);
135     CFrameworkunifiedState *l_pTargetState = m_pTargetState;
136     CFrameworkunifiedState *l_pCurrentState = f_pSourceState;
137
138
139
140
141     // Find the common parent of the source and target state
142     // and then call recursively  OnExit on source state and
143     // OnEntry on parent state
144     BOOL l_bFoundCommonParent = FALSE;
145     while (l_pCurrentState->m_pParentState) {
146       while (l_pTargetState->m_pParentState) {
147         // Check if current source state and target state has common parent
148         if (l_pCurrentState->m_pParentState == l_pTargetState->m_pParentState) {
149           l_bFoundCommonParent = TRUE;
150           break;
151         } else {
152           // Set the next target parent state
153           l_pTargetState = l_pTargetState->m_pParentState;
154         }
155       }
156
157       if (l_bFoundCommonParent) {
158         break;
159       } else {
160         // Set the next source parent state
161         l_pCurrentState = l_pCurrentState->m_pParentState;
162         l_pTargetState = m_pTargetState;
163       }
164     }
165
166     if (l_bFoundCommonParent) {
167       // recursively execute the exit on the current state
168       l_pCurrentState->FrameworkunifiedOnHSMStop(f_pData);
169
170       // execute actions associated with the external transition
171       CHKNULL(m_pActionList);
172       TActionListIterator l_itActionList =  m_pActionList->begin();
173
174       // iterate action list and execute actions
175       while (m_pActionList->end() != l_itActionList) {
176         CFrameworkunifiedAction *l_pAction = *l_itActionList;
177         CHKNULL(l_pAction);
178
179         l_pAction->FrameworkunifiedAction(f_pSourceState, l_pTargetState, f_pData);
180
181         l_itActionList++;
182       }
183
184       // Set the target state as a active state
185       CFrameworkunifiedState *l_pState = m_pTargetState;
186       while (l_pState->m_pParentState != l_pTargetState->m_pParentState) {
187         CHKNULL(l_pState->m_pParentState);
188
189         l_pState->m_pParentState->m_pActiveState = l_pState;
190         l_pState = l_pState->m_pParentState;
191       }
192
193
194       // recursively execute the entry on the target state
195       l_pActiveState = l_pTargetState->FrameworkunifiedOnHSMStart(f_pData);
196
197       FRAMEWORKUNIFIEDLOG(ZONE_NS_SM_USR_INFO, __FUNCTION__, "External Transition from state %s to state %s"
198              , f_pSourceState->m_strStateName.c_str(), m_pTargetState->m_strStateName.c_str());
199     } else {
200       FRAMEWORKUNIFIEDLOG(ZONE_NS_SM_USR_INFO, __FUNCTION__, "External Transition from state %s to state %s failed"
201              , f_pSourceState->m_strStateName.c_str(), m_pTargetState->m_strStateName.c_str());
202       return NULL;
203     }
204   } catch (std::exception &e) {
205     FRAMEWORKUNIFIEDLOG(ZONE_NS_ERR, __FUNCTION__, "Exception %s", e.what());
206   }
207
208   return l_pActiveState;
209 }
210
211 EFrameworkunifiedStatus CFrameworkunifiedExternalTransition::FrameworkunifiedAddAction(CFrameworkunifiedAction *f_pAction) {
212   EFrameworkunifiedStatus l_eFrameworkunifiedStatus = eFrameworkunifiedStatusOK;
213   try {
214     CHKNULL(m_pActionList);
215
216     CHKNULL(f_pAction);
217
218     m_pActionList->push_back(f_pAction);
219   } catch (std::exception &e) {
220     FRAMEWORKUNIFIEDLOG(ZONE_NS_ERR, __FUNCTION__, "Exception %s", e.what());
221     l_eFrameworkunifiedStatus = eFrameworkunifiedStatusNullPointer;
222   }
223
224   return l_eFrameworkunifiedStatus;
225 }