openETCS
case study for the European Train Control System developed for the authors dissertation
CPPGenerator.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2010-2011
3  Johannes Feuser <feuser@uni-bremen.de>
4  This file is part of the openETCS library.
5 
6  The openETCS library is free software: you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation, either version 3 of the License, or
9  any later version.
10 
11  The openETCS library is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU General Public License for more details.
15 
16  You should have received a copy of the GNU General Public License
17  along with the openETCS library. If not, see <http://www.gnu.org/licenses/>.
18 */
19 
20 /*!
21  * \author Johannes Feuser <feuser@uni-bremen.de>
22  * \brief
23  */
24 
25 #include "CPPGenerator.h"
26 #include "../../GOPPRR/Graph.h"
27 #include "../../GOPPRR/Project.h"
28 #include "../../GOPPRR/Object.h"
29 #include "../../GOPPRR/Port.h"
30 
31 
32 
33 
34 namespace oETCS {
35 
36 namespace GEN {
37 
38 
40 {
41  // Bouml preserved body begin 0009A902
42  // create map for function block types
43  m_FBMap["AND"] = "CAnd";
44  m_FBMap["OR"] = "COr";
45  m_FBMap["XOR"] = "CXor";
46  m_FBMap["NOT"] = "CNot";
47  m_FBMap["Sum"] = "CSum";
48  m_FBMap["Subtraction"] = "CSubstraction";
49  m_FBMap["Division"] = "CDivision";
50  m_FBMap["Multiplication"] = "CMultiplication";
51  m_FBMap["DoubleEqual"] = "CDoubleEqual";
52  m_FBMap["IntEqual"] = "CIntEqual";
53  m_FBMap["StringEqual"] = "CStringEqual";
54  m_FBMap["DoubleEqualOrGreater"] = "CDoubleEqualOrGreater";
55  m_FBMap["DoubleGreater"] = "CDoubleGreater";
56  m_FBMap["IntGreater"] = "CIntGreater";
57  m_FBMap["DoubleArrayAccessor"] = "CDoubleArrayAccessor";
58  m_FBMap["VariableStorage"] = "CStorage";
59  m_FBMap["Odometer"] = "COdometer";
60  m_FBMap["ServiceBrake"] = "CServiceBrake";
61  m_FBMap["EmergencyBrake"] = "CEmergencyBrake";
62  m_FBMap["BrakingToTargetSpeed"] = "CBrakingToTargetSpeed";
63  m_FBMap["CeelingSpeedControl"] = "CCeelingSpeedControl";
64  m_FBMap["CommunicationReader"] = "CComBlockIn";
65  m_FBMap["CommunicationSender"] = "CComBlockOut";
66  m_FBMap["BoolGate"] = "CBoolGate";
67  m_FBMap["DoubleGate"] = "CDoubleGate";
68  m_FBMap["StringGate"] = "CStringGate";
69  m_FBMap["BoolSwitch"] = "CBoolSwitch";
70  m_FBMap["DoubleSwitch"] = "CDoubleSwitch";
71  m_FBMap["StringSwitch"] = "CStringSwitch";
72  m_FBMap["ModeGuard"] = "CEVCCondition";
73  m_FBMap["ApplicationLevelType"] = "CLevelCondition";
74  m_FBMap["DMIOutput"] = "CDMIOutput";
75  m_FBMap["DMIInput"] = "CDMIInput";
76  m_FBMap["EnteredTrigger"] = "CEnteredTrigger";
77  m_FBMap["EmbeddedStateMachine"] = "CControlFlow";
78  m_FBMap["StateGuard"] = "CCondition";
79 
80  // create map for function block methods/ports
81  m_FBMMap["StringEqual::IsEqual"] = "Equal";
82  m_FBMMap["IntEqual::IsEqual"] = "Equal";
83  m_FBMMap["IntEqual::Input1"] = "iInput1";
84  m_FBMMap["IntEqual::Input2"] = "iInput2";
85  m_FBMMap["DoubleEqual::IsEqual"] = "Equal";
86  m_FBMMap["DoubleEqual::Input1"] = "dInput1";
87  m_FBMMap["DoubleEqual::Input2"] = "dInput2";
88  m_FBMMap["Sum::Addend1"] = "dAddend1";
89  m_FBMMap["Sum::Addend2"] = "dAddend2";
90  m_FBMMap["Sum::Addend3"] = "dAddend3";
91  m_FBMMap["Subtraction::Minuend"] = "dMinuend";
92  m_FBMMap["Subtraction::Subtrahend"] = "dSubtrahend";
93  m_FBMMap["BrakingToTargetSpeed::AdhesionFactor"] = "dAdhesionFactor";
94  m_FBMMap["EmbeddedStateMachine::Start"] = "bStart";
95  m_FBMMap["DMIInput::PredefinedString"] = "PreStringMessage";
96  m_FBMMap["DMIInput::PredefinedDouble"] = "dPreDoubleMessage";
97  m_FBMMap["DMIInput::DataEntered"] = "EnteredData";
98  m_FBMMap["DMIInput::Visibility"] = "bVisible";
99  m_FBMMap["DMIOutput::IntMessage"] = "iIntMessage";
100  m_FBMMap["DMIOutput::DoubleMessage"] = "dDoubleMessage";
101  m_FBMMap["DMIOutput::BoolMessage"] = "bBoolMessage";
102  m_FBMMap["DMIOutput::Visibility"] = "bVisible";
103  m_FBMMap["StateGuard::Guard"] = "bGuard";
104  m_FBMMap["NOT::Input"] = "bInput";
105  m_FBMMap["NOT::NotResult"] = "Result";
106  m_FBMMap["OR::Input1"] = "bInput1";
107  m_FBMMap["OR::Input2"] = "bInput2";
108  m_FBMMap["OR::OrResult"] = "Result";
109  m_FBMMap["AND::AndResult"] = "Result";
110  m_FBMMap["AND::Input1"] = "bInput1";
111  m_FBMMap["AND::Input2"] = "bInput2";
112  m_FBMMap["DoubleGreater::GreaterValue"] = "dInput1";
113  m_FBMMap["DoubleGreater::LessValue"] = "dInput2";
114  m_FBMMap["DoubleGreater::IsGreater"] = "Greater";
115  m_FBMMap["IntGreater::GreaterValue"] = "iInput1";
116  m_FBMMap["IntGreater::LessValue"] = "iInput2";
117  m_FBMMap["IntGreater::IsGreater"] = "Greater";
118  m_FBMMap["DoubleEqualOrGreater::GreaterValue"] = "dInput1";
119  m_FBMMap["DoubleEqualOrGreater::LessValue"] = "dInput2";
120  m_FBMMap["DoubleEqualOrGreater::IsGreaterOrEqual"] = "EqualOrGreater";
121  m_FBMMap["DoubleGate::GateInput"] = "dGateInput";
122  m_FBMMap["DoubleGate::Open"] = "bOpen";
123  m_FBMMap["BoolGate::GateInput"] = "bGateInput";
124  m_FBMMap["BoolGate::Open"] = "bOpen";
125  m_FBMMap["StringGate::Open"] = "bOpen";
126  m_FBMMap["ServiceBrake::BrakeIntensity"] = "dBrakeIntensity";
127  m_FBMMap["EmergencyBrake::Active"] = "bActivation";
128  m_FBMMap["BrakingToTargetSpeed::PermittedVelocity"] = "dPermittedVelocity";
129  m_FBMMap["BrakingToTargetSpeed::DistanceOfPermittedVelocity"] = "dDistanceOfPermittedVelocity";
130  m_FBMMap["BrakingToTargetSpeed::CurrentVelocity"] = "dCurrentVelocity";
131  m_FBMMap["BrakingToTargetSpeed::CurrentAbsoluteDistance"] = "dCurrentAbsoluteDistance";
132  m_FBMMap["CeelingSpeedControl::PermittedVelocity"] = "dPermittedVelocity";
133  m_FBMMap["CeelingSpeedControl::DistanceOfPermittedVelocity"] = "dDistanceOfPermittedVelocity";
134  m_FBMMap["CeelingSpeedControl::CurrentVelocity"] = "dCurrentVelocity";
135  m_FBMMap["CeelingSpeedControl::CurrentAbsoluteDistance"] = "dCurrentAbsoluteDistance";
136  m_FBMMap["CeelingSpeedControl::AdhesionFactor"] = "dAdhesionFactor";
137  m_FBMMap["DoubleArrayAccessor::DoubleArray"] = "Array";
138  m_FBMMap["DoubleArrayAccessor::ArrayIndex"] = "iIndex";
139  m_FBMMap["DoubleArrayAccessor::ArrayValue"] = "Value";
140  m_FBMMap["CommunicationReader::TelegramReceived"] = "Received";
141  m_FBMMap["ModeGuard::Guard"] = "bGuard";
142  m_FBMMap["ApplicationLevelType::LevelSwitch"] = "bLevelSwitch";
143  m_FBMMap["DoubleSwitch::Input1"] = "dInput1";
144  m_FBMMap["DoubleSwitch::Input2"] = "dInput2";
145  m_FBMMap["DoubleSwitch::UseInput1"] = "bUseInput1";
146  // Bouml preserved body end 0009A902
147 
148 } // CCPPGenerator::CCPPGenerator() throw()
149 
150 
151 
152 
154 {
155  // Bouml preserved body begin 00103302
156  // empty destructor
157  // Bouml preserved body end 00103302
158 
159 } // CCPPGenerator::~CCPPGenerator() throw()
160 
161 
162 
163 
164 void CCPPGenerator::Generate(::DSM::CSyntaxTree * const pSyntaxTree, ::std::ostream & OutStream) throw(::oETCS::GEN::Error::CException)
165 {
166  // Bouml preserved body begin 00097202
167  bool bRootFound(false);
168  ::DSM::CGOPPRRSyntaxTree* pGOPPRR(dynamic_cast< ::DSM::CGOPPRRSyntaxTree* const >(pSyntaxTree));
169  ::GOPPRR::CProject* pProject(0);
170  ::GOPPRR::CGraph* pRootGraph(0);
171  decltype (pProject->m_GraphSet.begin()) Graph;
172  const ::std::string EVCSTATEMACHINE(__GENERATOR__EVCSTATEMACHINE__);
173 
174 
175 
176  // check, if syntax tree is not a GOPPRR tree
177  if (pGOPPRR == 0)
178  {
179  // throw exception
180  throw (::oETCS::GEN::Error::CParameter("unknown syntax tree format not supported"));
181 
182  } // if (pGOPPRR == 0)
183 
184  // get the GOPPRR project from the syntax tree
185  pProject = pGOPPRR->GetProject();
186 
187  // try to find root graph
188  for (Graph = pProject->m_GraphSet.begin(); Graph != pProject->m_GraphSet.end() && !bRootFound; Graph++)
189  {
190  // check type of current graph
191  if (Graph->second.m_Type == EVCSTATEMACHINE)
192  {
193  // set graph as root graph
194  pRootGraph = &Graph->second;
195 
196  // set found flag to true
197  bRootFound = true;
198 
199  } // if (Graph->second.m_Type == EVCSTATEMACHINE)
200 
201  } // for (Graph = pProject->m_GraphSet.begin(); Graph != pProject->m_GraphSet.end() && !bRootFound; Graph++)
202 
203  // check, if root graph was not found
204  if (!bRootFound)
205  {
206  // throw exception
207  throw (::oETCS::GEN::Error::CModel("no root graph found in model tree"));
208 
209  } // if (!bRootFound)
210 
211 
212  // reset generation maps with OIDs
213  m_GeneratedControlFlows.clear();
214  m_GeneratedEVCTransitions.clear();
215  m_GeneratedTransitions.clear();
216 
217 
218  try
219  {
220  // call internal helper method for root graph
221  this->GenerateRootGraph(pRootGraph, pProject, OutStream);
222  }
223  catch (const ::oETCS::GEN::Error::CException&)
224  {
225  // just re-throw exception here
226  throw;
227 
228  } // catch (const ::oETCS::GEN::Error::CException&)
229 
230 
231  // finally generate footer
232  this->GenerateFooter(OutStream);
233  // Bouml preserved body end 00097202
234 
235 } // void CCPPGenerator::Generate() throw(::oETCS::GEN::Error::CException)
236 
237 
238 
239 
240 void CCPPGenerator::GenerateRootGraph(GOPPRR::CGraph * const pRootGraph, GOPPRR::CProject * const pProject, ::std::ostream & OutStream) throw(::GOPPRR::Error::CException)
241 {
242  // Bouml preserved body begin 00097502
243  decltype (pProject->m_GraphSet.begin()) GGraph;
244  decltype (pProject->m_GraphSet) GGraphs;
245  decltype (::GOPPRR::CObject::m_Explosions.begin()) Graph;
246  decltype (pProject->m_ObjectSet.begin()) GObject;
247  decltype (pRootGraph->m_ObjectSet.begin()) Object;
248  decltype (pRootGraph->m_ObjectSet) Objects;
249  decltype (pRootGraph->m_PortSet.begin()) Port;
250  decltype (::GOPPRR::CProperty::m_NonProperties) Values;
251  decltype (::GOPPRR::CProperty::m_NonProperties.begin()) Value;
252  decltype (::GOPPRR::CObject::m_Explosions.begin()) Explosion;
253  ::std::string CurrentType;
254  ::std::string DMIDataType;
255  ::std::string ValueType;
256  ::std::string AllowedValue;
257  ::std::string InitialApplicationLevel;
258  ::GOPPRR::CObject* pInitialState(0);
259  const ::std::string TELEGRAM_GRAPH(__GENERATOR__TELEGRAMGRAPH__);
260  const ::std::string EVCSTATE_OBJECT(__GENERATOR__EVCSTATE__);
261  const ::std::string MAINFB_GRAPH(__GENERATOR__MAINFB__);
262  const ::std::string SUBFB_GRAPH(__GENERATOR__SUBFB__);
263  const ::std::string APPLICATION_LEVEL_OBJECT("ApplicationLevelType");
264  const ::std::string DMI_INPUT_OBJECT("DMIInput");
265  const ::std::string DMI_OUTPUT_OBJECT("DMIOutput");
266  const ::std::string BALISE_IN_DEVICE("BaliseReader");
267  const ::std::string BALISE_OUT_DEVICE("BaliseSender");
268  const ::std::string COM_IN_OBJECT("CommunicationReader");
269  const ::std::string COM_OUT_OBJECT("CommunicationSender");
270  const ::std::string COM_READER_GRAPH("CommunicationReader");
271  const ::std::string COM_SENDER_GRAPH("CommunicationSender");
272  bool bSimulation(false);
273 
274 
275 
276 
277  // get simulation property value of root graph
278  bSimulation = pRootGraph->Properties("Simulation").begin()->second->m_Value == "T" ? true : false;
279 
280 
281 
282  // first of all generate header of source by helper method
284 
285 
286  // generate state machine as first instance of all
287  OutStream << "// EVC state machine object\n";
288  OutStream << ::std::left << std::setw(38) <<"::oETCS::DF::CEVCStateMachine" << "EVC;\n\n\n\n";
289 
290 
291 
292  // search for all EVC state objects in root graph
293  for (Object = pRootGraph->m_ObjectSet.begin(); Object != pRootGraph->m_ObjectSet.end(); Object++)
294  {
295  // check, if current object is a EVC state
296  if (Object->second->m_Type == EVCSTATE_OBJECT)
297  {
298  // generate code for creating current state object
299  OutStream << "// EVC state [" << Object->second->m_ID << "] with OID " << Object->second->m_OID << "\n";
300  OutStream << ::std::left << std::setw(38) << "::oETCS::DF::CEVCState" << "EVCState_" << Object->second->m_OID << "(&EVC);\n";
301 
302  } // if (Object->second->m_Type == EVCSTATE_OBJECT)
303 
304  } // for (Object = pRootGraph->m_ObjectSet.begin(); Object != pRootGraph->m_ObjectSet.end(); Object++)
305 
306 
307  // insert newlines
308  OutStream << "\n\n\n\n";
309 
310 
311  // call internal helper to generate language instances and interconnections
312  this->GenerateLanguage(pProject, OutStream);
313 
314 
315  // insert newlines
316  OutStream << "\n\n\n\n";
317 
318 
319  // call internal helper for FB elements
320  this->GenerateFunctionBlockElements(pProject, OutStream);
321 
322 
323  // insert newlines
324  OutStream << "\n\n\n\n";
325 
326 
327  // generate all sub function blocks from project
328  for (GGraph = pProject->m_GraphSet.begin(); GGraph != pProject->m_GraphSet.end(); GGraph++)
329  {
330  // check, if current graph is of type sub function block
331  if (GGraph->second.m_Type == SUBFB_GRAPH)
332  {
333  // generate comment for current graph
334  OutStream << "// Sub Function Block Graph [" << GGraph->second.m_ID << "] with OID " << GGraph->second.m_OID << "\n";
335 
336  // generate current graph by internal helper method
337  this->GenerateFunctionBlock(&(GGraph->second), pProject, OutStream);
338 
339  // append some newlines
340  OutStream << "\n\n\n\n";
341 
342  } // if (GGraph->second.m_Type == SUBFB_GRAPH)
343 
344  } // for (GGraph = pProject->m_GraphSet.begin(); GGraph != pProject->m_GraphSet.end(); GGraph++)
345 
346 
347  // generate all communication graphs from project
348  for (GGraph = pProject->m_GraphSet.begin(); GGraph != pProject->m_GraphSet.end(); GGraph++)
349  {
350  // check, if current graph is of type sub function block
351  if (GGraph->second.m_Type == COM_READER_GRAPH || GGraph->second.m_Type == COM_SENDER_GRAPH)
352  {
353  // generate comment for current graph
354  OutStream << "// Communication Graph [" << GGraph->second.m_ID << "] with OID " << GGraph->second.m_OID << "\n";
355 
356  // generate current graph by internal helper method
357  this->GenerateCommunication(&(GGraph->second), pProject, OutStream);
358 
359  // append some newlines
360  OutStream << "\n\n\n\n";
361 
362  } // if (GGraph->second.m_Type == COM_READER_GRAPH || GGraph->second.m_Type == COM_SENDER_GRAPH)
363 
364  } // for (GGraph = pProject->m_GraphSet.begin(); GGraph != pProject->m_GraphSet.end(); GGraph++)
365 
366 
367 
368  // process all objects in root graph
369  for (Object = pRootGraph->m_ObjectSet.begin(); Object != pRootGraph->m_ObjectSet.end(); Object++)
370  {
371  // check, if current object is a EVC state
372  if (Object->second->m_Type == EVCSTATE_OBJECT)
373  {
374  // process all explosions of current object
375  for (Graph = Object->second->m_Explosions.begin(); Graph != Object->second->m_Explosions.end(); Graph++)
376  {
377  // generate comment for current graph
378  OutStream << "// Main Function Block Graph [" << Graph->second->m_ID << "] with OID " << Graph->second->m_OID << "\n";
379 
380  // generate current graph by internal helper method
381  this->GenerateFunctionBlock(Graph->second, pProject, OutStream);
382 
383  // append some newlines
384  OutStream << "\n\n\n\n";
385 
386  // call internal helper method for generating code for DMI widget
387  this->GenerateDMI(Graph->second, pRootGraph, Object->second, OutStream);
388 
389  // append some newlines
390  OutStream << "\n\n\n\n";
391 
392  // generate data flow objects for current state by helper method
393  this->GenerateDataFlow(Graph->second, pRootGraph, Object->second, OutStream);
394 
395  // append some newlines
396  OutStream << "\n\n\n\n";
397 
398  // process all explosions of current EVC state object
399  for (Explosion = Object->second->m_Explosions.begin(); Explosion != Object->second->m_Explosions.end(); Explosion++)
400  {
401  // call internal helper method for generating code for EVC transition
402  this->GenerateEVCTransitions(Explosion->second, Object->second, pRootGraph, OutStream);
403 
404  } // for (Explosion = Object->second->m_Explosions.begin(); Explosion != Object->second->m_Explosions.end(); Explosion++)
405 
406  // append some newlines
407  OutStream << "\n\n\n\n";
408 
409  } // for (Graph = Object->second->m_Explosions.begin(); Graph != Object->second->m_Explosions.end(); Graph++)
410 
411 
412  // check if current state object is initial
413  if (Object->second->Properties("IsInitial").begin()->second->m_Value == "T")
414  {
415  // store current state as initial
416  pInitialState = Object->second;
417 
418  // store initial application level
419  InitialApplicationLevel = pInitialState->Properties("InitialLevel").begin()->second->m_Value;
420 
421  } // if (Object->second->Properties("IsInitial").begin()->second->m_Value == "T")
422 
423  } // if (Object->second->m_Type == EVCSTATE_OBJECT)
424 
425  } // for (Object = pRootGraph->m_ObjectSet.begin(); Object != pRootGraph->m_ObjectSet.end(); Object++)
426 
427 
428 
429  // call internal helper to create control flows
430  this->GenerateControlFlows(pProject, OutStream);
431 
432 
433 
434  // call internal helper to create transitions
435  this->GenerateTransitions(pRootGraph, OutStream);
436 
437 
438  // insert newlines
439  OutStream << "\n\n\n\n";
440 
441 
442  // check, if a initial state was found
443  if (pInitialState != 0)
444  {
445  // TODO: add generation of try- and catch-block
446 
447  // generate code for initial get D-Bus as workarround
448  OutStream << "// get D-Bus session bus once in main thread before all others\n";
449  OutStream << "QDBusConnection::sessionBus();\n\n";
450 
451  // finally generate of code for starting the execution of the EVC state machine
452  OutStream << "// start EVC state machine non-blocking and wait for any key to finish\n";
453  OutStream << "EVC.Start(&EVCState_" << pInitialState->m_OID
454  << ", ::std::string(\"" << InitialApplicationLevel << "\")"
455  << ");\n\n";
456 
457  // generation of Qt observer implementation
458  OutStream << "// create Qt observer implementation and register it with the EVC\n";
459  OutStream << "::oETCS::DF::CDMIQWidget DMI(&EVC";
460 
461  // check, if simulation flag is true
462  if (bSimulation)
463  {
464  // generate additional arguments for simulation usage
465  OutStream << ", 0, " << (bSimulation ? "true" : "false");
466 
467  } // if (bSimulation)
468 
469  // finish generation of Qt observer instantiation
470  OutStream << ");\n";
471  OutStream << "DMI.setWindowTitle(\"EVC Driver Machine Interface\");\n\n";
472  OutStream << "DMI.resize(600, 400);\n\n";
473  OutStream << "DMI.show();\n\n";
474 
475  // generate code for starting the Qt application for widgets
476  OutStream << "Application.exec();\n\n";
477 
478  // generate code for terminating the EVC machine
479  OutStream << "EVC.Stop();\n\n";
480 
481  } // if (pInitialState != 0)
482  // Bouml preserved body end 00097502
483 
484 } // void CCPPGenerator::GenerateRootGraph() throw(::GOPPRR::Error::CException)
485 
486 
487 
488 
489 void CCPPGenerator::GenerateFunctionBlockElements(GOPPRR::CProject * const pProject, ::std::ostream & OutStream) throw(::GOPPRR::Error::CException)
490 {
491  // Bouml preserved body begin 000B7E02
492  decltype (::GOPPRR::CProject::m_GraphSet.begin()) GGraph;
493  decltype (::GOPPRR::CProject::m_GraphSet) GGraphs;
494  decltype (::GOPPRR::CObject::m_Explosions.begin()) Graph;
495  decltype (pProject->m_ObjectSet.begin()) GObject;
496  decltype (::GOPPRR::CGraph::m_ObjectSet.begin()) Object;
497  decltype (::GOPPRR::CGraph::m_ObjectSet) Objects;
498  decltype (::GOPPRR::CGraph::m_PortSet.begin()) Port;
499  decltype (::GOPPRR::CProperty::m_NonProperties) Values;
500  decltype (::GOPPRR::CProperty::m_NonProperties.begin()) Value;
501  decltype (::GOPPRR::CObject::m_Explosions.begin()) Explosion;
502  decltype (::GOPPRR::CProperty::m_NonProperties) InitialValues;
503  ::GOPPRR::CObject* pInitialValue(nullptr);
504  ::std::string CurrentType;
505  ::std::string DMIDataType;
506  ::std::string InitialType;
507  ::std::string InitialValue;
508  ::std::string ValueType;
509  ::std::string AllowedValue;
510  const ::std::string TELEGRAM_GRAPH(__GENERATOR__TELEGRAMGRAPH__);
511  const ::std::string EVCSTATE_OBJECT(__GENERATOR__EVCSTATE__);
512  const ::std::string MAINFB_GRAPH(__GENERATOR__MAINFB__);
513  const ::std::string SUBFB_GRAPH(__GENERATOR__SUBFB__);
514  const ::std::string APPLICATION_LEVEL_OBJECT("ApplicationLevelType");
515  const ::std::string DMI_INPUT_OBJECT("DMIInput");
516  const ::std::string DMI_OUTPUT_OBJECT("DMIOutput");
517  const ::std::string BALISE_IN_DEVICE("BaliseReader");
518  const ::std::string BALISE_OUT_DEVICE("BaliseSender");
519  const ::std::string COM_IN_OBJECT("CommunicationReader");
520  const ::std::string COM_OUT_OBJECT("CommunicationSender");
521  const ::std::string STORAGE_OBJECT("VariableStorage");
522  const ::std::string SERVICE_BRAKE_OBJECT("ServiceBrake");
523  const ::std::string EMERGENCY_BRAKE_OBJECT("EmergencyBrake");
524  const ::std::string ODOMETER_BRAKE_OBJECT("Odometer");
525 
526 
527 
528 
529 
530  // generate all function block elements
531  for (GObject = pProject->m_ObjectSet.begin(); GObject != pProject->m_ObjectSet.end(); GObject++)
532  {
533  // check, if current object is a function block
534  if (m_FBMap.find(GObject->second.m_Type) != m_FBMap.end())
535  {
536  // generate current function block element
537  OutStream << "// Function Block type " << GObject->second.m_Type << " [" << GObject->second.m_ID << "] with OID " << GObject->second.m_OID << "\n";
538  OutStream << "::oETCS::DF::" << ::std::left << ::std::setw(25) << m_FBMap[GObject->second.m_Type] << "FBO_" << GObject->second.m_OID << "(&EVC";
539 
540  // check, if current element is an special object
541  if (GObject->second.m_Type == APPLICATION_LEVEL_OBJECT)
542  {
543  // generate second argument ( application level) for constructor
544  OutStream << ", \"" << GObject->second.Properties("ApplicationLevelName").begin()->second->m_Value << "\"";
545 
546  // generate code for terminating constructor statement
547  OutStream << ");\n";
548 
549  } // if (GObject->second.m_Type == APPLICATION_LEVEL_OBJECT)
550  else if (GObject->second.m_Type == DMI_INPUT_OBJECT)
551  {
552  // get data type
553  DMIDataType = GObject->second.Properties("DataType").begin()->second->m_Value;
554 
555  // generate enum type from string
556  if (DMIDataType == "double")
557  {
558  // generate second parameter
559  OutStream << ", ::oETCS::DF::DOUBLE";
560 
561  } // if (DMIDataType == "double")
562  else if (DMIDataType == "doubleArray")
563  {
564  // generate second parameter
565  OutStream << ", ::oETCS::DF::DOUBLE_ARRAY";
566 
567  } // else if (DMIDataType == "doubleArray")
568  else if (DMIDataType == "bool")
569  {
570  // generate second parameter
571  OutStream << ", ::oETCS::DF::BOOL";
572 
573  } // else if (DMIDataType == "bool")
574  else if (DMIDataType == "int")
575  {
576  // generate second parameter
577  OutStream << ", ::oETCS::DF::INT";
578 
579  } // else if (DMIDataType == "int")
580  else if (DMIDataType == "string")
581  {
582  // generate second parameter
583  OutStream << ", ::oETCS::DF::STRING";
584 
585  } // else if (DMIDataType == "string")
586 
587  // generate label string from ID
588  OutStream << ", \"" << GObject->second.m_ID << "\"";
589 
590  // check, if property for initial visible flag exists
591  if (not GObject->second.Properties("InitialVisible").empty())
592  {
593  // compare value of property
594  if (GObject->second.Properties("InitialVisible").begin()->second->m_Value == "T")
595  {
596  // generate code for visible flag
597  OutStream << ", true";
598 
599  } // if (GObject->second.Properties("InitialVisible").begin()->second->m_Value == "T")
600  else
601  {
602  // generate code for visible flag
603  OutStream << ", false";
604 
605  } // else
606 
607  } // if (not GObject->second.Properties("InitialVisible").empty())
608 
609  // generate code for terminating constructor statement
610  OutStream << ");\n";
611 
612  // check, if property for allowed values does exist
613  if (not GObject->second.Properties("AllowedValues").empty())
614  {
615  // check, if any allowed values are set
616  if (not GObject->second.Properties("AllowedValues").begin()->second->NonProperties("Value").empty())
617  {
618  // get all values
619  Values = GObject->second.Properties("AllowedValues").begin()->second->NonProperties("Value");
620 
621  // process all values
622  for (Value = Values.begin(); Value != Values.end(); Value++)
623  {
624  // get current value type
625  ValueType = Value->second->Properties("ValueType").begin()->second->m_Value;
626 
627  // get current value
628  AllowedValue = Value->second->Properties("Value").begin()->second->m_Value;
629 
630  // check current value type
631  if (ValueType == "bool")
632  {
633  // generate code to add current allowed value
634  OutStream << "FBO_" << GObject->second.m_OID << ".m_AllowedBoolInputs.push_back(" << AllowedValue << ");\n";
635 
636  } // if (ValueType == "bool")
637  else if (ValueType == "double")
638  {
639  // generate code to add current allowed value
640  OutStream << "FBO_" << GObject->second.m_OID << ".m_AllowedDoubleInputs.push_back(" << AllowedValue << ");\n";
641 
642  } // else if (ValueType == "double")
643  else if (ValueType == "integer")
644  {
645  // generate code to add current allowed value
646  OutStream << "FBO_" << GObject->second.m_OID << ".m_AllowedIntInputs.push_back(" << AllowedValue << ");\n";
647 
648  } // else if (ValueType == "integer")
649  else if (ValueType == "string")
650  {
651  // generate code to add current allowed value
652  OutStream << "FBO_" << GObject->second.m_OID << ".m_AllowedStringInputs.push_back(\"" << AllowedValue << "\");\n";
653 
654  } // else if (ValueType == "string")
655 
656  } // for (Value = Values.begin(); Value != Values.end(); Value++)
657 
658  } // if (not GObject->second.Properties("AllowedValues").begin()->second->NonProperties("Value").empty())
659 
660  } // if (not GObject->second.Properties("AllowedValues").empty())
661 
662 
663  // check, if property for initial visible flag exists
664  if (not GObject->second.Properties("InitialVisible").empty())
665  {
666  // compare value of property
667  if (GObject->second.Properties("InitialVisible").begin()->second->m_Value == "T")
668  {
669  // generate code for visible flag
670  OutStream << "FBO_" << GObject->second.m_OID << ".m_bVisible = true;\n";
671 
672  } // if (GObject->second.Properties("InitialVisible").begin()->second->m_Value == "T")
673  else
674  {
675  // generate code for visible flag
676  OutStream << "FBO_" << GObject->second.m_OID << ".m_bVisible = false;\n";
677 
678  } // else
679 
680  } // if (not GObject->second.Properties("InitialVisible").empty())
681 
682  } // else if (GObject->second.m_Type == DMI_INPUT_OBJECT)
683  else if (GObject->second.m_Type == DMI_OUTPUT_OBJECT)
684  {
685  // get data type
686  DMIDataType = GObject->second.Properties("DataType").begin()->second->m_Value;
687 
688  // generate enum type from string
689  if (DMIDataType == "double")
690  {
691  // generate second parameter
692  OutStream << ", ::oETCS::DF::DOUBLE";
693 
694  } // if (DMIDataType == "double")
695  else if (DMIDataType == "doubleArray")
696  {
697  // generate second parameter
698  OutStream << ", ::oETCS::DF::DOUBLE_ARRAY";
699 
700  } // else if (DMIDataType == "doubleArray")
701  else if (DMIDataType == "bool")
702  {
703  // generate second parameter
704  OutStream << ", ::oETCS::DF::BOOL";
705 
706  } // else if (DMIDataType == "bool")
707  else if (DMIDataType == "int")
708  {
709  // generate second parameter
710  OutStream << ", ::oETCS::DF::INT";
711 
712  } // else if (DMIDataType == "int")
713  else if (DMIDataType == "string")
714  {
715  // generate second parameter
716  OutStream << ", ::oETCS::DF::STRING";
717 
718  } // else if (DMIDataType == "string")
719 
720  // generate label string from ID
721  OutStream << ", \"" << GObject->second.m_ID << "\"";
722 
723  // check, if property for initial visible flag exists
724  if (not GObject->second.Properties("InitialVisible").empty())
725  {
726  // compare value of property
727  if (GObject->second.Properties("InitialVisible").begin()->second->m_Value == "T")
728  {
729  // generate code for visible flag
730  OutStream << ", true";
731 
732  } // if (GObject->second.Properties("InitialVisible").begin()->second->m_Value == "T")
733  else
734  {
735  // generate code for visible flag
736  OutStream << ", false";
737 
738  } // else
739 
740  } // if (not GObject->second.Properties("InitialVisible").empty())
741 
742  // generate code for terminating constructor statement
743  OutStream << ");\n";
744 
745  } // else if (GObject->second.m_Type == DMI_OUTPUT_OBJECT)
746  else if (GObject->second.m_Type == COM_IN_OBJECT)
747  {
748  // check, if object has a decomposition
749  if (GObject->second.m_pDecomposition != 0)
750  {
751  // generate vector of in devices as second parameter
752  OutStream << ", INDEVICES_" << GObject->second.m_pDecomposition->m_OID;
753 
754  // add vector with valid IDs as parameter
755  OutStream << ", PACKIDVEC_" << GObject->second.m_pDecomposition->m_OID;
756 
757  } // if (GObject->second.m_pDecomposition != 0)
758 
759  // generate code for terminating constructor statement
760  OutStream << ");\n";
761 
762  } // else if (GObject->second.m_Type == COM_IN_OBJECT)
763  else if (GObject->second.m_Type == COM_OUT_OBJECT)
764  {
765  // check, if object has a decomposition
766  if (GObject->second.m_pDecomposition != 0)
767  {
768  // generate vector of in devices as second parameter
769  OutStream << ", OUTDEVICES_" << GObject->second.m_pDecomposition->m_OID;
770 
771  } // if (GObject->second.m_pDecomposition != 0)
772 
773  // generate code for terminating constructor statement
774  OutStream << ");\n";
775 
776  } // else if (GObject->second.m_Type == COM_OUT_OBJECT)
777  else if (GObject->second.m_Type == STORAGE_OBJECT)
778  {
779  // check, if storage has debug flag set
780  if (GObject->second.Properties("DebugOutput").begin()->second->m_Value == "T")
781  {
782  // append parameters for debug output
783  OutStream << ", true, \"" << GObject->second.Properties("Name").begin()->second->m_Value << "\"";
784 
785  } // if (GObject->second.Properties("DebugOutput").begin()->second->m_Value == "T")
786 
787 
788  // generate code for terminating constructor statement
789  OutStream << ");\n";
790 
791  // get value object as non-property from initial value property
792  InitialValues = GObject->second.Properties("InitialValue").begin()->second->m_NonProperties;
793 
794  // check, if initial value is set
795  if (not InitialValues.empty())
796  {
797  // store pointer to initial value as object
798  pInitialValue = static_cast< ::GOPPRR::CObject* >(InitialValues.begin()->second);
799 
800  // get initial value from object
801  InitialValue = pInitialValue->Properties("Value").begin()->second->m_Value;
802 
803  // get initial value type from object
804  InitialType = pInitialValue->Properties("ValueType").begin()->second->m_Value;
805 
806  // check for initial type
807  if (InitialType == "bool")
808  {
809  // set initial value as boolean
810  OutStream << "FBO_" << GObject->second.m_OID << ".m_bBoolInput = " << InitialValue << ";\n";
811 
812  } // if (InitialType == "bool")
813  if (InitialType == "double")
814  {
815  // set initial value as double
816  OutStream << "FBO_" << GObject->second.m_OID << ".m_dDoubleInput = " << InitialValue << ";\n";
817 
818  } // if (InitialType == "double")
819  if (InitialType == "integer")
820  {
821  // set initial value as integer
822  OutStream << "FBO_" << GObject->second.m_OID << ".m_iIntInput = " << InitialValue << ";\n";
823 
824  } // if (InitialType == "integer")
825  if (InitialType == "string")
826  {
827  // set initial value as string
828  OutStream << "FBO_" << GObject->second.m_OID << ".m_StringInput = \"" << InitialValue << "\";\n";
829 
830  } // if (InitialType == "string")
831 
832  } // if (not InitialValues.empty())
833 
834  } // else if (GObject->second.m_Type == STORAGE_OBJECT)
835  else if (GObject->second.m_Type == SERVICE_BRAKE_OBJECT || GObject->second.m_Type == EMERGENCY_BRAKE_OBJECT || GObject->second.m_Type == ODOMETER_BRAKE_OBJECT)
836  {
837  // generate second argument (platform specific usage) for constructor
838  OutStream << ", " << (GObject->second.Properties("IsExternal").begin()->second->m_Value == "F" ? "false" : "true");
839 
840  // generate code for terminating constructor statement
841  OutStream << ");\n";
842 
843  } // else if (GObject->second.m_Type == SERVICE_BRAKE_OBJECT || GObject->second.m_Type == EMERGENCY_BRAKE_OBJECT || GObject->second.m_Type == ODOMETER_BRAKE_OBJECT)
844  else
845  {
846  // generate code for terminating constructor statement
847  OutStream << ");\n";
848 
849  } // else
850 
851  // TODO: add generation platform specific usage for HW interface classes
852 
853  } // if (m_FBMap.find(GObject->second.m_Type) != m_FBMap.end())
854 
855  } // for (GObject = pProject->m_ObjectSet.begin(); GObject != pProject->m_ObjectSet.end(); GObject++)
856  // Bouml preserved body end 000B7E02
857 
858 } // void CCPPGenerator::GenerateFunctionBlockElements() throw(::GOPPRR::Error::CException)
859 
860 
861 
862 
863 void CCPPGenerator::GenerateFunctionBlock(GOPPRR::CGraph * const pFunctionBlock, GOPPRR::CProject * const pProject, ::std::ostream & OutStream) throw(::GOPPRR::Error::CException)
864 {
865  // Bouml preserved body begin 0009C782
866  decltype (::GOPPRR::CGraph::m_ObjectSet.begin()) Object;
867  decltype (::GOPPRR::CGraph::m_ObjectSet) InputObjects;
868  decltype (::GOPPRR::CGraph::m_PortSet) Ports;
869  decltype (::GOPPRR::CGraph::m_PortSet) InputPorts;
870  decltype (::GOPPRR::CGraph::m_PortSet.begin()) Port;
871  decltype (::GOPPRR::CGraph::m_RoleSet) OutputRoles;
872  decltype (::GOPPRR::CGraph::m_RoleSet) InputRoles;
873  decltype (::GOPPRR::CGraph::m_RoleSet.begin()) Role;
874  decltype (::GOPPRR::CGraph::m_RelationshipSet) Relationships;
875  decltype (::GOPPRR::CGraph::m_RelationshipSet.begin()) Relationship;
876  decltype (::GOPPRR::CGraph::m_ObjectSet) Variables;
877  decltype (::GOPPRR::CGraph::m_ObjectSet.begin()) Variable;
878  decltype (::GOPPRR::CGraph::m_RoleSet) OutRoles;
879  decltype (::GOPPRR::CGraph::m_RoleSet.begin()) OutRole;
880  ::std::string InputPortName;
881  ::std::string OutputPortName;
882  ::std::string FlowType;
883  const ::std::string VARIABLE_INSTANCE_OBJECT("VariableInstance");
884  const ::std::string VARIABLE_STORAGE_OBJECT("VariableStorage");
885  const ::std::string VARIABLE_TYPE_RESOLUTION("VariableResolution");
886  const ::std::string VARIABLE_TYPE_RESOLUTION_UNIT("Unit");
887  const ::std::string VARIABLE_TYPE_SIZE("Size");
888  const ::std::string VALUEMAP_OBJECT("ValueMap");
889  const ::std::string TELEGRAM_OBJECT("Telegram");
890  const ::std::string DATAFLOW_RELATIONSHIP("DataFlow");
891  const ::std::string DATAINPUT_ROLE("DataInput");
892  const ::std::string DATAOUTPUT_ROLE("DataOutput");
893 
894 
895 
896  // process all objects in main function block
897  for (Object = pFunctionBlock->m_ObjectSet.begin(); Object !=pFunctionBlock->m_ObjectSet.end(); Object++)
898  {
899  // check, if current object is a concrete function block element
900  if (m_FBMap.find(Object->second->m_Type) != m_FBMap.end())
901  {
902  // get all output ports of object
903  Ports = pFunctionBlock->Ports(Object->second, "Output", true, false);
904 
905  // check, if current port as output ports
906  if (Ports.size() > 0)
907  {
908  // append each object connected with a output port in corresponding output vector
909  for (Port = Ports.begin(); Port != Ports.end(); Port++)
910  {
911  // get output port name
912  OutputPortName = Port->second->m_ID;
913 
914  // get flow type for template
915  FlowType = TypeFromPort(Port->second);
916 
917  // strip all "Get" prefixes from output port name
918  while (OutputPortName.find("Get") != OutputPortName.npos)
919  {
920  // erase current occurrence of prefix
921  OutputPortName.erase(OutputPortName.find("Get"), 3);
922 
923  } // while (OutputPortName.find("Get") != OutputPortName.npos)
924 
925  // check if output port name is in map
926  if (m_FBMMap.find(Object->second->m_Type + ::std::string("::") + OutputPortName) != m_FBMMap.end())
927  {
928  // set output port name to mapped version
929  OutputPortName = m_FBMMap[Object->second->m_Type + ::std::string("::") + OutputPortName];
930 
931  } // if (m_FBMMap.find(Object->second->m_Type + ::std::string("::") + OutputPortName) != m_FBMMap.end())
932 
933  // get all roles connected with output port
934  OutputRoles = pFunctionBlock->Roles(Object->second, Port->second, "DataOutput", false, false);
935 
936  // process all output roles
937  for (Role = OutputRoles.begin(); Role != OutputRoles.end(); Role++)
938  {
939  // get all connected data flow relationships
940  Relationships = pFunctionBlock->Relationships(Role->second, "DataFlow");
941 
942  // store first (and only) relationship
943  Relationship = Relationships.begin();
944 
945  // get all connected output roles from first relationship
946  InputRoles = pFunctionBlock->Roles(Role->second, "DataInput");
947 
948  // get all connected input ports
949  InputPorts = pFunctionBlock->Ports(InputRoles.begin()->second, false);
950 
951  // check, if an input port was found
952  if (InputPorts.size() > 0)
953  {
954  // get input port name
955  InputPortName = InputPorts.begin()->second->m_ID;
956 
957  // strip all "Get" prefixes from output port name
958  while (InputPortName.find("Set") != InputPortName.npos)
959  {
960  // erase current occurrence of prefix
961  InputPortName.erase(InputPortName.find("Set"), 3);
962 
963  } // while (InputPortName("Set") != InputPortName)
964 
965  // get all connected objects from first object
966  InputObjects = pFunctionBlock->Objects(InputPorts.begin()->second, InputRoles.begin()->second, false);
967 
968  // check if input port name is in map
969  if (m_FBMMap.find(InputObjects.begin()->second->m_Type + ::std::string("::") + InputPortName) != m_FBMMap.end())
970  {
971  // set input port name to mapped version
972  InputPortName = m_FBMMap[InputObjects.begin()->second->m_Type + ::std::string("::") + InputPortName];
973 
974  } // if (m_FBMMap.find(InputObjects.begin()->second->m_Type + ::std::string("::") + InputPortName) != m_FBMMap.end())
975 
976  // generate appending of output via CFlow object
977  OutStream << "// appending object [" << InputObjects.begin()->second->m_ID << "] of type "
978  << InputObjects.begin()->second->m_Type << " to output of object [" << Object->second->m_ID << "] of type " << Object->second->m_Type
979  << " with flow object "<< Relationship->second->m_OID << "\n";
980 
981  OutStream << "::oETCS::DF::CFlow< " << FlowType << ::std::left << std::setw(38) << " >" << "FLOW_" << Relationship->second->m_OID << "(&(FBO_"
982  << InputObjects.begin()->second->m_OID << ".m_" << InputPortName << "), &EVC);\n";
983 
984  OutStream << "FBO_" << Object->second->m_OID << ".m_" << OutputPortName << ".push_back(&FLOW_"
985  << Relationship->second->m_OID << ");\n";
986 
987  } // if (InputPorts.size() > 0)
988  else
989  {
990  // get all connected objects from first object
991  InputObjects = pFunctionBlock->Objects(InputRoles.begin()->second);
992 
993  // get variable input port name
994  InputPortName = Port->second->m_Type + "Input";
995 
996  // strip "Output" from input port name
997  InputPortName.erase(InputPortName.find("Output"), 6);
998 
999  // convert current first letter to upper case
1000  InputPortName[0] = InputPortName[0] + 'A' - 'a';
1001 
1002  // add prefix for data type to port name
1003  InputPortName = CCPPGenerator::PrefixFromPort(Port->second) + InputPortName;
1004 
1005  // generate appending of output via CFlow object
1006  OutStream << "// appending object [" << InputObjects.begin()->second->m_ID << "] of type "
1007  << InputObjects.begin()->second->m_Type << " to output of object [" << Object->second->m_ID << "] of type " << Object->second->m_Type
1008  << " with flow object "<< Relationship->second->m_OID << "\n";
1009 
1010  OutStream << "::oETCS::DF::CFlow< " << FlowType << ::std::left << std::setw(38) << " >" << "FLOW_" << Relationship->second->m_OID << "(&(FBO_"
1011  << InputObjects.begin()->second->m_OID << ".m_" << InputPortName << "), &EVC);\n";
1012 
1013  OutStream << "FBO_" << Object->second->m_OID << ".m_" << OutputPortName << ".push_back(&FLOW_"
1014  << Relationship->second->m_OID << ");\n";
1015 
1016  } // else
1017 
1018  } // for (Role = Roles.begin(); Role != Roles.end(); Role++)
1019 
1020  } // for (Port = Ports.begin(); Port != Ports.end(); Port++)
1021 
1022  } // if (Ports.size() > 0)
1023  else
1024  {
1025  // get all roles connected with this relationship
1026  OutputRoles = pFunctionBlock->Roles(Object->second, "DataOutput", false, false);
1027 
1028  // process all output roles
1029  for (Role = OutputRoles.begin(); Role != OutputRoles.end(); Role++)
1030  {
1031  // get all connected data flow relationships
1032  Relationships = pFunctionBlock->Relationships(Role->second, "DataFlow");
1033 
1034  // store first (and only) relationship
1035  Relationship = Relationships.begin();
1036 
1037  // get all connected output roles from first relationship
1038  InputRoles = pFunctionBlock->Roles(Role->second, "DataInput", false, false);
1039 
1040  // get all connected input ports
1041  InputPorts = pFunctionBlock->Ports(InputRoles.begin()->second, false);
1042 
1043  // check, if an input port was found
1044  if (InputPorts.size() > 0)
1045  {
1046  // get input port name
1047  InputPortName = InputPorts.begin()->second->m_ID;
1048 
1049  // get flow type for template
1050  FlowType = TypeFromPort(InputPorts.begin()->second);
1051 
1052  // strip all "Get" prefixes from output port name
1053  while (InputPortName.find("Set") != InputPortName.npos)
1054  {
1055  // erase current occurrence of prefix
1056  InputPortName.erase(InputPortName.find("Set"), 3);
1057 
1058  } // while (InputPortName("Set") != InputPortName)
1059 
1060  // get all connected objects from first object
1061  InputObjects = pFunctionBlock->Objects(InputPorts.begin()->second, InputRoles.begin()->second, false);
1062 
1063  // check if input port name is in map
1064  if (m_FBMMap.find(InputObjects.begin()->second->m_Type + ::std::string("::") + InputPortName) != m_FBMMap.end())
1065  {
1066  // set input port name to mapped version
1067  InputPortName = m_FBMMap[InputObjects.begin()->second->m_Type + ::std::string("::") + InputPortName];
1068 
1069  } // if (m_FBMMap.find(InputObjects.begin()->second->m_Type + ::std::string("::") + InputPortName) != m_FBMMap.end())
1070 
1071  // get variable input port name
1072  OutputPortName = InputPorts.begin()->second->m_Type + "Value";
1073 
1074  // strip "Input" from output port name
1075  OutputPortName.erase(OutputPortName.find("Input"), 5);
1076 
1077  // convert current first letter to upper case
1078  OutputPortName[0] = OutputPortName[0] + 'A' - 'a';
1079 
1080  // generate appending of output via CFlow object
1081  OutStream << "// appending object [" << InputObjects.begin()->second->m_ID << "] of type "
1082  << InputObjects.begin()->second->m_Type << " to output of object [" << Object->second->m_ID << "] of type " << Object->second->m_Type
1083  << " with flow object "<< Relationship->second->m_OID << "\n";
1084 
1085  OutStream << "::oETCS::DF::CFlow< " << FlowType << ::std::left << std::setw(38) << " >" << "FLOW_" << Relationship->second->m_OID << "(&(FBO_"
1086  << InputObjects.begin()->second->m_OID << ".m_" << InputPortName << "), &EVC);\n";
1087 
1088 
1089  OutStream << "FBO_" << Object->second->m_OID << ".m_" << OutputPortName << ".push_back(&FLOW_"
1090  << Relationship->second->m_OID << ");\n";
1091 
1092  } // if (InputPorts.size() > 0)
1093  else
1094  {
1095  // get all connected objects from first object
1096  InputObjects = pFunctionBlock->Objects(InputRoles.begin()->second, false);
1097 
1098  // generate appending of output via CFlow object
1099  OutStream << "// appending object [" << InputObjects.begin()->second->m_ID << "] of type "
1100  << InputObjects.begin()->second->m_Type << " to output of object [" << Object->second->m_ID << "] of type " << Object->second->m_Type
1101  << " with flow object "<< Relationship->second->m_OID << "\n";
1102 
1103  OutStream << ::std::left << std::setw(38) << "::oETCS::DF::CBitFlow" << "FLOW_" << Relationship->second->m_OID << "(&(FBO_"
1104  << InputObjects.begin()->second->m_OID << "), &EVC);\n";
1105 
1106  OutStream << "FBO_" << Object->second->m_OID << ".m_BitValue.push_back(&FLOW_"
1107  << Relationship->second->m_OID << ");\n";
1108 
1109  } // else
1110 
1111  } // for (Role = Roles.begin(); Role != Roles.end(); Role++)
1112 
1113  } // else
1114 
1115  } // if (m_FBMap.find(Object->second->m_Type) != m_FBMap.end())
1116 
1117  } // for (Objects = pFunctionBlock->m_ObjectSet.begin(); Objects !=pFunctionBlock->m_ObjectSet.end(); Objects++)
1118  // Bouml preserved body end 0009C782
1119 
1120 } // void CCPPGenerator::GenerateFunctionBlock() throw(::GOPPRR::Error::CException)
1121 
1122 
1123 
1124 
1125 void CCPPGenerator::GenerateCommunication(GOPPRR::CGraph * const pCommunication, GOPPRR::CProject * const pProject, ::std::ostream & OutStream) throw(::GOPPRR::Error::CException)
1126 {
1127  // Bouml preserved body begin 000E2902
1128  decltype (::GOPPRR::CGraph::m_ObjectSet) InputObjects;
1129  decltype (::GOPPRR::CGraph::m_PortSet) Ports;
1130  decltype (::GOPPRR::CGraph::m_PortSet) InputPorts;
1131  decltype (::GOPPRR::CGraph::m_PortSet.begin()) Port;
1132  decltype (::GOPPRR::CGraph::m_RoleSet) OutputRoles;
1133  decltype (::GOPPRR::CGraph::m_RoleSet) InputRoles;
1134  decltype (::GOPPRR::CGraph::m_RoleSet.begin()) InputRole;
1135  decltype (::GOPPRR::CGraph::m_RoleSet.begin()) Role;
1136  decltype (::GOPPRR::CGraph::m_RelationshipSet) Relationships;
1137  decltype (::GOPPRR::CGraph::m_RelationshipSet.begin()) Relationship;
1138  decltype (::GOPPRR::CGraph::m_ObjectSet) Variables;
1139  decltype (::GOPPRR::CGraph::m_ObjectSet.begin()) Variable;
1140  decltype (::GOPPRR::CGraph::m_RoleSet) OutRoles;
1141  decltype (::GOPPRR::CGraph::m_RoleSet.begin()) OutRole;
1142  ::std::string InputPortName;
1143  ::std::string OutputPortName;
1144  ::std::string FlowType;
1145  ::GOPPRR::CObject* pVariableStorage(0);
1146  ::GOPPRR::CRelationship* pDataFlow(0);
1147  ::GOPPRR::CRole* pDataInput(0);
1148  ::GOPPRR::CRole* pDataOutput(0);
1149  const ::std::string VARIABLE_INSTANCE_OBJECT("VariableInstance");
1150  const ::std::string VARIABLE_STORAGE_OBJECT("VariableStorage");
1151  const ::std::string VARIABLE_TYPE_RESOLUTION("VariableResolution");
1152  const ::std::string VARIABLE_TYPE_RESOLUTION_UNIT("Unit");
1153  const ::std::string VARIABLE_TYPE_SIZE("Size");
1154  const ::std::string VALUEMAP_OBJECT("ValueMap");
1155  const ::std::string TELEGRAM_OBJECT("Telegram");
1156  const ::std::string DATAFLOW_RELATIONSHIP("DataFlow");
1157  const ::std::string DATAINPUT_ROLE("DataInput");
1158  const ::std::string DATAOUTPUT_ROLE("DataOutput");
1159 
1160 
1161 
1162 
1163  // check, if current graph is communication reader
1164  if (pCommunication->m_Type == "CommunicationReader")
1165  {
1166  // get all variable instances in current graph
1167  Variables = pCommunication->Objects(VARIABLE_INSTANCE_OBJECT, false, false);
1168 
1169  // process all variable instance objects to find bit data flows
1170  for (Variable = Variables.begin(); Variable != Variables.end(); Variable++)
1171  {
1172  // get all "DataOutput" roles of current variable object
1173  OutRoles = pCommunication->Roles(Variable->second, DATAOUTPUT_ROLE, false, false);
1174 
1175  // process all out roles
1176  for (OutRole = OutRoles.begin(); OutRole != OutRoles.end(); OutRole++)
1177  {
1178  // get connected "DataFlow" relationship
1179  pDataFlow = pCommunication->Relationships(OutRole->second, DATAFLOW_RELATIONSHIP, false, true).begin()->second;
1180 
1181  // get connected data input role
1182  pDataInput = pCommunication->Roles(pDataFlow, DATAINPUT_ROLE, false, true).begin()->second;
1183 
1184  // get connected variable storage object
1185  pVariableStorage = pCommunication->Objects(pDataInput, true).begin()->second;
1186 
1187  // generate appending of output via CFlow object
1188  OutStream << "// appending variable storage object [" << pVariableStorage->m_ID << "] to output of variable instance ["
1189  << Variable->second->m_ID << "] with flow object "<< pDataFlow->m_OID << "\n";
1190 
1191  OutStream << ::std::left << std::setw(38) << "::oETCS::DF::CBitFlow" << "FLOW_" << pDataFlow->m_OID << "(&(FBO_"
1192  << pVariableStorage->m_OID << "), &EVC);\n";
1193 
1194  OutStream << "VAR_" << Variable->second->m_OID << ".m_BitValues.push_back(&FLOW_"
1195  << pDataFlow->m_OID << ");\n";
1196 
1197  } // for (OutRole = OutRoles.begin(); OutRole != OutRoles.end(); OutRole++)
1198 
1199  } // for for (Variable = Variables.begin(); Variable != Variables.end(); Variable++)
1200 
1201  // TODO: add generation
1202 
1203  } // if (pCommunication->m_Type == "CommunicationReader")
1204  else if (pCommunication->m_Type == "CommunicationSender")
1205  {
1206  // get all variable instances in current graph
1207  Variables = pCommunication->Objects(VARIABLE_INSTANCE_OBJECT, false, false);
1208 
1209  // process all variable instance objects to find bit data flows
1210  for (Variable = Variables.begin(); Variable != Variables.end(); Variable++)
1211  {
1212  // get all "DataInput" roles of current variable object
1213  InputRoles = pCommunication->Roles(Variable->second, DATAINPUT_ROLE, false, false);
1214 
1215  // process all out roles
1216  for (InputRole = InputRoles.begin(); InputRole != InputRoles.end(); InputRole++)
1217  {
1218  // get connected "DataFlow" relationship
1219  pDataFlow = pCommunication->Relationships(OutRole->second, DATAFLOW_RELATIONSHIP, false, true).begin()->second;
1220 
1221  // get connected data output role
1222  pDataOutput = pCommunication->Roles(pDataFlow, DATAOUTPUT_ROLE, false, true).begin()->second;
1223 
1224  // get connected variable storage object
1225  pVariableStorage = pCommunication->Objects(pDataOutput, true).begin()->second;
1226 
1227  // generate appending of output via CFlow object
1228  OutStream << "// appending variable storage object [" << pVariableStorage->m_ID << "] to input of variable instance ["
1229  << Variable->second->m_ID << "] with flow object "<< pDataFlow->m_OID << "\n";
1230 
1231  OutStream << ::std::left << std::setw(38) << "::oETCS::DF::CBitFlow" << "FLOW_" << pDataFlow->m_OID << "(&(FBO_"
1232  << pVariableStorage->m_OID << "), &EVC);\n";
1233 
1234  OutStream << "VAR_" << Variable->second->m_OID << ".m_BitValues.push_back(&FLOW_"
1235  << pDataFlow->m_OID << ");\n";
1236 
1237  } // for (OutRole = OutRoles.begin(); OutRole != OutRoles.end(); OutRole++)
1238 
1239  } // for for (Variable = Variables.begin(); Variable != Variables.end(); Variable++)
1240 
1241  } // else if (pCommunication->m_Type == "CommunicationSender")
1242  // Bouml preserved body end 000E2902
1243 
1244 } // void CCPPGenerator::GenerateCommunication() throw(::GOPPRR::Error::CException)
1245 
1246 
1247 
1248 
1249 void CCPPGenerator::GenerateDataFlow(GOPPRR::CGraph * const pMainFunctionBlock, GOPPRR::CGraph * const pEVCGraph, GOPPRR::CObject * const pEVCState, ::std::ostream & OutStream) throw(::GOPPRR::Error::CException)
1250 {
1251  // Bouml preserved body begin 000B0B82
1252  decltype (::GOPPRR::CGraph::m_ObjectSet.begin()) Object;
1253  decltype (::GOPPRR::CGraph::m_ObjectSet) SubFunctionBlocks;
1254  decltype (::GOPPRR::CGraph::m_ObjectSet.begin()) SubFunctionBlock;
1255  decltype (::GOPPRR::CGraph::m_RoleSet) CurrentStates;
1256  decltype (::GOPPRR::CGraph::m_RoleSet.begin()) CurrentState;
1257  decltype (::GOPPRR::CGraph::m_RelationshipSet.begin()) Relationship;
1258  ::std::string ApplicationLevel;
1259  ::GOPPRR::CObject* pFaultState(nullptr);
1260  ::GOPPRR::CObject* pFailureGuard(nullptr);
1261  ::GOPPRR::CObject* pCurrentModeGuard(nullptr);
1262  ::GOPPRR::CRelationship* pModeTransition(nullptr);
1263  ::GOPPRR::CRole* pNextState(nullptr);
1264  ::std::string OID;
1265  ::std::map< ::std::string, ::oETCS::GEN::CFBNode > FBNodes;
1266  decltype (FBNodes.begin()) n;
1267  decltype (::oETCS::GEN::CFBNode::m_Inputs.begin()) i;
1268  ::std::list< ::std::string > ExecutionOrder;
1269  decltype (ExecutionOrder.begin()) s;
1270  ::std::vector< const oETCS::GEN::CFBNode* > NodeStack(0);
1271  bool bFaultStateFound(false);
1272 
1273 
1274 
1275 
1276 
1277 
1278  // check, if fault state guard does exists in main function block
1279  if (not pMainFunctionBlock->Properties("FailureGuard").begin()->second->m_NonProperties.empty())
1280  {
1281  // get failure object
1282  pFailureGuard = static_cast< ::GOPPRR::CObject* >(pMainFunctionBlock->Properties("FailureGuard").begin()->second->m_NonProperties.begin()->second);
1283 
1284  // get all current roles of state in EVC graph
1285  CurrentStates = pEVCGraph->Roles(pEVCState, "CurrentState");
1286 
1287  // process all states
1288  for (CurrentState = CurrentStates.begin(); CurrentState != CurrentStates.end() && not bFaultStateFound; CurrentState++)
1289  {
1290  // get relationship from role
1291  pModeTransition = pEVCGraph->Relationships(CurrentState->second).begin()->second;
1292 
1293  // get mode guard object of current relationship
1294  pCurrentModeGuard = static_cast< ::GOPPRR::CObject* >(pModeTransition->Properties("ModeGuard").begin()->second->m_NonProperties.begin()->second);
1295 
1296  // check, if this relationship holds the failure guard as property
1297  if (pCurrentModeGuard == pFailureGuard)
1298  {
1299  // get next state role from relationship
1300  pNextState = pEVCGraph->Roles(pModeTransition, ::std::string("NextState")).begin()->second;
1301 
1302  // store target EVC state of current relation as fault state
1303  pFaultState = pEVCGraph->Objects(pNextState, "Mode").begin()->second;
1304 
1305  // set found flag to true
1306  bFaultStateFound = true;
1307 
1308  } // if (pCurrentModeGuard == pFailureGuard)
1309 
1310  } // for (CurrentState = CurrentStates.begin(); CurrentState != CurrentStates.end() && not bFaultStateFound; CurrentState++)
1311 
1312  } // if (not pMainFunctionBlock->Properties("FailureGuard").begin()->second->m_NonProperties.empty())
1313 
1314 
1315  // get application level value
1316  ApplicationLevel = pMainFunctionBlock->Properties("ActiveApplicationLevel").begin()->second->m_Value;
1317 
1318 
1319  // generate initial comment for this data flow object
1320  OutStream << "// Data flow object " << pMainFunctionBlock->m_Type << " [" << pMainFunctionBlock->m_ID << "] with OID " << pMainFunctionBlock->m_OID << "\n";
1321 
1322  // generate code for vector of function block object pointers instantiation
1323  OutStream << "::std::vector< ::oETCS::DF::CFunctionBlock* > FBVEC_" << pMainFunctionBlock->m_OID << ";\n";
1324 
1325  // generate code for vector of CAbstracFlow pointers for current data flow
1326  OutStream << "::std::vector< ::oETCS::DF::CAbstractFlow* > FLOWVEC_" << pMainFunctionBlock->m_OID << ";\n";
1327 
1328 
1329 
1330  // call helper method for adding all objects recursively from all graphs (including sub graphs)
1331  ::oETCS::GEN::CCPPGenerator::BuildAbstractModel(pMainFunctionBlock, FBNodes);
1332 
1333  // process all nodes found (including sub-graphs)
1334  for (n = FBNodes.begin(); n != FBNodes.end(); n++)
1335  {
1336  // process all inputs of current node
1337  for (i = n->second.m_Inputs.begin(); i != n->second.m_Inputs.end(); i++)
1338  {
1339  // store OID of current output node
1340  OID = (*i)->m_OID;
1341 
1342  // delete current undefined object
1343  delete (*i);
1344 
1345  // use pointer to actual node at iterators place
1346  *i = &FBNodes[OID];
1347 
1348  } // for (i = n->second.m_Inputs.begin(); i != n->second.m_Inputs.end(); i++)
1349 
1350  } // for (n = FBNodes.begin(); n != FBNodes.end(); n++)
1351 
1352 
1353  // process all nodes found again to determine execution order
1354  for (n = FBNodes.begin(); n != FBNodes.end(); n++)
1355  {
1356  // call method for processing abstract model
1357  ::oETCS::GEN::CCPPGenerator::ProcessAbstractModel(n->second, ExecutionOrder, NodeStack);
1358 
1359  } // for (n = FBNodes.begin(); n != FBNodes.end(); n++)
1360 
1361 
1362  // generate code for adding function block objects to vector in right order for data flow
1363  for (s = ExecutionOrder.begin(); s != ExecutionOrder.end(); s++)
1364  {
1365  // generate code for adding current function block element to vector with pointers
1366  OutStream << "FBVEC_" << pMainFunctionBlock->m_OID << ".push_back(&FBO_" << *s << ");\n";
1367 
1368  } // for (s = ExecutionOrder.begin(); s != ExecutionOrder.end(); s++)
1369 
1370 
1371 
1372 
1373  // process all "DataFlow" relationships in current graph to add CFlow objects to vector
1374  for (Relationship = pMainFunctionBlock->m_RelationshipSet.begin(); Relationship != pMainFunctionBlock->m_RelationshipSet.end(); Relationship++)
1375  {
1376  // check, if current relationship is "DataFlow" (ignore all others)
1377  if (Relationship->second->m_Type == "DataFlow")
1378  {
1379  // generate code for adding pointer to related CFlow object to vector of data flow object
1380  OutStream << "FLOWVEC_" << pMainFunctionBlock->m_OID << ".push_back(&FLOW_" << Relationship->second->m_OID << ");\n";
1381 
1382  } // if (Relationship->second->m_Type == "DataFlow")
1383 
1384  } // for (Relationship = pMainFunctionBlock->m_RelationshipSet.begin(); Relationship != pMainFunctionBlock->m_RelationshipSet.end(); Relationship++)
1385 
1386 
1387  // process all CommunicationReader and -Sender objects and add CBitFlow objects between CVariable and CStorage objects
1388  for (Object = pMainFunctionBlock->m_ObjectSet.begin(); Object != pMainFunctionBlock->m_ObjectSet.end(); Object++)
1389  {
1390  // check, if current object is a communication device
1391  if (Object->second->m_Type == "CommunicationReader" || Object->second->m_Type == "CommunicationSender")
1392  {
1393  // check, if decomposition does exist
1394  if (Object->second->m_pDecomposition != nullptr)
1395  {
1396  // call method for adding the bit flows in communication graph
1397  this->GenerateDataFlowForCommunication(pMainFunctionBlock->m_OID, Object->second->m_pDecomposition, OutStream);
1398 
1399  } // if (Object->second->m_pDecomposition != nullptr)
1400 
1401  } // if (Object->second->m_Type == "CommunicationReader" || Object->second->m_Type == "CommunicationSender")
1402 
1403  } // for (Object = pMainFunctionBlock->m_ObjectSet.begin(); Object != pMainFunctionBlock->m_ObjectSet.end(); Object++)
1404 
1405 
1406  // store full OID of this main function block graph
1407  OID = pMainFunctionBlock->m_OID;
1408 
1409  // get all sub function block objects in main function block
1410  SubFunctionBlocks = pMainFunctionBlock->Objects("SubFunction");
1411 
1412  // process all sub function block objects
1413  for (SubFunctionBlock = SubFunctionBlocks.begin(); SubFunctionBlock != SubFunctionBlocks.end(); SubFunctionBlock++)
1414  {
1415  // check, if current object has a decomposition
1416  if (SubFunctionBlock->second->m_pDecomposition != 0)
1417  {
1418  // call internal helper to generate code to add objects to current data flow
1419  GenerateDataFlow(OID, SubFunctionBlock->second->m_pDecomposition, OutStream);
1420 
1421  } // if (SubFunctionBlock->second->m_pDecomposition != 0)
1422 
1423  } // for (SubFunctionBlock = SubFunctionBlocks.begin(); SubFunctionBlock != SubFunctionBlocks.end(); SubFunctionBlock++)
1424 
1425 
1426  // generate code for CDataDFlow instantiation
1427  OutStream << ::std::left << std::setw(38) << "::oETCS::DF::CDataFlow" << "DATAFLOW_" << pMainFunctionBlock->m_OID << "(&EVCState_" << pEVCState->m_OID
1428  << ", ::std::string(\"" << ApplicationLevel << "\")"
1429  << ", FBVEC_" << pMainFunctionBlock->m_OID
1430  << ", FLOWVEC_" << pMainFunctionBlock->m_OID
1431  << ", &DMI_" << pMainFunctionBlock->m_OID;
1432 
1433  // check, if a fault state is available
1434  if (pFaultState != 0)
1435  {
1436  // generate code for pointer to fault state as parameter
1437  OutStream << ", &EVCState_" << pFaultState->m_OID;
1438 
1439  } // if (pFaultState != 0)
1440 
1441  // finally close constructor statement
1442  OutStream << ");\n";
1443  // Bouml preserved body end 000B0B82
1444 
1445 } // void CCPPGenerator::GenerateDataFlow() throw(::GOPPRR::Error::CException)
1446 
1447 
1448 
1449 
1450 void CCPPGenerator::GenerateDataFlow(const ::std::string & OID, GOPPRR::CGraph * const pSubFunctionBlock, ::std::ostream & OutStream) throw(::GOPPRR::Error::CException)
1451 {
1452  // Bouml preserved body begin 000B3182
1453  decltype (::GOPPRR::CGraph::m_ObjectSet.begin()) Object;
1454  decltype (::GOPPRR::CGraph::m_RelationshipSet.begin()) Relationship;
1455 
1456 
1457 
1458 
1459  // process all CommunicationReader and -Sender objects and add CBitFlow objects between CVariable and CStorage objects
1460  for (Object = pSubFunctionBlock->m_ObjectSet.begin(); Object != pSubFunctionBlock->m_ObjectSet.end(); Object++)
1461  {
1462  // check, if current object is a communication device
1463  if (Object->second->m_Type == "CommunicationReader" || Object->second->m_Type == "CommunicationSender")
1464  {
1465  // check, if decomposition does exist
1466  if (Object->second->m_pDecomposition != nullptr)
1467  {
1468  // call method for adding the bit flows in communication graph
1469  this->GenerateDataFlowForCommunication(OID, Object->second->m_pDecomposition, OutStream);
1470 
1471  } // if (Object->second->m_pDecomposition != nullptr)
1472 
1473  } // if (Object->second->m_Type == "CommunicationReader" || Object->second->m_Type == "CommunicationSender")
1474 
1475  } // for (Object = pSubFunctionBlock->m_ObjectSet.begin(); Object != pSubFunctionBlock->m_ObjectSet.end(); Object++)
1476 
1477  // process all "DataFlow" relationships in current sub graph to add CFlow objects to vector
1478  for (Relationship = pSubFunctionBlock->m_RelationshipSet.begin(); Relationship != pSubFunctionBlock->m_RelationshipSet.end(); Relationship++)
1479  {
1480  // check, if current relationship is "DataFlow" (ignore all others)
1481  if (Relationship->second->m_Type == "DataFlow")
1482  {
1483  // generate code for adding pointer to related CFlow object to vector of data flow object
1484  OutStream << "FLOWVEC_" << OID << ".push_back(&FLOW_" << Relationship->second->m_OID << ");\n";
1485 
1486  } // if (Relationship->second->m_Type == "DataFlow")
1487 
1488  } // for (Relationship = pSubFunctionBlock->m_RelationshipSet.begin(); Relationship != pSubFunctionBlock->m_RelationshipSet.end(); Relationship++)
1489 
1490  // process all objects in sub function block
1491  for (Object = pSubFunctionBlock->m_ObjectSet.begin(); Object != pSubFunctionBlock->m_ObjectSet.end(); Object++)
1492  {
1493  // check, if current object is a sub function block
1494  if (Object->second->m_Type == "SubFunction")
1495  {
1496  // check, if object has a decomposition
1497  if (Object->second->m_pDecomposition != 0)
1498  {
1499  // call this method recursively on decomposition
1500  this->GenerateDataFlow(OID, Object->second->m_pDecomposition, OutStream);
1501 
1502  } // if (Object->second->m_pDecomposition != 0)
1503 
1504  } // if (Object->second->m_Type == "SubFunction")
1505 
1506  } // for (Object = pSubFunctionBlock->m_ObjectSet.begin(); Object != pSubFunctionBlock->m_ObjectSet.end(); Object++)
1507  // Bouml preserved body end 000B3182
1508 
1509 } // void CCPPGenerator::GenerateDataFlow() throw(::GOPPRR::Error::CException)
1510 
1511 
1512 
1513 
1514 void CCPPGenerator::GenerateDataFlowForCommunication(const ::std::string & OID, GOPPRR::CGraph * const pCommGraph, ::std::ostream & OutStream) throw(::GOPPRR::Error::CException)
1515 {
1516  // Bouml preserved body begin 000E0F82
1517  decltype (::GOPPRR::CGraph::m_ObjectSet.begin()) Object;
1518  decltype (::GOPPRR::CGraph::m_RelationshipSet.begin()) Relationship;
1519  ::GOPPRR::CRole* pDataOutput(0);
1520  ::GOPPRR::CObject* pOutputObject(0);
1521 
1522 
1523 
1524  // process all "DataFlow" relationships in current sub graph to add CFlow objects to vector
1525  for (Relationship = pCommGraph->m_RelationshipSet.begin(); Relationship != pCommGraph->m_RelationshipSet.end(); Relationship++)
1526  {
1527  // check, if current relationship is "DataFlow" (ignore all others)
1528  if (Relationship->second->m_Type == "DataFlow")
1529  {
1530  // get connected "DataOutput" role of relationship
1531  pDataOutput = pCommGraph->Roles(Relationship->second, "DataOutput", false, true).begin()->second;
1532 
1533  // get connected object of role
1534  pOutputObject = pCommGraph->Objects(pDataOutput, true).begin()->second;
1535 
1536 
1537  // check, if current data output object is variable instance or variable storage (other flows are ignored here)
1538  if (pOutputObject->m_Type == "VariableInstance" || pOutputObject->m_Type == "VariableStorage")
1539  {
1540  // generate code for adding pointer to related CFlow object to vector of data flow object
1541  OutStream << "FLOWVEC_" << OID << ".push_back(&FLOW_" << Relationship->second->m_OID << ");\n";
1542 
1543  } // if (pOutputObject->m_Type == "VariableInstance" || pOutputObject->m_Type == "VariableStorage")
1544 
1545  } // if (Relationship->second->m_Type == "DataFlow")
1546 
1547  } // for (Relationship = pCommGraph->m_RelationshipSet.begin(); Relationship != pCommGraph->m_RelationshipSet.end(); Relationship++)
1548  // Bouml preserved body end 000E0F82
1549 
1550 } // void CCPPGenerator::GenerateDataFlowForCommunication() throw(::GOPPRR::Error::CException)
1551 
1552 
1553 
1554 
1555 void CCPPGenerator::GenerateDMI(GOPPRR::CGraph * const pMainFunctionBlock, GOPPRR::CGraph * const pEVCGraph, GOPPRR::CObject * const pEVCState, ::std::ostream & OutStream) throw(::GOPPRR::Error::CException)
1556 {
1557  // Bouml preserved body begin 000B3102
1558  decltype (::GOPPRR::CGraph::m_ObjectSet) DMIInputs;
1559  decltype (::GOPPRR::CGraph::m_ObjectSet.begin()) DMIInput;
1560  decltype (::GOPPRR::CGraph::m_ObjectSet) DMIOutputs;
1561  decltype (::GOPPRR::CGraph::m_ObjectSet.begin()) DMIOutput;
1562  decltype (::GOPPRR::CGraph::m_ObjectSet) SubFunctions;
1563  decltype (::GOPPRR::CGraph::m_ObjectSet.begin()) SubFunction;
1564 
1565 
1566 
1567  // generate initial comment for this DMI widget object
1568  OutStream << "// DMI widget object " << pMainFunctionBlock->m_Type << " [" << pMainFunctionBlock->m_ID << "] with OID " << pMainFunctionBlock->m_OID << "\n";
1569 
1570  // generate code to instantiate vector with pointer to DMI input objects
1571  OutStream << "::std::vector< ::oETCS::DF::CDMIInput* > DMIIVEC_" << pMainFunctionBlock->m_OID << ";\n";
1572 
1573  // generate code to instantiate vector with pointer to DMI output objects
1574  OutStream << "::std::vector< ::oETCS::DF::CDMIOutput* > DMIOVEC_" << pMainFunctionBlock->m_OID << ";\n";
1575 
1576 
1577  // get all DMI input objects in current main function blocks
1578  DMIInputs = pMainFunctionBlock->Objects("DMIInput", false, false);
1579 
1580  // process all DMI input objects
1581  for (DMIInput = DMIInputs.begin(); DMIInput != DMIInputs.end(); DMIInput++)
1582  {
1583  // generate code for adding current DMI input object to vector
1584  OutStream << "DMIIVEC_" << pMainFunctionBlock->m_OID << ".push_back(&FBO_" << DMIInput->second->m_OID << ");\n";
1585 
1586  } // for (DMIInput = DMIInputs.begin(); DMIInput != DMIInputs.end(); DMIInput++)
1587 
1588  // get all DMI output objects in current main function blocks
1589  DMIOutputs = pMainFunctionBlock->Objects("DMIOutput", false, false);
1590 
1591  // process all DMI output objects
1592  for (DMIOutput = DMIOutputs.begin(); DMIOutput != DMIOutputs.end(); DMIOutput++)
1593  {
1594  // generate code for adding current DMI input object to vector
1595  OutStream << "DMIOVEC_" << pMainFunctionBlock->m_OID << ".push_back(&FBO_" << DMIOutput->second->m_OID << ");\n";
1596 
1597  } // for (DMIOutput = DMIOutputs.begin(); DMIOutput != DMIOutputs.end(); DMIOutput++)
1598 
1599 
1600  // get all sub function objects in current main function blocks
1601  SubFunctions = pMainFunctionBlock->Objects("SubFunction", false, false);
1602 
1603  // process all sub function objects
1604  for (SubFunction = SubFunctions.begin(); SubFunction != SubFunctions.end(); SubFunction++)
1605  {
1606  // check, if current sub function object has a decomposition
1607  if (SubFunction->second->m_pDecomposition != 0)
1608  {
1609  // call method for this sub function block graph
1610  this->GenerateDMI(pMainFunctionBlock->m_OID, SubFunction->second->m_pDecomposition, OutStream);
1611 
1612  } // if (SubFunction->second->m_pDecomposition != 0)
1613 
1614  } // for (SubFunction = SubFunctions.begin(); SubFunction != SubFunctions.end(); SubFunction++)
1615 
1616 
1617  // generate code for DMI widget creation
1618  OutStream << ::std::left << std::setw(38) << "::oETCS::DF::CDMISubject" << "DMI_" << pMainFunctionBlock->m_OID << "("
1619  << "DMIIVEC_" << pMainFunctionBlock->m_OID
1620  << ", DMIOVEC_" << pMainFunctionBlock->m_OID << ");\n";
1621  // Bouml preserved body end 000B3102
1622 
1623 } // void CCPPGenerator::GenerateDMI() throw(::GOPPRR::Error::CException)
1624 
1625 
1626 
1627 
1628 void CCPPGenerator::GenerateDMI(const ::std::string & OID, GOPPRR::CGraph * const pSubFunctionBlock, ::std::ostream & OutStream) throw(::GOPPRR::Error::CException)
1629 {
1630  // Bouml preserved body begin 000B4B02
1631  decltype (::GOPPRR::CGraph::m_ObjectSet) DMIInputs;
1632  decltype (::GOPPRR::CGraph::m_ObjectSet.begin()) DMIInput;
1633  decltype (::GOPPRR::CGraph::m_ObjectSet) DMIOutputs;
1634  decltype (::GOPPRR::CGraph::m_ObjectSet.begin()) DMIOutput;
1635  decltype (::GOPPRR::CGraph::m_ObjectSet) SubFunctions;
1636  decltype (::GOPPRR::CGraph::m_ObjectSet.begin()) SubFunction;
1637 
1638 
1639 
1640 
1641  // get all DMI input objects in current sub function blocks
1642  DMIInputs = pSubFunctionBlock->Objects("DMIInput", false, false);
1643 
1644  // process all DMI input objects
1645  for (DMIInput = DMIInputs.begin(); DMIInput != DMIInputs.end(); DMIInput++)
1646  {
1647  // generate code for adding current DMI input object to vector
1648  OutStream << "DMIIVEC_" << OID << ".push_back(&FBO_" << DMIInput->second->m_OID << ");\n";
1649 
1650  } // for (DMIInput = DMIInputs.begin(); DMIInput != DMIInputs.end(); DMIInput++)
1651 
1652  // get all DMI output objects in current sub function blocks
1653  DMIOutputs = pSubFunctionBlock->Objects("DMIOutput", false, false);
1654 
1655  // process all DMI output objects
1656  for (DMIOutput = DMIOutputs.begin(); DMIOutput != DMIOutputs.end(); DMIOutput++)
1657  {
1658  // generate code for adding current DMI input object to vector
1659  OutStream << "DMIOVEC_" << OID << ".push_back(&FBO_" << DMIOutput->second->m_OID << ");\n";
1660 
1661  } // for (DMIOutput = DMIOutputs.begin(); DMIOutput != DMIOutputs.end(); DMIOutput++)
1662 
1663  // get all sub function objects in current sub function blocks
1664  SubFunctions = pSubFunctionBlock->Objects("SubFunction", false, false);
1665 
1666  // process all sub function objects
1667  for (SubFunction = SubFunctions.begin(); SubFunction != SubFunctions.end(); SubFunction++)
1668  {
1669  // check, if current sub function object has a decomposition
1670  if (SubFunction->second->m_pDecomposition != 0)
1671  {
1672  // call this method recursively for this sub function block graph
1673  this->GenerateDMI(OID, SubFunction->second->m_pDecomposition, OutStream);
1674 
1675  } // if (SubFunction->second->m_pDecomposition != 0)
1676 
1677  } // for (SubFunction = SubFunctions.begin(); SubFunction != SubFunctions.end(); SubFunction++)
1678  // Bouml preserved body end 000B4B02
1679 
1680 } // void CCPPGenerator::GenerateDMI() throw(::GOPPRR::Error::CException)
1681 
1682 
1683 
1684 
1685 void CCPPGenerator::GenerateEVCTransitions(GOPPRR::CGraph * const pMainFunctionBlock, GOPPRR::CObject * const pEVCState, GOPPRR::CGraph * const pRootGraph, ::std::ostream & OutStream) throw(::GOPPRR::Error::CException)
1686 {
1687  // Bouml preserved body begin 000B6482
1688  decltype (::GOPPRR::CGraph::m_ObjectSet) ModeGuards;
1689  decltype (::GOPPRR::CGraph::m_ObjectSet.begin()) ModeGuard;
1690  decltype (::GOPPRR::CGraph::m_RelationshipSet) Transitions;
1691  decltype (::GOPPRR::CGraph::m_RoleSet) CurrentRoles;
1692  decltype (::GOPPRR::CGraph::m_RoleSet.begin()) CurrentRole;
1693  decltype (::GOPPRR::CGraph::m_RoleSet) NextRoles;
1694  ::GOPPRR::CObject* pCurrentModeGuard(nullptr);
1695  ::GOPPRR::CObject* pNextEVCState(nullptr);
1696  ::GOPPRR::CRelationship* pTransition(nullptr);
1697  bool bModeGuardFound(false);
1698 
1699 
1700 
1701  // get all mode guard objects in current main function block
1702  ModeGuards = pMainFunctionBlock->Objects("ModeGuard", false, false);
1703 
1704  // process all mode guard objects
1705  for (ModeGuard = ModeGuards.begin(); ModeGuard != ModeGuards.end(); ModeGuard++)
1706  {
1707  // get all current state roles of current EVC state object
1708  CurrentRoles = pRootGraph->Roles(pEVCState, ::std::string("CurrentState"));
1709 
1710  // process all current roles
1711  for (CurrentRole = CurrentRoles.begin(); CurrentRole != CurrentRoles.end() && not bModeGuardFound; CurrentRole++)
1712  {
1713  // get connected relationships
1714  Transitions = pRootGraph->Relationships(CurrentRole->second);
1715 
1716  // get pointer to curent transition relationship
1717  pTransition = Transitions.begin()->second;
1718 
1719  // get mode guard object as property of relationship
1720  pCurrentModeGuard = static_cast< ::GOPPRR::CObject* >(pTransition->Properties("ModeGuard").begin()->second->m_NonProperties.begin()->second);
1721 
1722  // check, if current mode in relationship is guard object in main function block
1723  if (pCurrentModeGuard == ModeGuard->second)
1724  {
1725  // check if OID of current mode guard was already generated
1726  if (m_GeneratedEVCTransitions.find(pTransition->m_OID) == m_GeneratedEVCTransitions.end())
1727  {
1728  // get next roles connected to relationship
1729  NextRoles = pRootGraph->Roles(pTransition, ::std::string("NextState"));
1730 
1731  // get pointer to next EVC state object
1732  pNextEVCState = pRootGraph->Objects(NextRoles.begin()->second).begin()->second;
1733 
1734  // generate code for creating current EVC transition
1735  OutStream << "// EVC transition object for ModeGuard [" << ModeGuard->second->m_ID << "] with OID " << ModeGuard->second->m_OID << "\n";
1736  OutStream << ::std::left << std::setw(38) << "::oETCS::DF::CEVCTransition" << "EVCTRANS_" << pTransition->m_OID << "("
1737  << "&FBO_" << ModeGuard->second->m_OID
1738  << ", &EVCState_" << pEVCState->m_OID
1739  << ", &EVCState_" << pNextEVCState->m_OID
1740  << ", " << pTransition->Properties("Priority").begin()->second->m_Value
1741  << ");\n";
1742 
1743  // store OID of current mode guard as generated
1744  m_GeneratedEVCTransitions[pTransition->m_OID] = true;
1745 
1746  } // if (m_GeneratedEVCTransitions.find(pCurrentModeGuard->m_OID) == m_GeneratedEVCTransitions.end())
1747 
1748  // set found flag to true
1749  bModeGuardFound = true;
1750 
1751  } // if (pCurrentModeGuard == ModeGuard->second)
1752 
1753  } // for (CurrentRole = CurrentRoles.begin(); CurrentRole != CurrentRoles.end() && not bModeGuardFound; CurrentRole++)
1754 
1755  // reset found flag
1756  bModeGuardFound = false;
1757 
1758  } // for (ModeGuard = ModeGuards.begin(); ModeGuard != ModeGuards.end(); ModeGuard++)
1759  // Bouml preserved body end 000B6482
1760 
1761 } // void CCPPGenerator::GenerateEVCTransitions() throw(::GOPPRR::Error::CException)
1762 
1763 
1764 
1765 
1766 void CCPPGenerator::GenerateControlFlows(GOPPRR::CProject * const pProject, ::std::ostream & OutStream) throw(::GOPPRR::Error::CException)
1767 {
1768  // Bouml preserved body begin 000B7E82
1769  decltype (::GOPPRR::CProject::m_ObjectSet.begin()) GObject;
1770  decltype (::GOPPRR::CGraph::m_ObjectSet) States;
1771  decltype (::GOPPRR::CGraph::m_ObjectSet.begin()) State;
1772  decltype (::GOPPRR::CGraph::m_ObjectSet) StateGuards;
1773  decltype (::GOPPRR::CGraph::m_ObjectSet.begin()) StateGuard;
1774  decltype (::GOPPRR::CGraph::m_ObjectSet.begin()) FunctionBlock;
1775  decltype (::GOPPRR::CGraph::m_ObjectSet) Finals;
1776  decltype (::GOPPRR::CGraph::m_ObjectSet.begin()) Final;
1777  decltype (::GOPPRR::CGraph::m_RoleSet) Currents;
1778  decltype (::GOPPRR::CGraph::m_RoleSet.begin()) Current;
1779  decltype (::GOPPRR::CGraph::m_RoleSet) Nexts;
1780  decltype (::GOPPRR::CGraph::m_RoleSet.begin()) Next;
1781  decltype (::GOPPRR::CGraph::m_RelationshipSet) Transitions;
1782  decltype (::GOPPRR::CGraph::m_RoleSet.begin()) Relationship;
1783  decltype (::GOPPRR::CGraph::m_RelationshipSet) Relationships;
1784  const ::std::string CONTROL_FLOW_OBJECT("EmbeddedStateMachine");
1785  const ::std::string STATE_OBJECT("EmbeddedState");
1786  const ::std::string STATE_GUARD_OBJECT("StateGuard");
1787  const ::std::string INITIAL_OBJECT("EmbeddedInitialState");
1788  const ::std::string FINAL_OBJECT("EmbeddedFinalState");
1789  ::GOPPRR::CGraph* pControlFlow(0);
1790  ::GOPPRR::CGraph* pDataFlow(0);
1791  ::GOPPRR::CObject* pObject(0);
1792  ::std::string OID;
1793  ::std::map< ::std::string, ::oETCS::GEN::CFBNode > FBNodes;
1794  decltype (FBNodes.begin()) n;
1795  decltype (::oETCS::GEN::CFBNode::m_Inputs.begin()) i;
1796  ::std::list< ::std::string > ExecutionOrder;
1797  decltype (ExecutionOrder.begin()) s;
1798  ::std::vector< const oETCS::GEN::CFBNode* > NodeStack(0);
1799  bool bInitial(false);
1800 
1801 
1802 
1803 
1804 
1805  // process all objects in project
1806  for (GObject = pProject->m_ObjectSet.begin(); GObject != pProject->m_ObjectSet.end(); GObject++)
1807  {
1808  // check, if current object is an embedded state machine
1809  if (GObject->second.m_Type == CONTROL_FLOW_OBJECT)
1810  {
1811  // check, if this embedded state machine has a decomposition
1812  if (GObject->second.m_pDecomposition != 0)
1813  {
1814  // store pointer to current control flow graph
1815  pControlFlow = GObject->second.m_pDecomposition;
1816 
1817  // get all states from current graph
1818  States = pControlFlow->Objects(STATE_OBJECT, false, false);
1819 
1820  // process all states
1821  for (State = States.begin(); State != States.end(); State++)
1822  {
1823  // check if this state was already instantiated
1824  if (m_GeneratedControlFlows.find(State->second->m_OID) == m_GeneratedControlFlows.end())
1825  {
1826  // generate initial comment for current state object
1827  OutStream << "// State object " << State->second->m_Type << " [" << State->second->m_ID << "] with OID " << State->second->m_OID << "\n";
1828 
1829  // generate code for vector with active function block elements
1830  OutStream << "::std::vector< ::oETCS::DF::CFunctionBlock* > CVEC_" << State->second->m_OID << ";\n";
1831 
1832  // generate code for vector of CAbstracFlow pointers for current data flow
1833  OutStream << "::std::vector< ::oETCS::DF::CAbstractFlow* > FLOWVEC_" << State->second->m_OID << ";\n";
1834 
1835  // get all next roles of state
1836  Nexts = pControlFlow->Roles(State->second, "NextState", false, false);
1837 
1838  // process all next roles
1839  for (Next = Nexts.begin(); Next != Nexts.end() && not bInitial; Next++)
1840  {
1841  // get connected current role of current current role
1842  Currents = pControlFlow->Roles(Next->second, ::std::string("CurrentState"));
1843 
1844  // get connected object
1845  pObject = pControlFlow->Objects(Currents.begin()->second).begin()->second;
1846 
1847  // check, if object is an initial state object
1848  if (pObject->m_Type == INITIAL_OBJECT)
1849  {
1850  // set initial flag to true
1851  bInitial = true;
1852 
1853  } // if (pObject->m_Type == INITIAL_OBJECT)
1854 
1855  } // for (Next = Nexts.begin(); Next != Nexts.end() && not bInitial; Next++)
1856 
1857 
1858  // check, if current state has a decomposition
1859  if (State->second->m_pDecomposition != 0)
1860  {
1861  // store pointer to current data flow graph
1862  pDataFlow = State->second->m_pDecomposition;
1863 
1864 
1865  // clear function bloack node map
1866  FBNodes.clear();
1867 
1868  // call helper method for adding all objects recursively from all graphs (including sub graphs)
1870 
1871  // process all nodes found (including sub-graphs)
1872  for (n = FBNodes.begin(); n != FBNodes.end(); n++)
1873  {
1874  // process all inputs of current node
1875  for (i = n->second.m_Inputs.begin(); i != n->second.m_Inputs.end(); i++)
1876  {
1877  // store OID of current output node
1878  OID = (*i)->m_OID;
1879 
1880  // check, if input is still undefined
1881  if ((*i)->m_eState == ::oETCS::GEN::CFBNode::UNDEFINED)
1882  {
1883  // delete current undefined object
1884  delete (*i);
1885 
1886  // use pointer to actual node at iterators place
1887  *i = &FBNodes[OID];
1888 
1889  } // if ((*i)->m_eState == ::oETCS::GEN::CFBNode::UNDEFINED)
1890 
1891  } // for (i = n->second.m_Inputs.begin(); i != n->second.m_Inputs.end(); i++)
1892 
1893  } // for (n = FBNodes.begin(); n != FBNodes.end(); n++)
1894 
1895  // clear node stack
1896  NodeStack.clear();
1897 
1898  // clear execution order stack
1899  ExecutionOrder.clear();
1900 
1901  // process all nodes found again to determine execution order
1902  for (n = FBNodes.begin(); n != FBNodes.end(); n++)
1903  {
1904  // call method for processing abstract model
1905  ::oETCS::GEN::CCPPGenerator::ProcessAbstractModel(n->second, ExecutionOrder, NodeStack);
1906 
1907  } // for (n = FBNodes.begin(); n != FBNodes.end(); n++)
1908 
1909 
1910  // generate code for adding function block objects to vector in right order for data flow
1911  for (s = ExecutionOrder.begin(); s != ExecutionOrder.end(); s++)
1912  {
1913  // generate code for adding current function block element to vector with pointers
1914  OutStream << "CVEC_" << State->second->m_OID << ".push_back(&FBO_" << *s << ");\n";
1915 
1916  } // for (s = ExecutionOrder.begin(); s != ExecutionOrder.end(); s++)
1917 
1918 
1919  // process all "DataFlow" relationships by internal helper method
1920  this->GenerateDataFlow(State->second->m_OID, State->second->m_pDecomposition, OutStream);
1921 
1922 
1923  } // if (State->second->m_pDecomposition != 0)
1924 
1925 
1926  // generate code for current state object
1927  OutStream << ::std::left << std::setw(38) << "::oETCS::DF::CControlFlow::CState" << "STATE_" << State->second->m_OID << "("
1928  << "&FBO_" << GObject->second.m_OID
1929  << ", \"" << State->second->Properties("Name").begin()->second->m_Value << "\""
1930  << ", CVEC_" << State->second->m_OID
1931  << ", FLOWVEC_" << State->second->m_OID
1932  << ", false"
1933  << ", " << (bInitial ? "true" : "false")
1934  << ");\n";
1935 
1936 
1937  // insert newlines
1938  OutStream << "\n\n\n\n";
1939 
1940 
1941  // reset initial flag
1942  bInitial = false;
1943 
1944  // store current OID as generated
1945  m_GeneratedControlFlows[State->second->m_OID] = true;
1946 
1947  } // if (m_GeneratedControlFlows.find(State->second->m_OID) == m_GeneratedControlFlows.end())
1948 
1949  } // for (State = States.begin(); State != States.end(); State++)
1950 
1951 
1952 
1953  // get all final states in control flow graph
1954  Finals = pControlFlow->Objects(FINAL_OBJECT, false, false);
1955 
1956  // process all final objects
1957  for (Final = Finals.begin(); Final != Finals.end(); Final++)
1958  {
1959  // check if this state was already instantiated
1960  if (m_GeneratedControlFlows.find(Final->second->m_OID) == m_GeneratedControlFlows.end())
1961  {
1962 
1963  // generate code for current final state object
1964  OutStream << "// Final state object " << Final->second->m_Type << " with OID " << Final->second->m_OID << "\n";
1965  OutStream << ::std::left << std::setw(38) << "::oETCS::DF::CControlFlow::CState" << "STATE_" << Final->second->m_OID << "("
1966  << "&FBO_" << GObject->second.m_OID
1967  << ", \"" << Final->second->Properties("Name").begin()->second->m_Value << "\""
1968  << ", ::std::vector< ::oETCS::DF::CFunctionBlock* >(0)"
1969  << ", ::std::vector< ::oETCS::DF::CAbstractFlow* >(0)"
1970  << ", true"
1971  << ", false"
1972  << ");\n";
1973 
1974  // store current OID as generated
1975  m_GeneratedControlFlows[Final->second->m_OID] = true;
1976 
1977  } // if (m_GeneratedControlFlows.find(State->second->m_OID) == m_GeneratedControlFlows.end())
1978 
1979  } // for (Final = Finals.begin(); Final != Finals.end(); Final++)
1980 
1981  // insert newlines
1982  OutStream << "\n\n\n\n";
1983 
1984  } // if (GObject->second.m_pDecomposition != 0)
1985 
1986  } // if (GObject->second.m_Type == CONTROL_FLOW_OBJECT)
1987 
1988  } // for (GObject = pProject->m_ObjectSet.begin(); GObject != pProject->m_ObjectSet.end(); GObject++)
1989  // Bouml preserved body end 000B7E82
1990 
1991 } // void CCPPGenerator::GenerateControlFlows() throw(::GOPPRR::Error::CException)
1992 
1993 
1994 
1995 
1996 void CCPPGenerator::GenerateTransitions(GOPPRR::CGraph * const pRootGraph, ::std::ostream & OutStream) throw(::GOPPRR::Error::CException)
1997 {
1998  // Bouml preserved body begin 000B9882
1999  decltype (::GOPPRR::CGraph::m_ObjectSet) EVCStates;
2000  decltype (::GOPPRR::CGraph::m_ObjectSet.begin()) EVCState;
2001  decltype (::GOPPRR::CObject::m_Explosions) Explosions;
2002  decltype (::GOPPRR::CObject::m_Explosions.begin()) Explosion;
2003  const ::std::string EVCSTATE_OBJECT(__GENERATOR__EVCSTATE__);
2004 
2005 
2006 
2007 
2008 
2009  // get all EVC state objects in root graph
2010  EVCStates = pRootGraph->Objects(EVCSTATE_OBJECT);
2011 
2012  // process all EVC state objects
2013  for (EVCState = EVCStates.begin(); EVCState != EVCStates.end(); EVCState++)
2014  {
2015  // get all explosions of current EVC state
2016  Explosions = EVCState->second->m_Explosions;
2017 
2018  // process all explosions (main function block graphs)
2019  for (Explosion = Explosions.begin(); Explosion != Explosions.end(); Explosion++)
2020  {
2021  // call internal helper to create transitions
2022  this->GenerateTransitions(Explosion->second, EVCState->second, OutStream);
2023 
2024  } // for (Explosion = Explosions.begin(); Explosion != Explosions.end(); Explosion++)
2025 
2026  } // for (EVCState = EVCStates.begin(); EVCState != EVCStates.end(); EVCState++)
2027  // Bouml preserved body end 000B9882
2028 
2029 } // void CCPPGenerator::GenerateTransitions() throw(::GOPPRR::Error::CException)
2030 
2031 
2032 
2033 
2034 void CCPPGenerator::GenerateTransitions(GOPPRR::CGraph * const pFunctionBlock, GOPPRR::CObject * const pEVCState, ::std::ostream & OutStream) throw(::GOPPRR::Error::CException)
2035 {
2036  // Bouml preserved body begin 000B9902
2037  decltype (::GOPPRR::CGraph::m_ObjectSet) StateMachines;
2038  decltype (::GOPPRR::CGraph::m_ObjectSet.begin()) StateMachine;
2039  decltype (::GOPPRR::CGraph::m_ObjectSet) States;
2040  decltype (::GOPPRR::CGraph::m_ObjectSet.begin()) State;
2041  decltype (::GOPPRR::CGraph::m_ObjectSet) SubFunctions;
2042  decltype (::GOPPRR::CGraph::m_ObjectSet.begin()) SubFunction;
2043  ::GOPPRR::CGraph* pControlFlow(0);
2044  const ::std::string CONTROL_FLOW_OBJECT("EmbeddedStateMachine");
2045  const ::std::string STATE_OBJECT("EmbeddedState");
2046  const ::std::string SUB_FUNCTION_OBJECT("SubFunction");
2047 
2048 
2049 
2050 
2051  // get all embedded state machines in current graph
2052  StateMachines = pFunctionBlock->Objects(CONTROL_FLOW_OBJECT, false, false);
2053 
2054  // process all embedded state machine objects
2055  for (StateMachine = StateMachines.begin(); StateMachine != StateMachines.end(); StateMachine++)
2056  {
2057  // check, if this embedded state machine has a decomposition
2058  if (StateMachine->second->m_pDecomposition != 0)
2059  {
2060  // store pointer to current control flow graph
2061  pControlFlow = StateMachine->second->m_pDecomposition;
2062 
2063  // get all states from current graph
2064  States = pControlFlow->Objects(STATE_OBJECT, false, false);
2065 
2066  // process all states again for because of transitions
2067  for (State = States.begin(); State != States.end(); State++)
2068  {
2069  // check, if current state has a decomposition
2070  if (State->second->m_pDecomposition != 0)
2071  {
2072  // call helper to generate transitions
2073  this->GenerateTransitions(State->second->m_pDecomposition, pControlFlow, pEVCState, State->second, OutStream);
2074 
2075  } // if (State->second->m_pDecomposition != 0)
2076 
2077  } // for (State = States.begin(); State != States.end(); State++)
2078 
2079  } // if (StateMachine->second->m_pDecomposition != 0)
2080 
2081  } // for (StateMachine = StateMachines.begin(); StateMachine != StateMachines.end(); StateMachine++)
2082 
2083 
2084 
2085  // get all sub function objects in current data flow
2086  SubFunctions = pFunctionBlock->Objects(SUB_FUNCTION_OBJECT, false, false);
2087 
2088  // process all sub function objects
2089  for (SubFunction = SubFunctions.begin(); SubFunction != SubFunctions.end(); SubFunction++)
2090  {
2091  // check, if current sub function object has a decomposition
2092  if (SubFunction->second->m_pDecomposition != 0)
2093  {
2094  // call this method recursively for sub data flow graph
2095  this ->GenerateTransitions(SubFunction->second->m_pDecomposition, pEVCState, OutStream);
2096 
2097  } // if (SubFunction->second->m_pDecomposition != 0)
2098 
2099  } // for (SubFunction = SubFunctions.begin(); SubFunction != SubFunctions.end(); SubFunction++)
2100  // Bouml preserved body end 000B9902
2101 
2102 } // void CCPPGenerator::GenerateTransitions() throw(::GOPPRR::Error::CException)
2103 
2104 
2105 
2106 
2107 void CCPPGenerator::GenerateTransitions(GOPPRR::CGraph * const pFunctionBlock, GOPPRR::CGraph * const pControlFlow, GOPPRR::CObject * const pEVCState, GOPPRR::CObject * const pState, ::std::ostream & OutStream) throw(::GOPPRR::Error::CException)
2108 {
2109  // Bouml preserved body begin 000B9802
2110  decltype (::GOPPRR::CGraph::m_ObjectSet) StateGuards;
2111  decltype (::GOPPRR::CGraph::m_ObjectSet.begin()) StateGuard;
2112  decltype (::GOPPRR::CGraph::m_RoleSet) Currents;
2113  decltype (::GOPPRR::CGraph::m_RoleSet.begin()) Current;
2114  decltype (::GOPPRR::CGraph::m_RoleSet) Nexts;
2115  decltype (::GOPPRR::CGraph::m_RoleSet.begin()) Next;
2116  decltype (::GOPPRR::CGraph::m_RelationshipSet) Transitions;
2117  const ::std::string STATE_GUARD_OBJECT("StateGuard");
2118  ::GOPPRR::CObject* pGuard(0);
2119  ::GOPPRR::CObject* pTarget(0);
2120 
2121 
2122 
2123 
2124 
2125 
2126  // get all state guards in current data flow
2127  StateGuards = pFunctionBlock->Objects(STATE_GUARD_OBJECT, false, false);
2128 
2129  // process all state guards
2130  for (StateGuard = StateGuards.begin(); StateGuard != StateGuards.end(); StateGuard++)
2131  {
2132  // get all current state roles of corresponding state object
2133  Currents = pControlFlow->Roles(pState, std::string("CurrentState"), false, true);
2134 
2135  // process all current state roles
2136  for (Current = Currents.begin(); Current != Currents.end(); Current++)
2137  {
2138  // get connected transition relationship
2139  Transitions = pControlFlow->Relationships(Current->second);
2140 
2141  // get state guard pointer from property
2142  pGuard = static_cast< ::GOPPRR::CObject* >(Transitions.begin()->second->Properties("StateGuard").begin()->second->m_NonProperties.begin()->second);
2143 
2144  // compare current state guard with one of relationship
2145  if (StateGuard->second == pGuard)
2146  {
2147  // get next roles from relationship
2148  Nexts = pControlFlow->Roles(Transitions.begin()->second, ::std::string("NextState"));
2149 
2150  // get pointer to target state from next role
2151  pTarget = pControlFlow->Objects(Nexts.begin()->second).begin()->second;
2152 
2153  // check, if transition instance was already generated
2154  if (m_GeneratedTransitions.find(StateGuard->second->m_OID + "_" + pEVCState->m_OID + "_" + pControlFlow->m_OID) == m_GeneratedTransitions.end())
2155  {
2156  // generate code for instantiation for state transition object (parent EVC state needed!)
2157  OutStream << "// State transition object " << StateGuard->second->m_Type << " [" << StateGuard->second->m_ID << "] with OID " << StateGuard->second->m_OID
2158  << " in EVCState [" << pEVCState->m_ID << "] with OID " << pEVCState->m_OID << "\n";
2159  OutStream << ::std::left << std::setw(38) << "::oETCS::DF::CTransition" << "TRANS_" << StateGuard->second->m_OID << "_" << pEVCState->m_OID << "_" << pControlFlow->m_OID << "("
2160  << "&EVCState_" << pEVCState->m_OID
2161  << ", &FBO_" << StateGuard->second->m_OID
2162  << ", &STATE_" << pState->m_OID
2163  << ", &STATE_" << pTarget->m_OID
2164  << ", " << Transitions.begin()->second->Properties("Priority").begin()->second->m_Value
2165  << ");\n";
2166 
2167  // store OID of this transition as already generated
2168  m_GeneratedTransitions[StateGuard->second->m_OID + "_" + pEVCState->m_OID + "_" + pControlFlow->m_OID] = true;
2169 
2170  } // if (m_GeneratedTransitions.find(StateGuard->second->m_OID) == m_GeneratedTransitions.end())
2171 
2172  } // if (StateGuard->second == pGuard)
2173 
2174  } // for (Current = Currents.begin(); Current != Currents.end(); Current++)
2175 
2176  } // for (StateGuard = StateGuards.begin(); StateGuard != StateGuards.end(); StateGuard++)
2177  // Bouml preserved body end 000B9802
2178 
2179 } // void CCPPGenerator::GenerateTransitions() throw(::GOPPRR::Error::CException)
2180 
2181 
2182 
2183 
2184 void CCPPGenerator::GenerateLanguage(GOPPRR::CProject * const pProject, ::std::ostream & OutStream) throw(::GOPPRR::Error::CException)
2185 {
2186  // Bouml preserved body begin 000A5182
2187  decltype (pProject->m_GraphSet.begin()) GGraph;
2188  decltype (pProject->m_GraphSet) GGraphs;
2189  decltype (::GOPPRR::CObject::m_Explosions.begin()) Graph;
2190  decltype (pProject->m_ObjectSet.begin()) GObject;
2191  decltype (pProject->m_ObjectSet.begin()) ComObject;
2192  decltype (::GOPPRR::CObject::m_Properties) Properties;
2193  decltype (::GOPPRR::CObject::m_Properties.begin()) Property;
2194  decltype (::GOPPRR::CProperty::m_NonProperties) NonProperties;
2195  decltype (::GOPPRR::CProperty::m_NonProperties.begin()) NonProperty;
2196  decltype (::GOPPRR::CGraph::m_RoleSet) Previous;
2197  decltype (::GOPPRR::CGraph::m_RoleSet) Next;
2198  decltype (::GOPPRR::CGraph::m_RoleSet) ScalingValues;
2199  decltype (::GOPPRR::CGraph::m_RoleSet.begin()) ScalingValue;
2200  decltype (::GOPPRR::CGraph::m_RoleSet.begin()) ScaledValue;
2201  decltype (::GOPPRR::CGraph::m_ObjectSet) AnyPackets;
2202  decltype (::GOPPRR::CGraph::m_ObjectSet.begin()) AnyPacket;
2203  decltype (::GOPPRR::CGraph::m_ObjectSet) Variables;
2204  decltype (::GOPPRR::CGraph::m_ObjectSet.begin()) Variable;
2205  decltype (::GOPPRR::CGraph::m_ObjectSet) BaliseInDevices;
2206  decltype (::GOPPRR::CGraph::m_ObjectSet.begin()) BaliseInDevice;
2207  decltype (::GOPPRR::CGraph::m_ObjectSet) BaliseOutDevices;
2208  decltype (::GOPPRR::CGraph::m_ObjectSet.begin()) BaliseOutDevice;
2209  decltype (::GOPPRR::CGraph::m_PortSet) OutPorts;
2210  decltype (::GOPPRR::CGraph::m_PortSet) InPorts;
2211  decltype (::GOPPRR::CGraph::m_RoleSet) OutRoles;
2212  decltype (::GOPPRR::CGraph::m_RoleSet.begin()) OutRole;
2213  decltype (::GOPPRR::CGraph::m_RoleSet) InRoles;
2214  decltype (::GOPPRR::CGraph::m_ObjectSet) Telegrams;
2215  decltype (::GOPPRR::CGraph::m_ObjectSet.begin()) Telegram;
2216  decltype (::GOPPRR::CGraph::m_ObjectSet) Packets;
2217  decltype (::GOPPRR::CGraph::m_ObjectSet.begin()) Packet;
2218  decltype (::GOPPRR::CGraph::m_ObjectSet) IteratedVariables;
2219  decltype (::GOPPRR::CGraph::m_ObjectSet.begin()) Iterated;
2220  ::GOPPRR::CObject* pCurrentNode(nullptr);
2221  ::GOPPRR::CObject* pLeafNode(nullptr);
2222  ::GOPPRR::CObject* pVariableType(nullptr);
2223  ::GOPPRR::CGraph* pTelegramGraph(nullptr);
2224  ::GOPPRR::CObject* pScaledVariable(nullptr);
2225  ::std::string ResolutionUnit;
2226  ::std::string Resolution;
2227  ::std::string Size;
2228  ::std::string Value;
2229  ::std::string MappedValue;
2230  ::std::string Unit;
2231  ::std::string ValueType;
2232  ::std::string PacketID;
2233  ::std::string ConditionalIterator;
2234  ::std::string ConditionalValue;
2235  const ::std::string TELEGRAM_GRAPH(__GENERATOR__TELEGRAMGRAPH__);
2236  const ::std::string EVCSTATE_OBJECT(__GENERATOR__EVCSTATE__);
2237  const ::std::string MAINFB_GRAPH(__GENERATOR__MAINFB__);
2238  const ::std::string SUBFB_GRAPH(__GENERATOR__SUBFB__);
2239  const ::std::string APPLICATION_LEVEL_OBJECT("ApplicationLevelType");
2240  const ::std::string DMI_INPUT_OBJECT("DMIInput");
2241  const ::std::string DMI_OUTPUT_OBJECT("DMIOutput");
2242  const ::std::string BALISE_IN_DEVICE("BaliseReader");
2243  const ::std::string BALISE_OUT_DEVICE("BaliseSender");
2244  const ::std::string COM_IN("CommunicationReader");
2245  const ::std::string COM_OUT("CommunicationSender");
2246  const ::std::string VARIABLE_INSTANCE_OBJECT("VariableInstance");
2247  const ::std::string PACKET_OBJECT("Packet");
2248  const ::std::string ANY_PACKET_OBJECT("AnyPacket");
2249  const ::std::string VARIABLE_TYPE_OBJECT("VariableType");
2250  const ::std::string VARIABLE_STORAGE_OBJECT("VariableStorage");
2251  const ::std::string VARIABLE_TYPE_RESOLUTION("VariableResolution");
2252  const ::std::string VARIABLE_TYPE_RESOLUTION_UNIT("Unit");
2253  const ::std::string VARIABLE_TYPE_SIZE("Size");
2254  const ::std::string VALUEMAP_OBJECT("ValueMap");
2255  const ::std::string TELEGRAM_OBJECT("Telegram");
2256  const ::std::string DATAFLOW_RELATIONSHIP("DataFlow");
2257  const ::std::string DATAINPUT_ROLE("DataInput");
2258  const ::std::string DATAOUTPUT_ROLE("DataOutput");
2259  const ::std::string CONDITIONAL_FLAG_PROPERTY("IsConditionalIterator");
2260  const ::std::string CONDITIONAL_VALUE_PROPERTY("ConditionalValue");
2261  ::std::vector< ::std::string > InDeviceNames;
2262  ::std::vector< ::std::string > OutDeviceNames;
2263  ::std::stringstream TempStream;
2264  unsigned int x(0);
2265 
2266 
2267 
2268 
2269  // process all communication reader graphs
2270  for (GGraph = pProject->m_GraphSet.begin(); GGraph != pProject->m_GraphSet.end(); GGraph++)
2271  {
2272  // check, if current graph is a communication reader
2273  if (GGraph->second.m_Type == COM_IN)
2274  {
2275  // generate vector with used packet IDs in this graph
2276  OutStream << "// Vector of used packet IDs in graph [" << GGraph->second.m_ID << "] with OID " << GGraph->second.m_OID << "\n";
2277  OutStream << ::std::left << std::setw(38) << "::std::vector< unsigned char >" << "PACKIDVEC_" << GGraph->second.m_OID << ";\n";
2278 
2279 
2280  // get all packets in current graph
2281  Packets = GGraph->second.Objects(PACKET_OBJECT, false, false);
2282 
2283  // process all packet objects
2284  for (Packet = Packets.begin(); Packet != Packets.end(); Packet++)
2285  {
2286  // add ID of current packet to vector
2287  OutStream << "PACKIDVEC_" << GGraph->second.m_OID << ".push_back(" << Packet->second->Properties("PacketID").begin()->second->m_Value << ");\n";
2288 
2289  } // for (Packet = Packets.begin(); Packet != Packets.end(); Packet++)
2290 
2291  } // if (GGraph->second.m_Type == COM_IN)
2292 
2293  } // for (GGraph = pProject->m_GraphSet.begin(); GGraph != pProject->m_GraphSet.end(); GGraph++)
2294 
2295 
2296 
2297  // insert newlines
2298  OutStream << "\n\n\n\n";
2299 
2300 
2301 
2302  // process all value map objects
2303  for (GObject = pProject->m_ObjectSet.begin(); GObject != pProject->m_ObjectSet.end(); GObject++)
2304  {
2305  // check, if current object is a value map
2306  if (GObject->second.m_Type == VALUEMAP_OBJECT)
2307  {
2308  // get value of map
2309  Value = GObject->second.Properties("Value").begin()->second->m_Value;
2310 
2311  // get mapped value of map
2312  MappedValue = GObject->second.Properties("MappedValue").begin()->second->m_Value;
2313 
2314  // get unit value of map
2315  Unit = GObject->second.Properties("ValueType").begin()->second->m_Value;
2316 
2317  // get value type of map
2318  ValueType = GObject->second.Properties("ValueType").begin()->second->m_Value;
2319 
2320  // generate instantiation of current value map object
2321  OutStream << "// Variable object (as value map) " << GObject->second.m_Type << " [" << GObject->second.m_ID << "] with OID " << GObject->second.m_OID << "\n";
2322  OutStream << ::std::left << std::setw(38) << "::oETCS::DF::CVariable" << "VARMAP_" << GObject->second.m_OID << "(&EVC, 1";
2323 
2324  // check, which resolution unit is used
2325  if (Unit == "double")
2326  {
2327  // generate unit parameter
2328  OutStream << ", ::oETCS::DF::CVariable::DOUBLE";
2329 
2330  } // if (Unit == "double")
2331  else if (Unit == "string")
2332  {
2333  // generate unit parameter
2334  OutStream << ", ::oETCS::DF::CVariable::STRING";
2335 
2336  } // else if (Unit == "string")
2337  else
2338  {
2339  // generate unit parameter
2340  OutStream << ", ::oETCS::DF::CVariable::INTEGER";
2341 
2342  } // else
2343 
2344  // generate size parameter for constructor
2345  OutStream << ", " << MappedValue.length();
2346 
2347  // generate end of current constructor
2348  OutStream << ");\n";
2349 
2350  // generate setting of value
2351  OutStream << "VARMAP_" << GObject->second.m_OID << ".SetValue(\"" << MappedValue << "\");\n";
2352 
2353  } // if (GObject->second.m_Type == VALUEMAP_OBJECT)
2354 
2355  } // for (GObject = pProject->m_ObjectSet.begin(); GObject != pProject->m_ObjectSet.end(); GObject++)
2356 
2357 
2358  // insert newlines
2359  OutStream << "\n\n\n\n";
2360 
2361 
2362  // process all variable instances objects
2363  for (GObject = pProject->m_ObjectSet.begin(); GObject != pProject->m_ObjectSet.end(); GObject++)
2364  {
2365  // check, if current object is a variable instance
2366  if (GObject->second.m_Type == VARIABLE_INSTANCE_OBJECT)
2367  {
2368  // get pointer to variable type object of this instance object
2369  pVariableType = dynamic_cast< ::GOPPRR::CObject* >(GObject->second.Properties("Type").begin()->second->NonProperties(VARIABLE_TYPE_OBJECT).begin()->second);
2370 
2371  // get resolution from property
2372  Resolution = pVariableType->Properties(VARIABLE_TYPE_RESOLUTION).begin()->second->m_Value;
2373 
2374  // get resolution unit from property
2375  ResolutionUnit = pVariableType->Properties(VARIABLE_TYPE_RESOLUTION_UNIT).begin()->second->m_Value;
2376 
2377  // get variable bit size from property
2378  Size = pVariableType->Properties(VARIABLE_TYPE_SIZE).begin()->second->m_Value;
2379 
2380  // get variable conditional flag and value from properties of variable instance
2381  ConditionalIterator = GObject->second.Properties(CONDITIONAL_FLAG_PROPERTY).begin()->second->m_Value == "T" ? "true" : "false";
2382  ConditionalValue = GObject->second.Properties(CONDITIONAL_VALUE_PROPERTY).begin()->second->m_Value;
2383 
2384  // generate initial comment for this variable object
2385  OutStream << "// Variable object " << GObject->second.m_Type << " [" << GObject->second.m_ID << "] with OID " << GObject->second.m_OID << "\n";
2386 
2387  // get value map property of current variable type
2388  Properties = pVariableType->Properties("Map");
2389 
2390  // check, if a value map has hat least one non property
2391  if (not Properties.begin()->second->m_NonProperties.empty())
2392  {
2393  // generate value map
2394  OutStream << "::std::map< ::oETCS::DF::VARIABLE_VALUE_VECTOR_T, ::oETCS::DF::CVariable* > STLMAP_" << GObject->second.m_OID << ";\n";
2395 
2396  // copy all non properties from value map property
2397  NonProperties = Properties.begin()->second->m_NonProperties;
2398 
2399  // process all non properties / objects
2400  for (NonProperty = NonProperties.begin(); NonProperty != NonProperties.end(); NonProperty++)
2401  {
2402  // get value of map
2403  Value = NonProperty->second->Properties("Value").begin()->second->m_Value;
2404 
2405  // generate map entry value->mapped value
2406  OutStream << "STLMAP_" << GObject->second.m_OID << "[ ::oETCS::DF::CVariable::StringToValueVector(\"" << Value << "\") ] = &VARMAP_" << NonProperty->second->m_OID << ";\n";
2407 
2408  } // for (NonProperty = NonProperties.begin(); NonProperty != NonProperties.end(); NonProperty++)
2409 
2410  } // if (not Properties.begin()->second->m_NonProperties.empty())
2411 
2412 
2413  // generate instantiation of current variable object
2414  OutStream << ::std::left << std::setw(38) << "::oETCS::DF::CVariable" << "VAR_" << GObject->second.m_OID << "(&EVC, " << Resolution;
2415 
2416  // check, which resolution unit is used
2417  if (ResolutionUnit == "m")
2418  {
2419  // generate unit parameter
2420  OutStream << ", ::oETCS::DF::CVariable::METERS";
2421 
2422  } // if (ResolutionUnit == "m")
2423  else if (ResolutionUnit == "s")
2424  {
2425  // generate unit parameter
2426  OutStream << ", ::oETCS::DF::CVariable::SECONDS";
2427 
2428  } // else if (ResolutionUnit == "s")
2429  else if (ResolutionUnit == "km/h")
2430  {
2431  // generate unit parameter
2432  OutStream << ", ::oETCS::DF::CVariable::KILO_METERS_PER_HOUR";
2433 
2434  } // else if (ResolutionUnit == "km/h")
2435  else if (ResolutionUnit == "cm")
2436  {
2437  // generate unit parameter
2438  OutStream << ", ::oETCS::DF::CVariable::CENTI_METERS";
2439 
2440  } // else if (ResolutionUnit == "s")
2441  else if (ResolutionUnit == "integer")
2442  {
2443  // generate unit parameter
2444  OutStream << ", ::oETCS::DF::CVariable::INTEGER";
2445 
2446  } // else if (ResolutionUnit == "integer")
2447  else if (ResolutionUnit == "string")
2448  {
2449  // generate unit parameter
2450  OutStream << ", ::oETCS::DF::CVariable::STRING";
2451 
2452  } // else if (ResolutionUnit == "string")
2453  else
2454  {
2455  // generate unit parameter
2456  OutStream << ", ::oETCS::DF::CVariable::DOUBLE";
2457 
2458  } // else
2459 
2460  // generate size parameter for constructor
2461  OutStream << ", " << Size;
2462 
2463 
2464  // generate parameters from conditional iterator properties
2465  OutStream << ", " << ConditionalIterator;
2466  OutStream << ", " << ConditionalValue;
2467 
2468 
2469  // check, if a value map is used
2470  if (not Properties.begin()->second->m_NonProperties.empty())
2471  {
2472  // generate value map as argument
2473  OutStream << ", " << "STLMAP_" << GObject->second.m_OID;
2474 
2475  } // if (not Properties.begin()->second->m_NonProperties.empty())
2476 
2477  // generate end of current constructor
2478  OutStream << ");\n";
2479 
2480  } // if (GObject->second.m_Type == VARIABLE_INSTANCE_OBJECT)
2481 
2482  } // for (GObject = pProject->m_ObjectSet.begin(); GObject != pProject->m_ObjectSet.end(); GObject++)
2483 
2484 
2485 
2486  // insert newlines
2487  OutStream << "\n\n\n\n";
2488 
2489 
2490  // process all packet objects
2491  for (GObject = pProject->m_ObjectSet.begin(); GObject != pProject->m_ObjectSet.end(); GObject++)
2492  {
2493  // check, if current object is a value map
2494  if (GObject->second.m_Type == PACKET_OBJECT)
2495  {
2496  // get packet ID value from current object
2497  PacketID = GObject->second.Properties("PacketID").begin()->second->m_Value;
2498 
2499  // generate initial comment for this packet object
2500  OutStream << "// Packet object " << GObject->second.m_Type << " [" << GObject->second.m_ID << "] with OID " << GObject->second.m_OID << " & " << &(GObject->second) << "\n";
2501 
2502  // check, if packet has a decomposition
2503  if (GObject->second.m_pDecomposition != 0)
2504  {
2505  // get all variable objects in decomposition
2506  Variables = GObject->second.m_pDecomposition->Objects(VARIABLE_INSTANCE_OBJECT);
2507 
2508  // generate code for vector with pointers to variable instances in this packet
2509  OutStream << "::std::vector< ::oETCS::DF::CVariable* > STLVEC_" << GObject->second.m_OID << ";\n";
2510 
2511  // process all variables
2512  for (Variable = Variables.begin(); Variable != Variables.end(); Variable++)
2513  {
2514  // generate code for adding current variable to vector
2515  OutStream << "STLVEC_" << GObject->second.m_OID << ".push_back(&VAR_" << Variable->second->m_OID << ");\n";
2516 
2517  // check, if this node is an iterator
2518  if (Variable->second->Properties("IsIterator").begin()->second->m_Value == "T")
2519  {
2520  // get all objects graphical contained by current node
2521  IteratedVariables = GObject->second.m_pDecomposition->Contained(Variable->second, false);
2522 
2523  // process all iterated objects
2524  for (Iterated = IteratedVariables.begin(); Iterated != IteratedVariables.end(); Iterated++)
2525  {
2526  // check, if current object if a variable instance
2527  if (Iterated->second->m_Type == VARIABLE_INSTANCE_OBJECT)
2528  {
2529  // generate code to add this object to iterated list of current variable
2530  OutStream << "VAR_" << Variable->second->m_OID << ".m_IteratedVariables.push_back(" << "&VAR_" << Iterated->second->m_OID << ");\n";
2531 
2532  } // if (Iterated->second->m_Type == VARIABLE_INSTANCE_OBJECT)
2533 
2534  } // for (Iterated = IteratedVariables.begin(); Iterated != IteratedVariables.end(); Iterated++)
2535 
2536  } // if (Variable->second->Properties("IsIterator").begin()->second->m_Value == "T")
2537 
2538 
2539  // get all scaling roles of current node
2540  ScalingValues = GObject->second.m_pDecomposition->Roles(Variable->second, "ScalingValue", false, false);
2541 
2542  // process all scaling roles
2543  for (ScalingValue = ScalingValues.begin(); ScalingValue != ScalingValues.end(); ScalingValue++)
2544  {
2545  // get connected role of current scaling value role
2546  ScaledValue = GObject->second.m_pDecomposition->Roles(ScalingValue->second, "ScaledValue", false, true).begin();
2547 
2548  // get connected object
2549  pScaledVariable = GObject->second.m_pDecomposition->Objects(ScaledValue->second, VARIABLE_INSTANCE_OBJECT, false, true).begin()->second;
2550 
2551  // generate code to add this object to scaled list of current variable
2552  OutStream << "VAR_" << Variable->second->m_OID << ".m_ScaledVariables.push_back(" << "&VAR_" << pScaledVariable->m_OID << ");\n";
2553 
2554  } // for (ScalingValue = ScalingValues.begin(); ScalingValue != ScalingValues.end(); ScalingValue++)
2555 
2556  } // for (Variable = Variables.begin(); Variable != Variables.end(); Variable++)
2557 
2558  } // if (GObject->second.m_pDecomposition != 0)
2559 
2560  // generate instantiation of current variable object
2561  OutStream << ::std::left << std::setw(38) << "::oETCS::DF::CPacket" << "PACK_" << GObject->second.m_OID << "(&EVC, " << PacketID
2562  << ", STLVEC_" << GObject->second.m_OID << ");\n";
2563 
2564  } // if (GObject->second.m_Type == PACKET_OBJECT)
2565 
2566  } // for (GObject = pProject->m_ObjectSet.begin(); GObject != pProject->m_ObjectSet.end(); GObject++)
2567 
2568 
2569  // insert newlines
2570  OutStream << "\n\n\n\n";
2571 
2572 
2573  // generate balise device objects
2574  for (GGraph = pProject->m_GraphSet.begin(); GGraph != pProject->m_GraphSet.end(); GGraph++)
2575  {
2576  // check, if current graph is a communication reader or sender
2577  if (GGraph->second.m_Type == COM_IN)
2578  {
2579  // clear in device names
2580  InDeviceNames.clear();
2581 
2582  // get all balise in devices in current graph
2583  BaliseInDevices = GGraph->second.Objects(BALISE_IN_DEVICE);
2584 
2585  // process all balise in devices in current graph
2586  for (BaliseInDevice = BaliseInDevices.begin(); BaliseInDevice != BaliseInDevices.end(); BaliseInDevice++)
2587  {
2588  // check, if current object has any connected out port
2589  if (not GGraph->second.Ports(BaliseInDevice->second, "telegramOutput").empty())
2590  {
2591  // generate initial comment for this balise in device object
2592  OutStream << "// Balise in device object " << BaliseInDevice->second->m_Type << " [" << BaliseInDevice->second->m_ID << "] with OID " << BaliseInDevice->second->m_OID
2593  << " in graph [" << GGraph->second.m_ID << "] with OID " << GGraph->second.m_OID << "\n";
2594 
2595  // generate vector for all telegrams used for balise in device
2596  OutStream << "::std::vector< ::oETCS::DF::CTelegram* > TELEGRAMS_" << BaliseInDevice->second->m_OID << "_" << GGraph->second.m_OID << ";\n";
2597 
2598  // get connected ports of current object
2599  OutPorts = GGraph->second.Ports(BaliseInDevice->second, "telegramOutput");
2600 
2601  // get connected out roles
2602  OutRoles = GGraph->second.Roles(BaliseInDevice->second, OutPorts.begin()->second);
2603 
2604  // process all output roles of current port/object
2605  for (OutRole = OutRoles.begin(); OutRole != OutRoles.end(); OutRole++)
2606  {
2607  // get connected in roles
2608  InRoles = GGraph->second.Roles(OutRoles.begin()->second, "DataInput");
2609 
2610  // get connected telegrams
2611  Telegrams = GGraph->second.Objects(InRoles.begin()->second);
2612 
2613  // get telegram
2614  Telegram = Telegrams.begin();
2615 
2616  // check, if telegram has a decomposition
2617  if (Telegram->second->m_pDecomposition != 0)
2618  {
2619  // store pointer to current telegram graph in pointer
2620  pTelegramGraph = Telegram->second->m_pDecomposition;
2621 
2622  // generate code for vector with pointers to variables (header
2623  OutStream << "::std::vector< ::oETCS::DF::CVariable* > VARVEC_" << Telegram->second->m_OID << "_" << GGraph->second.m_OID << ";\n";
2624 
2625  // generate code for vector with pointers to packets
2626  OutStream << "::std::vector< ::oETCS::DF::CPacket* > PACKVEC_" << Telegram->second->m_OID << "_" << GGraph->second.m_OID << ";\n";
2627 
2628  // get the leaf node object
2629  pLeafNode = pTelegramGraph->Objects("LeafNode").begin()->second;
2630 
2631  // get root node object
2632  pCurrentNode = pTelegramGraph->Objects("RootNode").begin()->second;
2633 
2634  // navigate through chain until leaf object
2635  while (pCurrentNode != pLeafNode)
2636  {
2637  // check type of current node
2638  if (pCurrentNode->m_Type == VARIABLE_INSTANCE_OBJECT)
2639  {
2640  // generate code for adding current variable object
2641  OutStream << "VARVEC_" << Telegram->second->m_OID << "_" << GGraph->second.m_OID << ".push_back(&VAR_" << pCurrentNode->m_OID << ");\n";
2642 
2643  } // if (pCurrentNode->m_Type == VARIABLE_INSTANCE_OBJECT)
2644  else if (pCurrentNode->m_Type == PACKET_OBJECT)
2645  {
2646  // generate code for adding current packet object
2647  OutStream << "PACKVEC_" << Telegram->second->m_OID << "_" << GGraph->second.m_OID << ".push_back(&PACK_" << pCurrentNode->m_OID << ");\n";
2648 
2649  } // else if (pCurrentNode->m_Type == PACKET_OBJECT)
2650  else if (pCurrentNode->m_Type == ANY_PACKET_OBJECT)
2651  {
2652  // check, if decomposition exists
2653  if (pCurrentNode->m_pDecomposition != 0)
2654  {
2655  // get all packets in any packet graph
2656  Packets = pCurrentNode->m_pDecomposition->Objects(PACKET_OBJECT);
2657 
2658  // process all packets
2659  for (Packet = Packets.begin(); Packet != Packets.end(); Packet++)
2660  {
2661  // generate code for adding current packet to vector
2662  OutStream << "PACKVEC_" << Telegram->second->m_OID << "_" << GGraph->second.m_OID << ".push_back(&PACK_" << Packet->second->m_OID << ");\n";
2663 
2664  } // for (Packet = Packets.begin(); Packet != Packets.end(); Packet++)
2665 
2666  } // if (pCurrentNode->m_pDecomposition != 0)
2667 
2668  } // else if (pCurrentNode->m_Type == ANY_PACKET_OBJECT)
2669 
2670  // navigate to previous role
2671  Previous = pTelegramGraph->Roles(pCurrentNode, "Previous", true);
2672 
2673  // navigate to next role
2674  Next = pTelegramGraph->Roles(Previous.begin()->second, "Next", true);
2675 
2676  // navigate to connected node
2677  pCurrentNode = pTelegramGraph->Objects(Next.begin()->second).begin()->second;
2678 
2679  } // while (CurrentNode != LeafNode)
2680 
2681  } // if (Telegram->second->m_pDecomposition != 0)
2682 
2683  // generate code for instantiation of current telegram
2684  OutStream << ::std::left << std::setw(38) << "::oETCS::DF::CTelegram" << "TEL_" << Telegram->second->m_OID << "_" << GGraph->second.m_OID
2685  << "(&EVC, VARVEC_" << Telegram->second->m_OID << "_" << GGraph->second.m_OID << ", PACKVEC_" << Telegram->second->m_OID << "_" << GGraph->second.m_OID
2686  << ");\n";
2687 
2688  // generate code to append current telegram to vector
2689  OutStream << "TELEGRAMS_" << BaliseInDevice->second->m_OID << "_" << GGraph->second.m_OID << ".push_back(&TEL_"
2690  << Telegrams.begin()->second->m_OID << "_" << GGraph->second.m_OID << ");\n";
2691 
2692  } // for (OutRole = OutRoles.begin(); OutRole != OutRoles.end(); OutRole++)
2693 
2694 
2695  // generate instantiation of this balise in device object
2696  OutStream << ::std::left << std::setw(38) << "::oETCS::DF::CBaliseDeviceIn" << "BALIN_" << BaliseInDevice->second->m_OID << "_" << GGraph->second.m_OID
2697  << "(TELEGRAMS_" << BaliseInDevice->second->m_OID << "_" << GGraph->second.m_OID
2698  << ", " << (BaliseInDevice->second->Properties("IsExternal").begin()->second->m_Value == "F" ? "false" : "true") << ");\n";
2699 
2700  // store current balise device object name in vector
2701  TempStream.str("");
2702  TempStream << "BALIN_" << BaliseInDevice->second->m_OID << "_" << GGraph->second.m_OID;
2703  InDeviceNames.push_back(TempStream.str());
2704 
2705  } // if (not GGraph->second.Ports(BaliseInDevice->second, "telegramOutput").empty())
2706 
2707  } // for (BaliseInDevice = BaliseInDevices.begin(); BaliseInDevice != BaliseInDevices.end(); BaliseInDevice++)
2708 
2709  // generate initial comment for this balise in device vector
2710  OutStream << "// vector of balise in devices in graph [" << GGraph->second.m_ID << "] with OID " << GGraph->second.m_OID << "\n";
2711 
2712  // generate instantiation of vector with pointers to in devices
2713  OutStream << "::std::vector< ::oETCS::DF::CBaliseDeviceIn* > INDEVICES_" << GGraph->second.m_OID << ";\n";
2714 
2715  // generate code for adding elements to vector
2716  for (x = 0; x < InDeviceNames.size(); x++)
2717  {
2718  // generate code for current device
2719  OutStream << "INDEVICES_" << GGraph->second.m_OID << ".push_back(&" << InDeviceNames[x] << ");\n";
2720 
2721  } // for (x = 0; x < InDeviceNames.size(); x++)
2722 
2723  } // if (GGraph->second.m_Type == COM_IN)
2724  else if (GGraph->second.m_Type == COM_OUT)
2725  {
2726  // clear out device names
2727  OutDeviceNames.clear();
2728 
2729  // get all balise out devices in current graph
2730  BaliseOutDevices = GGraph->second.Objects(BALISE_OUT_DEVICE);
2731 
2732  // process all balise out devices in current graph
2733  for (BaliseOutDevice = BaliseOutDevices.begin(); BaliseOutDevice != BaliseOutDevices.end(); BaliseOutDevice++)
2734  {
2735  // check, if current object has any connected in port
2736  if (not GGraph->second.Ports(BaliseOutDevice->second, "telegramInput").empty())
2737  {
2738  // generate initial comment for this balise out device object
2739  OutStream << "// Balise out device object " << BaliseOutDevice->second->m_Type << " [" << BaliseOutDevice->second->m_ID << "] with OID " << BaliseOutDevice->second->m_OID
2740  << " in graph [" << GGraph->second.m_ID << "] with OID " << GGraph->second.m_OID << "\n";
2741 
2742  // generate vector for all telegrams used for balise out device
2743  OutStream << "::std::vector< ::oETCS::DF::CTelegram* > TELEGRAMS_" << BaliseOutDevice->second->m_OID << "_" << GGraph->second.m_OID << ";\n";
2744 
2745  // get connected input roles
2746  InRoles = GGraph->second.Roles(BaliseOutDevice->second, "DataInput");
2747 
2748  // get connected out roles
2749  OutRoles = GGraph->second.Roles(OutRoles.begin()->second, "DataOutput");
2750 
2751  // get connected telegrams
2752  Telegrams = GGraph->second.Objects(OutRoles.begin()->second);
2753 
2754  // generate code to append current telegram to vector
2755  OutStream << "TELEGRAMS_" << BaliseOutDevice->second->m_OID << "_" << GGraph->second.m_OID << ".push_back(&TEL_"
2756  << Telegrams.begin()->second->m_OID << ");\n";
2757 
2758  // store current balise device object name in vector
2759  TempStream.str("");
2760  TempStream << "TELEGRAMS_" << BaliseOutDevice->second->m_OID << "_" << GGraph->second.m_OID;
2761  OutDeviceNames.push_back(TempStream.str());
2762 
2763  // TODO: add generation of code for CBaliseDeviceOut instances
2764 
2765  } // if (not GGraph->second.Ports(BaliseOutDevice->second, "telegramInput").empty())
2766 
2767  } // for (BaliseOutDevice = BaliseOutDevices.begin(); BaliseOutDevice != BaliseOutDevices.end(); BaliseOutDevice++)
2768 
2769  // generate initial comment for this balise out device vector
2770  OutStream << "// vector of balise oit devices in graph [" << GGraph->second.m_ID << "] with OID " << GGraph->second.m_OID << "\n";
2771 
2772  // generate instantiation of vector with pointers to in devices
2773  OutStream << "::std::vector< ::oETCS::DF::CBaliseDeviceOut* > OUTDEVICES_" << GGraph->second.m_OID << ";\n";
2774 
2775  // generate code for adding elements to vector
2776  for (x = 0; x < OutDeviceNames.size(); x++)
2777  {
2778  // generate code for current device
2779  OutStream << "OUTDEVICES_" << GGraph->second.m_OID << ".push_back(&" << OutDeviceNames[x] << ");\n";
2780 
2781  } // for (x = 0; x < OutDeviceNames.size(); x++)
2782 
2783  } // else if (GGraph->second.m_Type == COM_OUT)
2784 
2785  } // for (GGraph = pProject->m_GraphSet.begin(); GGraph != pProject->m_GraphSet.end(); GGraph++)
2786  // Bouml preserved body end 000A5182
2787 
2788 } // void CCPPGenerator::GenerateLanguage() throw(::GOPPRR::Error::CException)
2789 
2790 
2791 
2792 
2793 void CCPPGenerator::BuildAbstractModel(GOPPRR::CGraph * const pFunctionBlock, ::std::map< ::std::string, oETCS::GEN::CFBNode >& FBNodes) throw(::GOPPRR::Error::CException)
2794 {
2795  // Bouml preserved body begin 000E5D82
2796  decltype (::GOPPRR::CGraph::m_ObjectSet.begin()) Object;
2797  decltype (::GOPPRR::CGraph::m_RoleSet) Inputs;
2798  decltype (::GOPPRR::CGraph::m_RoleSet.begin()) Input;
2799  ::GOPPRR::CRole* pOutput(nullptr);
2800  ::GOPPRR::CObject* pOutputNode(nullptr);
2801 
2802 
2803 
2804 
2805  // process all objects in sub function block
2806  for (Object = pFunctionBlock->m_ObjectSet.begin(); Object != pFunctionBlock->m_ObjectSet.end(); Object++)
2807  {
2808  // check, if current object is a concrete function block element
2809  if (m_FBMap.find(Object->second->m_Type) != m_FBMap.end())
2810  {
2811  // add current object to node list
2812  FBNodes[Object->second->m_OID] = ::oETCS::GEN::CFBNode(Object->second->m_OID, ::oETCS::GEN::CFBNode::DEFINED);
2813 
2814  // get all input roles of current function block object
2815  Inputs = pFunctionBlock->Roles(Object->second, "DataInput", false, false);
2816 
2817  // process all inputs
2818  for (Input = Inputs.begin(); Input != Inputs.end(); Input++)
2819  {
2820  // get connected output role
2821  pOutput = pFunctionBlock->Roles(Input->second, "DataOutput", false, true).begin()->second;
2822 
2823  // get connected function block object
2824  pOutputNode = pFunctionBlock->Objects(pOutput, true).begin()->second;
2825 
2826  // add input object as undefined node in outputs
2827  FBNodes[Object->second->m_OID].m_Inputs.push_back(new ::oETCS::GEN::CFBNode(pOutputNode->m_OID, ::oETCS::GEN::CFBNode::UNDEFINED)); // TODO: handle exceptions
2828 
2829  } // for (Input = Inputs.begin(); Input != Inputs.end(); Input++)
2830 
2831  } // if (m_FBMap.find(Object->second->m_Type) != m_FBMap.end())
2832  else if (Object->second->m_Type == "SubFunction")
2833  {
2834  // check, if object has a decomposition
2835  if (Object->second->m_pDecomposition != 0)
2836  {
2837  // call this method recursively on decomposition
2838  this->BuildAbstractModel(Object->second->m_pDecomposition, FBNodes);
2839 
2840  } // if (Object->second->m_pDecomposition != 0)
2841 
2842  } // else if (Object->second->m_Type == "SubFunction")
2843 
2844  } // for (Object = pFunctionBlock->m_ObjectSet.begin(); Object != pFunctionBlock->m_ObjectSet.end(); Object++)
2845  // Bouml preserved body end 000E5D82
2846 
2847 } // void CCPPGenerator::BuildAbstractModel() throw(::GOPPRR::Error::CException)
2848 
2849 
2850 
2851 
2852 void CCPPGenerator::GenerateHeader(::std::ostream & OutStream) throw(::GOPPRR::Error::CException)
2853 
2854 {
2855  // Bouml preserved body begin 00097582
2856  ::std::time_t Now = ::std::chrono::system_clock::to_time_t(::std::chrono::system_clock::now());
2857 
2858 
2859  // output header
2860  OutStream << "/*\n"
2861  " Copyright (C) 2010-2012\n"
2862  " Johannes Feuser <feuser@uni-bremen.de>\n\n"
2863  " source generated for openETCS EVC by C++ generator\n"
2864  " time point (UTC) of generation: " << ::std::asctime(::std::gmtime(&Now)) << "\n"
2865  " */\n\n\n\n"
2866  "// include Qt header\n"
2867  "#include <QtDBus>\n"
2868  "#include <QApplication>\n"
2869  "// include the main header of the openETCS library \n"
2870  "#include \"oETCS/DF/EVCStateMachine.h\"\n"
2871  "#include \"oETCS/DF/Storage.h\"\n"
2872  "#include \"oETCS/DF/FunctionBlocks.h\"\n"
2873  "#include \"oETCS/DF/DriverMachineInterfaceMOC.h\"\n"
2874  "#include \"oETCS/DF/ControlFlow.h\"\n"
2875  "#include \"oETCS/DF/Condition.h\"\n"
2876  "#include \"oETCS/DF/Language.h\"\n"
2877  "#include \"oETCS/DF/PlatformSpecificStubsMOC.h\"\n\n\n"
2878  "int main(int argc, char* argv[])\n"
2879  "{\n"
2880  "// first create a QApplication object for widgets\n"
2881  "QApplication Application(argc, argv);\n\n\n";
2882 
2883 
2884  // Bouml preserved body end 00097582
2885 
2886 } // void CCPPGenerator::GenerateHeader() throw(::GOPPRR::Error::CException)
2887 
2888 
2889 
2890 
2891 
2892 void CCPPGenerator::GenerateFooter(::std::ostream & OutStream) throw(::GOPPRR::Error::CException)
2893 
2894 {
2895  // Bouml preserved body begin 000A5102
2896  // output footer
2897  OutStream << "return (0);\n";
2898  OutStream << "} // int main(int argc, char* argv[]\n\n";
2899  // Bouml preserved body end 000A5102
2900 
2901 } // void CCPPGenerator::GenerateFooter() throw(::GOPPRR::Error::CException)
2902 
2903 
2904 
2905 
2906 
2908 
2909 {
2910  // Bouml preserved body begin 0009A882
2911  bool bIsFunctionBlock(false);
2912  const char* pFunctionBlockTypes[] = __GENERATOR__FBTYPES__;
2913  const unsigned int NUMBER_ELEMENTS(sizeof(pFunctionBlockTypes));
2914  unsigned int x(0);
2915 
2916 
2917  // check, if pointer is valid
2918  if (pObject != 0)
2919  {
2920  // process all types names
2921  for (x = 0; x < NUMBER_ELEMENTS && !bIsFunctionBlock; x++)
2922  {
2923  // // check current name
2924  bIsFunctionBlock = (pObject->m_Type == pFunctionBlockTypes[x]);
2925 
2926  } // for (x = 0; x < NUMBER_ELEMENTS; x++)
2927 
2928  } // if (pObject != 0)
2929 
2930  // return flag
2931  return (bIsFunctionBlock);
2932  // Bouml preserved body end 0009A882
2933 
2934 } // bool CCPPGenerator::IsFunctionBlock() throw(::GOPPRR::Error::CException)
2935 
2936 
2937 
2938 
2939 
2941 
2942 {
2943  // Bouml preserved body begin 000A5082
2944  ::std::string PortType;
2945 
2946 
2947 
2948  // check, if pointer is valid
2949  if (pPort != 0)
2950  {
2951  // check for different types
2952  if (pPort->m_Type.find("bool") != std::string::npos)
2953  {
2954  // set port type to boolean
2955  PortType = "bool";
2956 
2957  } // if (pPort->m_Type.find("bool") != std::string::npos)
2958  else if (pPort->m_Type.find("doubleArray") != std::string::npos)
2959  {
2960  // set port type to double array
2961  PortType = "::std::vector< double >";
2962 
2963  } // else if (pPort->m_Type.find("doubleArray") != std::string::npos)
2964  else if (pPort->m_Type.find("double") != std::string::npos)
2965  {
2966  // set port type to double
2967  PortType = "double";
2968 
2969  } // else if (pPort->m_Type.find("double") != std::string::npos)
2970  else if (pPort->m_Type.find("int") != std::string::npos)
2971  {
2972  // set port type to integer
2973  PortType = "int";
2974 
2975  } // else if (pPort->m_Type.find("int") != std::string::npos)
2976  else if (pPort->m_Type.find("string") != std::string::npos)
2977  {
2978  // set port type to string
2979  PortType = "::std::string";
2980 
2981  } // else if (pPort->m_Type.find("string") != std::string::npos)
2982 
2983  } // if (pPort != 0)
2984 
2985 
2986  // finally return port type
2987  return (PortType);
2988  // Bouml preserved body end 000A5082
2989 
2990 } // ::std::string CCPPGenerator::TypeFromPort() throw(::GOPPRR::Error::CException)
2991 
2992 
2993 
2994 
2995 
2997 
2998 {
2999  // Bouml preserved body begin 000BE682
3000  ::std::string Prefix;
3001 
3002 
3003 
3004 
3005  // check, if pointer is valid
3006  if (pPort != 0)
3007  {
3008  // check for different types
3009  if (pPort->m_Type.find("bool") != std::string::npos)
3010  {
3011  // set prefix
3012  Prefix = "b";
3013 
3014  } // if (pPort->m_Type.find("bool") != std::string::npos)
3015  else if (pPort->m_Type.find("doubleArray") != std::string::npos)
3016  {
3017  // set prefix
3018  Prefix = "";
3019 
3020  } // else if (pPort->m_Type.find("doubleArray") != std::string::npos)
3021  else if (pPort->m_Type.find("double") != std::string::npos)
3022  {
3023  // set prefix
3024  Prefix = "d";
3025 
3026  } // else if (pPort->m_Type.find("double") != std::string::npos)
3027  else if (pPort->m_Type.find("int") != std::string::npos)
3028  {
3029  // set prefix
3030  Prefix = "i";
3031 
3032  } // else if (pPort->m_Type.find("int") != std::string::npos)
3033  else if (pPort->m_Type.find("string") != std::string::npos)
3034  {
3035  // set prefix
3036  Prefix = "";
3037 
3038  } // else if (pPort->m_Type.find("string") != std::string::npos)
3039  else
3040  {
3041  // set prefix
3042  Prefix = "";
3043 
3044  } // else
3045 
3046  } // if (pPort != 0)
3047 
3048 
3049  // finally return port type
3050  return (Prefix);
3051  // Bouml preserved body end 000BE682
3052 
3053 } // ::std::string CCPPGenerator::PrefixFromPort() throw(::GOPPRR::Error::CException)
3054 
3055 
3056 
3057 
3058 
3059 void CCPPGenerator::ProcessAbstractModel(const oETCS::GEN::CFBNode & Node, ::std::list< ::std::string >& ExecutionOrder, ::std::vector< const oETCS::GEN::CFBNode * >& NodeStack) throw()
3060 
3061 {
3062  // Bouml preserved body begin 000E5D02
3063  decltype (Node.m_Inputs.begin()) i;
3064  decltype (ExecutionOrder.begin()) s;
3065  decltype (NodeStack.begin()) ns;
3066  bool bFound(false);
3067  bool bOnStack(false);
3068 
3069 
3070  // check, if this node is already on node stack
3071  for (ns = NodeStack.begin(); ns != NodeStack.end() && not bOnStack; ns++)
3072  {
3073  // check, if current node on stack is current node
3074  bOnStack = (*ns == &Node);
3075 
3076  } // for (ns = NodeStack.begin(); ns != NodeStack.end() && not bOnStack; ns++)
3077 
3078 
3079  // only process node, if it is not on stack to avoid infinite recursions on data flow loops
3080  if (not bOnStack)
3081  {
3082  // check, if current node already exists on execution order stack
3083  for (s = ExecutionOrder.begin(); s != ExecutionOrder.end() && not bFound; s++)
3084  {
3085  // check, if current stack element corresponds to current node's OID
3086  bFound = (*s == Node.m_OID);
3087 
3088  } // for (s = ExecutionOrder.begin(); s != ExecutionOrder.end() && not bFound; s++)
3089 
3090 
3091  // check, if node has any input
3092  if (Node.m_Inputs.empty())
3093  {
3094  // check, if node is already on stack
3095  if (not bFound)
3096  {
3097  // node is a flow-chain start point and is directly added to the execution order
3098  ExecutionOrder.push_back(Node.m_OID);
3099 
3100  } // if (not bFound)
3101 
3102  } // if (Node.m_Inputs.empty())
3103  else
3104  {
3105  // process all input nodes
3106  for (i = Node.m_Inputs.begin(); i != Node.m_Inputs.end(); i++)
3107  {
3108  // place current node on stack
3109  NodeStack.push_back(&Node);
3110 
3111  // call this method recursively for current node
3112  ::oETCS::GEN::CCPPGenerator::ProcessAbstractModel((**i), ExecutionOrder, NodeStack);
3113 
3114  // remove node again from stack
3115  NodeStack.pop_back();
3116 
3117  } // for (i = Node.m_Inputs.begin(); i != Node.m_Inputs.end(); i++)
3118 
3119  // check, if node is already on stack
3120  if (not bFound)
3121  {
3122  // add current node after all inputs node on execution order stack
3123  ExecutionOrder.push_back(Node.m_OID);
3124 
3125  } // if (not bFound)
3126 
3127  } // else
3128 
3129  } // if (not bOnStack)
3130  // Bouml preserved body end 000E5D02
3131 
3132 } // void CCPPGenerator::ProcessAbstractModel() throw()
3133 
3134 
3135 
3136 
3137 
3138 
3139 
3140 } // namespace oETCS::GEN
3141 
3142 } // namespace oETCS

Copyright (C) 2010-2012 Johannes Feuser (feuser@uni-bremen.de)
The openETCS library is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or any later version.
The openETCS library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with the openETCS library. If not, see "http://www.gnu.org/licenses/.