@@ -192,11 +192,22 @@ private void UpdateNodes()
192192
193193 private GraphPortModel ? FindPort ( Connection connection )
194194 {
195- return FindNodeModel ( connection . Parent ) ? . Ports
195+ var nodePort = FindNodeModel ( connection . Parent ) ? . Ports
196+ . OfType < GraphPortModel > ( )
197+ . FirstOrDefault ( x => x . Connection == connection ) ;
198+ if ( nodePort != null )
199+ return nodePort ;
200+
201+ return Diagram . Groups
202+ . SelectMany ( x => x . Ports )
196203 . OfType < GraphPortModel > ( )
197204 . FirstOrDefault ( x => x . Connection == connection ) ;
198205 }
199206
207+ private LambdaGroupModel ? FindLambdaGroup ( string ? bodyScopeId ) => Diagram . Groups
208+ . OfType < LambdaGroupModel > ( )
209+ . FirstOrDefault ( x => x . DelegateNode . BodyScopeId == bodyScopeId ) ;
210+
200211 #endregion
201212
202213 #region Events from client
@@ -418,6 +429,9 @@ private static void OnLambdaGroupMoved(MovableModel movableModel)
418429 if ( movableModel is not LambdaGroupModel group )
419430 return ;
420431
432+ var groupDecoration = group . DelegateNode . GetOrAddDecoration < NodeDecorationPosition > ( ( ) => new ( Vector2 . Zero ) ) ;
433+ groupDecoration . Position = new ( ( float ) group . Position . X , ( float ) group . Position . Y ) ;
434+
421435 foreach ( var nodeModel in group . GetDescendantNodeModels ( ) )
422436 {
423437 var decoration = nodeModel . Node . GetOrAddDecoration < NodeDecorationPosition > ( ( ) => new ( Vector2 . Zero ) ) ;
@@ -754,6 +768,23 @@ public void ToggleBreakpointOnSelectedNode()
754768
755769 public void RemoveNode ( Node node )
756770 {
771+ if ( node is LambdaReturnNode { IsImplicit : true } boundaryReturn )
772+ {
773+ var group = FindLambdaGroup ( boundaryReturn . CallableScopeId ) ;
774+ if ( group != null )
775+ {
776+ foreach ( var port in group . Ports
777+ . OfType < GraphPortModel > ( )
778+ . Where ( x => x . Connection . Parent == boundaryReturn )
779+ . ToList ( ) )
780+ {
781+ group . RemovePort ( port ) ;
782+ }
783+ group . Refresh ( ) ;
784+ }
785+ return ;
786+ }
787+
757788 var nodeModel = FindNodeModel ( node ) ;
758789 if ( nodeModel == null )
759790 return ;
@@ -832,6 +863,8 @@ public void AddNode(Node node)
832863 {
833864 if ( node is CreateDelegateNode delegateNode )
834865 AddLambdaGroupModel ( delegateNode ) ;
866+ else if ( node is LambdaReturnNode { IsImplicit : true } boundaryReturn )
867+ AddBoundaryReturnToGroup ( boundaryReturn ) ;
835868 else
836869 AddGraphNodeModel ( node ) ;
837870
@@ -859,10 +892,11 @@ private void EnsureInitialScopedPosition(Node node)
859892 return ;
860893
861894 var ownerPosition = owner . GetOrAddDecoration < NodeDecorationPosition > ( ( ) => new ( Vector2 . Zero ) ) . Position ;
895+ var groupPadding = FindLambdaGroup ( owner . BodyScopeId ) ? . Padding ?? LambdaGroupModel . MinimumPadding ;
862896 var existingNodesInScope = Diagram . Nodes
863897 . OfType < GraphNodeModel > ( )
864898 . Count ( x => x . Node . CallableScopeId == node . CallableScopeId ) ;
865- var offset = new Vector2 ( 80 + existingNodesInScope * 220 , 100 ) ;
899+ var offset = new Vector2 ( groupPadding + existingNodesInScope * 220 , groupPadding ) ;
866900 node . AddDecoration ( new NodeDecorationPosition ( ownerPosition + offset ) ) ;
867901 }
868902
@@ -872,11 +906,32 @@ private LambdaGroupModel AddLambdaGroupModel(CreateDelegateNode node)
872906 foreach ( var capture in node . CaptureInputs )
873907 group . AddPort ( new GraphPortModel ( group , capture , true ) ) ;
874908 group . AddPort ( new GraphPortModel ( group , node . DelegateOutput , false ) ) ;
909+ if ( group . BoundaryReturn is { } boundaryReturn )
910+ AddBoundaryReturnPorts ( group , boundaryReturn ) ;
875911
876912 group . Moved += OnLambdaGroupMoved ;
877913 return group ;
878914 }
879915
916+ private void AddBoundaryReturnToGroup ( LambdaReturnNode boundaryReturn )
917+ {
918+ var group = FindLambdaGroup ( boundaryReturn . CallableScopeId ) ;
919+ if ( group == null )
920+ return ;
921+
922+ AddBoundaryReturnPorts ( group , boundaryReturn ) ;
923+ group . Refresh ( ) ;
924+ }
925+
926+ private static void AddBoundaryReturnPorts ( LambdaGroupModel group , LambdaReturnNode boundaryReturn )
927+ {
928+ foreach ( var connection in boundaryReturn . Inputs )
929+ {
930+ if ( group . Ports . OfType < GraphPortModel > ( ) . All ( x => x . Connection != connection ) )
931+ group . AddPort ( new GraphPortModel ( group , connection , true ) ) ;
932+ }
933+ }
934+
880935 private void ReparentScopedModels ( )
881936 {
882937 var groupsByScope = Diagram . Groups
@@ -982,6 +1037,12 @@ public void Refresh(Node node)
9821037 UpdateNodes ( ) ;
9831038 return ;
9841039 }
1040+ if ( node is LambdaReturnNode { IsImplicit : true } boundaryReturn )
1041+ {
1042+ var group = FindLambdaGroup ( boundaryReturn . CallableScopeId ) ;
1043+ group ? . Refresh ( ) ;
1044+ return ;
1045+ }
9851046
9861047 var nodeModel = FindNodeModel ( node ) as GraphNodeModel ;
9871048 if ( nodeModel == null )
@@ -1037,12 +1098,12 @@ public void Refresh(Node node)
10371098
10381099 private void InitializeCanvasWithGraphNodes ( )
10391100 {
1040- foreach ( var node in Graph . Nodes . Values . Where ( x => x is not CreateDelegateNode ) )
1041- AddGraphNodeModel ( node ) ;
1042-
10431101 foreach ( var delegateNode in Graph . Nodes . Values . OfType < CreateDelegateNode > ( ) )
10441102 AddLambdaGroupModel ( delegateNode ) ;
10451103
1104+ foreach ( var node in Graph . Nodes . Values . Where ( x => x is not CreateDelegateNode and not LambdaReturnNode { IsImplicit : true } ) )
1105+ AddGraphNodeModel ( node ) ;
1106+
10461107 ReparentScopedModels ( ) ;
10471108
10481109 // add links
0 commit comments