Skip to content
GitLab
Menu
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
monticore
EmbeddedMontiArc
generators
EMAM2Cpp
Commits
c1a4ce0d
Commit
c1a4ce0d
authored
Oct 22, 2018
by
Nils Kaminski
Browse files
Dynamic port (request) connection
parent
3a4a1d5f
Changes
8
Hide whitespace changes
Inline
Side-by-side
src/main/java/de/monticore/lang/monticar/generator/cpp/BluePrintFixer.java
View file @
c1a4ce0d
...
...
@@ -2,6 +2,7 @@ package de.monticore.lang.monticar.generator.cpp;
import
de.monticore.lang.monticar.generator.BluePrint
;
import
de.monticore.lang.monticar.generator.Variable
;
import
de.monticore.lang.monticar.generator.cpp.symbols.MathStringExpression
;
import
de.se_rwth.commons.logging.Log
;
import
java.util.*
;
...
...
@@ -40,10 +41,14 @@ public class BluePrintFixer {
}
if
(
isDynamic
){
newVars
.
add
(
addConnectedVariableForVariable
(
varList
,
nameWithoutArray
,
bluePrint
));
newVars
.
add
(
addConnectedRequestQueueForVariable
(
nameWithoutArray
,
bluePrint
));
}
});
//TODO: Generate vectors with output functionality
// std::vector<connection<bool>> dynamic_bool_connection_IN;
// std::vector<connection<bool>> dynamic_bool_connection_OUT;
bluePrint
.
setVariables
(
newVars
);
}
...
...
@@ -51,21 +56,31 @@ public class BluePrintFixer {
protected
static
Variable
addConnectedVariableForVariable
(
List
<
Variable
>
varList
,
String
nameWithoutArray
,
BluePrint
bluePrint
){
Log
.
info
(
"Adding __connected variable for "
+
nameWithoutArray
,
"Dynamic Connected Variable"
);
String
s
=
"["
;
for
(
int
i
=
0
;
i
<
varList
.
size
();
++
i
){
s
+=
varList
.
get
(
i
).
isDynamic
()
?
"false"
:
"true"
;
if
(
i
<
varList
.
size
()-
1
){
s
+=
", "
;
}
}
s
+=
"]"
;
Variable
variable
=
new
Variable
();
variable
.
setName
(
"__"
+
nameWithoutArray
+
"_connected"
);
VariableConstantArray
variable
=
new
VariableConstantArray
(
"__"
+
nameWithoutArray
+
"_connected"
);
variable
.
addAdditionalInformation
(
Variable
.
ORIGINPORT
);
variable
.
setArraySize
(
varList
.
size
());
variable
.
setTypeNameTargetLanguage
(
"bool"
);
variable
.
setIsConstantVariable
(
true
);
variable
.
setConstantValue
(
s
);
// variable.setIsConstantVariable(true);
// variable.setConstantValue(s);
variable
.
setPublic
(
false
);
for
(
int
i
=
0
;
i
<
varList
.
size
();
++
i
){
variable
.
addConstantInitValue
(
varList
.
get
(
i
).
isDynamic
()
?
"false"
:
"true"
);
}
bluePrint
.
getMathInformationRegister
().
addVariable
(
variable
);
return
variable
;
}
protected
static
Variable
addConnectedRequestQueueForVariable
(
String
nameWithoutArray
,
BluePrint
bluePrint
){
Log
.
info
(
"Adding __connect_request variable for "
+
nameWithoutArray
,
"Dynamic Request Connect Queue for Variable"
);
Variable
variable
=
new
Variable
();
variable
.
setName
(
"__"
+
nameWithoutArray
+
"_connect_request"
);
variable
.
setTypeNameTargetLanguage
(
"std::queue<int>"
);
variable
.
setPublic
(
false
);
bluePrint
.
getMathInformationRegister
().
addVariable
(
variable
);
...
...
src/main/java/de/monticore/lang/monticar/generator/cpp/VariableConstantArray.java
0 → 100644
View file @
c1a4ce0d
package
de.monticore.lang.monticar.generator.cpp
;
import
de.monticore.lang.monticar.generator.Method
;
import
de.monticore.lang.monticar.generator.TargetCodeInstruction
;
import
de.monticore.lang.monticar.generator.Variable
;
import
java.util.ArrayList
;
import
java.util.List
;
public
class
VariableConstantArray
extends
Variable
{
protected
List
<
String
>
values
=
new
ArrayList
<>();
public
VariableConstantArray
(
String
name
){
super
();
this
.
setName
(
name
);
}
@Override
public
boolean
isConstantVariable
()
{
return
true
;
}
@Override
public
String
getConstantValue
()
{
return
String
.
join
(
", "
,
values
);
}
public
void
generateInit
(
Method
initMethod
){
for
(
int
i
=
0
;
i
<
this
.
getArraySize
();
++
i
){
if
(
i
<
values
.
size
()){
initMethod
.
addInstruction
(
new
TargetCodeInstruction
(
String
.
format
(
"%s[%d] = %s;\n"
,
this
.
getName
(),
i
,
values
.
get
(
i
))
));
}
}
}
public
void
addConstantInitValue
(
String
value
){
values
.
add
(
value
);
}
}
src/main/java/de/monticore/lang/monticar/generator/cpp/converter/ComponentConverter.java
View file @
c1a4ce0d
...
...
@@ -73,6 +73,8 @@ public class ComponentConverter {
Method
execute
=
ComponentConverterMethodGeneration
.
generateExecuteMethod
(
componentSymbol
,
bluePrint
,
mathStatementsSymbol
,
generatorCPP
,
includeStrings
);
Method
init
=
generateInitMethod
(
componentSymbol
,
bluePrint
,
generatorCPP
,
includeStrings
);
EventConverter
.
generateEvents
(
execute
,
componentSymbol
,
bluePrint
,
mathStatementsSymbol
,
generatorCPP
,
includeStrings
);
bluePrint
.
addMethod
(
init
);
bluePrint
.
addMethod
(
execute
);
...
...
@@ -130,8 +132,10 @@ public class ComponentConverter {
for
(
Variable
v
:
bluePrint
.
getVariables
())
{
Log
.
info
(
"Variable: "
+
v
.
getName
(),
"initBluePrintCreate:"
);
if
(
v
instanceof
VariablePortValueChecker
){
((
VariablePortValueChecker
)
v
).
addInitInstructionsToMethod
(
method
);
if
(
v
instanceof
VariablePortValueChecker
)
{
((
VariablePortValueChecker
)
v
).
addInitInstructionsToMethod
(
method
);
}
else
if
(
v
instanceof
VariableConstantArray
){
((
VariableConstantArray
)
v
).
generateInit
(
method
);
}
else
{
if
(
v
.
isInputVariable
()
&&
!
v
.
isConstantVariable
())
{
//method.addParameter(v);
...
...
src/main/java/de/monticore/lang/monticar/generator/cpp/converter/ComponentConverterMethodGeneration.java
View file @
c1a4ce0d
...
...
@@ -67,7 +67,7 @@ public class ComponentConverterMethodGeneration {
Collection
<
EMAConnectorInstanceSymbol
>
connectors
=
componentSymbol
.
getConnectorInstances
();
generateConnectors
(
connectors
,
bluePrint
,
method
);
EventConverter
.
generateEventConnectors
(
method
,
componentSymbol
,
bluePrint
,
mathStatementsSymbol
,
generatorCPP
,
includeStrings
);
if
(
mathStatementsSymbol
!=
null
)
{
handleMathStatementGeneration
(
method
,
bluePrint
,
mathStatementsSymbol
,
generatorCPP
,
includeStrings
);
...
...
src/main/java/de/monticore/lang/monticar/generator/cpp/converter/EventConverter.java
View file @
c1a4ce0d
...
...
@@ -6,16 +6,11 @@ import de.monticore.lang.embeddedmontiarc.embeddedmontiarc._symboltable.instance
import
de.monticore.lang.embeddedmontiarcdynamic.embeddedmontiarcdynamic._symboltable.instanceStructure.EMADynamicComponentInstanceSymbol
;
import
de.monticore.lang.embeddedmontiarcdynamic.embeddedmontiarcdynamic._symboltable.instanceStructure.EMADynamicConnectorInstanceSymbol
;
import
de.monticore.lang.embeddedmontiarcdynamic.embeddedmontiarcdynamic._symboltable.instanceStructure.EMADynamicEventHandlerInstanceSymbol
;
import
de.monticore.lang.embeddedmontiarcdynamic.event._symboltable.expression.EventBracketExpressionSymbol
;
import
de.monticore.lang.embeddedmontiarcdynamic.event._symboltable.expression.EventExpressionSymbol
;
import
de.monticore.lang.embeddedmontiarcdynamic.event._symboltable.expression.EventLogicalOperationExpressionSymbol
;
import
de.monticore.lang.embeddedmontiarcdynamic.event._symboltable.expression.EventPortExpressionValueSymbol
;
import
de.monticore.lang.embeddedmontiarcdynamic.embeddedmontiarcdynamic._symboltable.instanceStructure.EMADynamicPortInstanceSymbol
;
import
de.monticore.lang.embeddedmontiarcdynamic.event._symboltable.expression.*
;
import
de.monticore.lang.embeddedmontiarcdynamic.event._symboltable.expression.portvalueexpressionvalues.*
;
import
de.monticore.lang.math._symboltable.MathStatementsSymbol
;
import
de.monticore.lang.monticar.generator.Instruction
;
import
de.monticore.lang.monticar.generator.Method
;
import
de.monticore.lang.monticar.generator.TargetCodeInstruction
;
import
de.monticore.lang.monticar.generator.Variable
;
import
de.monticore.lang.monticar.generator.*
;
import
de.monticore.lang.monticar.generator.cpp.BluePrintCPP
;
import
de.monticore.lang.monticar.generator.cpp.GeneratorCPP
;
import
de.monticore.lang.monticar.generator.cpp.VariablePortValueChecker
;
...
...
@@ -23,13 +18,14 @@ import de.monticore.lang.monticar.generator.cpp.instruction.ConnectInstructionCP
import
de.monticore.lang.monticar.generator.cpp.instruction.EventConnectInstructionCPP
;
import
de.se_rwth.commons.logging.Log
;
import
java.util.ArrayList
;
import
java.util.Collection
;
import
java.util.List
;
import
java.util.Optional
;
public
class
EventConverter
{
public
static
void
generateEvent
Connector
s
(
Method
m
ethod
,
EMAComponentInstanceSymbol
componentSymbol
,
BluePrintCPP
bluePrint
,
MathStatementsSymbol
mathStatementsSymbol
,
GeneratorCPP
generatorCPP
,
List
<
String
>
includeStrings
){
public
static
void
generateEvents
(
Method
executeM
ethod
,
EMAComponentInstanceSymbol
componentSymbol
,
BluePrintCPP
bluePrint
,
MathStatementsSymbol
mathStatementsSymbol
,
GeneratorCPP
generatorCPP
,
List
<
String
>
includeStrings
){
if
(!(
componentSymbol
instanceof
EMADynamicComponentInstanceSymbol
)){
return
;
}
...
...
@@ -37,33 +33,99 @@ public class EventConverter {
for
(
EMADynamicEventHandlerInstanceSymbol
event
:
dynComponent
.
getEventHandlers
()){
Log
.
info
(
"Create
connectors for
: "
+
event
.
get
Full
Name
(),
"EventConverter"
);
Log
.
info
(
"Create
Event
: "
+
event
.
getName
(),
"EventConverter"
);
int
number
=
0
;
for
(
EMADynamicConnectorInstanceSymbol
connector
:
event
.
getConnectorsDynamic
()){
if
(
connector
.
isDynamicSourceNewComponent
()
||
connector
.
isDynamicSourceNewPort
()
||
connector
.
isDynamicTargetNewComponent
()
||
connector
.
isDynamicTargetNewPort
()){
continue
;
}
boolean
generateCondition
=
false
;
generateEventConnector
(
event
.
getFullName
(),
connector
,
bluePrint
,
method
);
++
number
;
if
(
event
.
isDynamicPortConnectionEvent
())
{
//TODO generate dynamic event
generateCondition
=
generateDynamicConnectEvent
(
event
,
componentSymbol
,
executeMethod
,
bluePrint
);
}
else
{
Log
.
info
(
"Create connectors for: "
+
event
.
getFullName
(),
"EventConverter"
);
generateCondition
=
generateValueEvent
(
event
,
executeMethod
,
bluePrint
);
}
if
(
number
>
0
)
{
if
(
generateCondition
)
{
//generate event condition method
Method
condition
=
new
Method
(
EventConnectInstructionCPP
.
getEventNameCPP
(
event
.
getFullName
()),
"bool"
);
condition
.
setPublic
(
false
);
generateEventConditionMethod
(
event
,
componentSymbol
,
bluePrint
);
}
}
}
protected
static
void
generateEventConditionMethod
(
EMADynamicEventHandlerInstanceSymbol
event
,
EMAComponentInstanceSymbol
componentSymbol
,
BluePrintCPP
bluePrint
){
Method
condition
=
new
Method
(
EventConnectInstructionCPP
.
getEventNameCPP
(
event
.
getFullName
()),
"bool"
);
condition
.
setPublic
(
false
);
String
conditionExpression
=
"return "
;
conditionExpression
+=
generateEventCondition
(
event
.
getCondition
(),
componentSymbol
,
bluePrint
);
conditionExpression
+=
";\n"
;
String
conditionExpression
=
"return "
;
conditionExpression
+=
generateEventCondition
(
event
.
getCondition
(),
componentSymbol
,
bluePrint
);
conditionExpression
+=
";\n"
;
condition
.
addInstruction
(
new
TargetCodeInstruction
(
conditionExpression
));
bluePrint
.
addMethod
(
condition
);
}
condition
.
addInstruction
(
new
TargetCodeInstruction
(
conditionExpression
));
bluePrint
.
addMethod
(
condition
);
protected
static
boolean
generateValueEvent
(
EMADynamicEventHandlerInstanceSymbol
event
,
Method
executeMethod
,
BluePrintCPP
bluePrint
){
int
number
=
0
;
for
(
EMADynamicConnectorInstanceSymbol
connector
:
event
.
getConnectorsDynamic
()){
if
(
connector
.
isDynamicSourceNewComponent
()
||
connector
.
isDynamicSourceNewPort
()
||
connector
.
isDynamicTargetNewComponent
()
||
connector
.
isDynamicTargetNewPort
()){
continue
;
}
generateEventConnector
(
event
.
getFullName
(),
connector
,
bluePrint
,
executeMethod
);
++
number
;
}
return
number
>
0
;
}
protected
static
boolean
generateDynamicConnectEvent
(
EMADynamicEventHandlerInstanceSymbol
event
,
EMAComponentInstanceSymbol
componentSymbol
,
Method
executeMethod
,
BluePrintCPP
bluePrint
)
{
List
<
String
>
names
=
new
ArrayList
<>();
event
.
getCondition
().
getConnectPortNames
(
names
);
java
.
util
.
Collections
.
sort
(
names
);
String
connectMethodName
=
"connect_"
+
String
.
join
(
"_"
,
names
);
if
(!
bluePrint
.
getMethod
(
connectMethodName
).
isPresent
()){
generateConnectMethod
(
connectMethodName
,
names
,
componentSymbol
,
bluePrint
);
}
//TODO generate event body method
return
true
;
}
protected
static
void
generateConnectMethod
(
String
name
,
List
<
String
>
names
,
EMAComponentInstanceSymbol
componentSymbol
,
BluePrintCPP
bluePrint
){
Log
.
info
(
"Create connect method: "
+
name
+
"(...)"
,
"EventConverter"
);
Method
method
=
new
Method
(
name
,
"bool"
);
List
<
String
>
checks
=
new
ArrayList
<>();
for
(
String
n
:
names
){
Variable
v
=
new
Variable
();
v
.
setName
(
n
+
"_indexref"
);
v
.
setTypeNameTargetLanguage
(
"int*"
);
method
.
addParameter
(
v
);
long
counter
=
componentSymbol
.
getPortInstanceList
().
stream
().
filter
(
p
->
p
.
getNameWithoutArrayBracketPart
().
equals
(
n
)).
count
();
String
inst
=
String
.
format
(
"*%s_indexref = dynamicconnect(%d, __%s_connected, &__%s_connect_request);\n"
,
n
,
counter
,
n
,
n
);
method
.
addInstruction
(
new
TargetCodeInstruction
(
inst
)
);
checks
.
add
(
String
.
format
(
"(*%s_indexref < 0)"
,
n
));
}
method
.
addInstruction
(
new
TargetCodeInstruction
(
String
.
format
(
"if(%s){return false;}\n"
,
String
.
join
(
" || "
,
checks
))
));
method
.
addInstruction
(
new
TargetCodeInstruction
(
"return true;\n"
));
bluePrint
.
addAdditionalIncludeString
(
"DynamicHelper"
);
bluePrint
.
addMethod
(
method
);
}
public
static
void
generatePVCNextMethod
(
BluePrintCPP
bluePrint
){
Method
next
=
new
Method
(
"next"
,
"void"
);
next
.
setPublic
(
false
);
...
...
@@ -114,6 +176,8 @@ public class EventConverter {
}
}
//<editor-fold desc="Generate event condition">
protected
static
String
generateEventCondition
(
EventExpressionSymbol
expression
,
EMAComponentInstanceSymbol
componentSymbol
,
BluePrintCPP
bluePrint
){
if
(
expression
instanceof
EventBracketExpressionSymbol
){
return
"( "
+
generateEventCondition
(((
EventBracketExpressionSymbol
)
expression
).
getInnerExpression
(),
componentSymbol
,
bluePrint
)+
" )"
;
...
...
@@ -121,6 +185,8 @@ public class EventConverter {
return
generateEventConditionEventLogicalExpressionSymbol
((
EventLogicalOperationExpressionSymbol
)
expression
,
componentSymbol
,
bluePrint
);
}
else
if
(
expression
instanceof
EventPortExpressionValueSymbol
){
return
generateEventConditionEventPortValueSymbol
((
EventPortExpressionValueSymbol
)
expression
,
componentSymbol
,
bluePrint
);
}
else
if
(
expression
instanceof
EventPortExpressionConnectSymbol
){
return
generateEventConditionEventPortConnectSymbol
((
EventPortExpressionConnectSymbol
)
expression
,
componentSymbol
,
bluePrint
);
}
return
""
;
...
...
@@ -143,7 +209,6 @@ public class EventConverter {
protected
static
String
generateEventConditionEventPortValueSymbol
(
EventPortExpressionValueSymbol
expressionValueSymbol
,
EMAComponentInstanceSymbol
componentSymbol
,
BluePrintCPP
bluePrint
){
// Variable v = new Variable()
VariablePortValueChecker
pvc
=
new
VariablePortValueChecker
(
expressionValueSymbol
.
getName
());
bluePrint
.
addVariable
(
pvc
);
...
...
@@ -153,13 +218,18 @@ public class EventConverter {
pvc
.
setVariableType
(
TypeConverter
.
getVariableTypeForMontiCarTypeName
(
typeNameMontiCar
,
pvc
,
portSymbol
.
get
()).
get
());
}
addTest
(
expressionValueSymbol
.
getPortValue
(),
pvc
);
return
pvc
.
getNameTargetLanguageFormat
()+
".check()"
;
}
protected
static
String
generateEventConditionEventPortConnectSymbol
(
EventPortExpressionConnectSymbol
expressionConnectSymbol
,
EMAComponentInstanceSymbol
componentSymbol
,
BluePrint
bluePrint
){
return
"(!__"
+
expressionConnectSymbol
.
getName
()+
"_connect_request.empty())"
;
}
//</editor-fold>
//<editor-fold desc="Generate concrete test for port values">
public
static
void
addTest
(
PortValueSymbol
pvs
,
VariablePortValueChecker
vpvc
){
...
...
src/main/resources/template/dynamics/dynamic_port_request_connect_helper_h.ftl
0 → 100644
View file @
c1a4ce0d
#
ifndef
Dynamic_Connect_Helper_h
#
define
Not_h
#
include
<queue>
#
include
<vector>
#
ifndef
CONNECTION_H
#
define
CONNECTION_H
template
<
typename
T>
struct
connection
{
T
*
from
;
T
*
to
;
}
;
#
endif
int
dynamicconnect(int numPorts, bool
*
connected)
{
int
port
=
-1
;
for
(
port
=
0
;
port
<
numPorts
;
++
port
)
{
if
(
!
connected
[
port
]
)
{
break
;
}
}
if
(
port
>=
numPorts
)
{
//
no
free
ports
return
-1
;
}
connected
[
port
]
= true;
return
port
;
}
int
dynamicconnect(int numPorts, bool
*
connected, std::queue<int>
*
request)
{
int
port
=
dynamicconnect
(
numPorts
,
connected
)
;
if
(
port
>=
0
){
request-
>
push
(
port
)
;
}
return
port
;
}
#
endif
/
*
Dynamic_Connect_Helper_h
*
/
\ No newline at end of file
src/test/java/de/monticore/lang/monticar/generator/dynamics/DynamicPortConnectionGenerationTest.java
0 → 100644
View file @
c1a4ce0d
package
de.monticore.lang.monticar.generator.dynamics
;
import
de.monticore.lang.embeddedmontiarc.embeddedmontiarc._symboltable.instanceStructure.EMAComponentInstanceSymbol
;
import
de.monticore.lang.monticar.generator.AbstractSymtabTest
;
import
de.monticore.lang.monticar.generator.cpp.GeneratorCPP
;
import
de.monticore.lang.tagging._symboltable.TaggingResolver
;
import
de.se_rwth.commons.logging.Log
;
import
org.junit.BeforeClass
;
import
org.junit.Test
;
import
java.io.File
;
import
java.io.IOException
;
import
java.util.List
;
import
static
org
.
junit
.
Assert
.
assertNotNull
;
public
class
DynamicPortConnectionGenerationTest
extends
AbstractSymtabTest
{
@BeforeClass
public
static
void
setUp
()
{
// ensure an empty log
Log
.
getFindings
().
clear
();
Log
.
enableFailQuick
(
false
);
}
@Test
public
void
Test_01_PortRequest1
()
throws
IOException
{
TaggingResolver
symtab
=
createSymTabAndTaggingResolver
(
"src/test/resources/dynamics"
);
EMAComponentInstanceSymbol
componentSymbol
=
symtab
.<
EMAComponentInstanceSymbol
>
resolve
(
"portRequest.portRequest1"
,
EMAComponentInstanceSymbol
.
KIND
).
orElse
(
null
);
assertNotNull
(
componentSymbol
);
GeneratorCPP
generatorCPP
=
new
GeneratorCPP
();
generatorCPP
.
useArmadilloBackend
();
generatorCPP
.
setGenerationTargetPath
(
"./target/generated-sources-cpp/dynamics/DynamicPortConnectionGenerationTest_Test_01_PortRequest1"
);
List
<
File
>
files
=
generatorCPP
.
generateFiles
(
symtab
,
componentSymbol
,
symtab
);
files
.
stream
().
forEach
(
f
->
System
.
out
.
println
(
"Generated: "
+
f
.
getName
()));
}
}
src/test/resources/dynamics/portRequest/PortRequest1.emam
0 → 100644
View file @
c1a4ce0d
package
portRequest
;
dynamic
component
PortRequest1
{
ports
dynamic
in
B
a
[
2
:
8
],
dynamic
out
B
b
[
3
:
8
];
connect
a
[
1
]
->
b
[
1
];
connect
a
[
2
]
->
b
[
2
];
@
b
::
connect
&&
a
::
connect
{
connect
a
[?]
->
b
[?];
}
}
\ No newline at end of file
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment