diff --git a/AlgebraicDataflowArchitectureModel/src/generators/CodeGeneratorFromDataFlowGraph.java b/AlgebraicDataflowArchitectureModel/src/generators/CodeGeneratorFromDataFlowGraph.java index 8d981e6..59930d9 100644 --- a/AlgebraicDataflowArchitectureModel/src/generators/CodeGeneratorFromDataFlowGraph.java +++ b/AlgebraicDataflowArchitectureModel/src/generators/CodeGeneratorFromDataFlowGraph.java @@ -173,7 +173,7 @@ } // Declare the fields to refer to other resources in the parent/this component, and the state field in the parent component. - declareFieldsToReferToOtherResourcesAndStateFieldInParentComponent(resourceNode, component, parentComponent, constructorParams, langSpec); + boolean bDeclareClientField = declareFieldsToReferToOtherResourcesAndStateFieldInParentComponent(resourceNode, component, parentComponent, constructorParams, platformSpec, langSpec); // (#2) Declare the getter method to obtain the resource state in an ancestor resource. (complementary to #1) if (component == null) { @@ -479,10 +479,11 @@ } } - private void declareFieldsToReferToOtherResourcesAndStateFieldInParentComponent(ResourceNode resourceNode, TypeDeclaration component, TypeDeclaration parentComponent, - Map> constructorParams, ILanguageSpecific langSpec) { + private boolean declareFieldsToReferToOtherResourcesAndStateFieldInParentComponent(ResourceNode resourceNode, TypeDeclaration component, TypeDeclaration parentComponent, + Map> constructorParams, IPlatformSpecific platformSpec, ILanguageSpecific langSpec) { // Declare reference fields for push data transfer. boolean noPullTransfer = true; + boolean bDeclareClientField = false; for (Edge resToCh : resourceNode.getOutEdges()) { DataFlowEdge re = (DataFlowEdge) resToCh; ChannelNode directDstChNode = (ChannelNode) re.getDestination(); @@ -616,6 +617,13 @@ } } } + if (!platformSpec.isMonolithic()) { + if (!bDeclareClientField) { + // Declare a client field to connect to the destination resource of push transfer. + platformSpec.addClientFieldDeclaration(parentComponent); + bDeclareClientField = true; + } + } } } } @@ -623,9 +631,23 @@ } // Declare reference fields for pull data transfer. for (Edge chToRes : resourceNode.getInEdges()) { - for (Edge resToCh: chToRes.getSource().getInEdges()) { + ChannelNode directSrcChNode = (ChannelNode) chToRes.getSource(); + DataTransferChannel directSrcCh = directSrcChNode.getChannel(); + // Should take into account the channel hierarchy. + Set ancestorSrcChannels = directSrcChNode.getAncestors(); + Set descendantSrcChannels = directSrcChNode.getDescendants(); + Set inEdges = new HashSet<>(); + inEdges.addAll(directSrcChNode.getInEdges()); + for (ChannelNode ancestorSrc: ancestorSrcChannels) { + inEdges.addAll(ancestorSrc.getInEdges()); + } + for (ChannelNode descendantSrc: descendantSrcChannels) { + inEdges.addAll(descendantSrc.getInEdges()); + } + for (Edge resToCh: inEdges) { DataFlowEdge re = (DataFlowEdge) resToCh; - DataTransferChannel ch = ((ChannelNode) re.getDestination()).getChannel(); + ChannelNode chNode = (ChannelNode) re.getDestination(); + DataTransferChannel ch = chNode.getChannel(); ResourcePath srcRes = ((ResourceNode) re.getSource()).getOutSideResource(ch); // Check if the source resource is outside of the channel scope. boolean outsideInputResource = false; @@ -643,6 +665,13 @@ break; } } + // Also take into account the channel hierarchy to determine push/pull transfer. + if (descendantSrcChannels.contains(chNode)) { + outsideInputResource = true; // Regarded as (collecting) pull transfer. + } + if (ancestorSrcChannels.contains(chNode)) { + outsideOutputResource = true; // Regarded as (broadcasting) push transfer. + } if ((((PushPullAttribute) re.getAttribute()).getSelectedOption() != PushPullValue.PUSH && !outsideOutputResource) || outsideInputResource) { noPullTransfer = false; // Declare a field in the parent/this component to refer to the source resource of pull transfer. @@ -734,6 +763,13 @@ } } } + if (!platformSpec.isMonolithic()) { + if (!bDeclareClientField) { + // Declare a client field to connect to the destination resource of push transfer. + platformSpec.addClientFieldDeclaration(parentComponent); + bDeclareClientField = true; + } + } } } } @@ -764,6 +800,7 @@ } } } + return bDeclareClientField; }