Refactor GeneralViewLayoutStrategy to use LayoutGraph and LayoutEngine - #15
Merged
Conversation
…raph Phase B of the Rendering migration: GeneralViewLayoutStrategy no longer hand-rolls its own placement pipeline (PlaceGroups/LayoutGroup/BuildEdges/ RouteEdges/ComputeCanvasWidth). Instead it expresses the whole General View as one DemaConsulting.Rendering LayoutGraph - package folders as Folder-shaped container nodes, definitions as leaf nodes carrying Shape/Keyword/Compartments - and places it with a single HierarchicalLayoutAlgorithm.Apply call: - Root scope packs package folders and top-level definitions by reading order (ContainmentLayoutAlgorithm), selected via LayoutOptions.ForAlgorithm so a future LayoutEngine.Layout(graph) caller is never misled into skipping the hierarchical engine. - Each folder own contents are ordered by their intra-package edges with the bundled layered algorithm (LayeredLayoutAlgorithm), selected per-node via CoreOptions.Algorithm on the folder container itself. - Folder TitleHeight is set from BoxMetrics.TitleAreaHeight so the engine reserves the exact title band the renderer draws (uses the new LayoutGraphNode.TitleHeight override). - Depth-truncated folders are never expanded into individual boxes at all: the folder becomes a single leaf node sized like the previous ellipsis indicator (its Children graph is never touched, so the engine keeps the caller-computed size instead of auto-sizing it as a container), and its "+N more..." label is stamped onto the placed box once layout is known. - Model edges are resolved by qualified name once, then scoped per the graph's lowest-common-ancestor convention: same-package edges go into that folder's own Children scope, everything else goes to the root graph referencing descendant nodes directly. An edge touching a depth-truncated definition has no node to reference and is dropped, exactly as before. This removes SysML2Tools's hand-rolled box-placement/edge-routing logic in favor of Rendering's own engine, including its anchor-coordination fix for connectors converging on a shared box face. Regenerated DictionaryMarkSystemView confirms the original 6-way connector collision no longer reproduces. Test updates: intra-package edges are now routed within their folder's own coordinate space by the hierarchical engine, so they appear nested inside that folder box's Children rather than at the top level of the LayoutTree. Added a recursive CollectLines test helper (mirroring the existing CollectBoxes helper) and switched every edge-presence assertion to use it. All existing GeneralViewLayoutStrategy behavioral tests continue to pass unchanged in intent. Note: DemaConsulting.SysML2Tools.Core and .Tool still reference the local Rendering checkout via ProjectReference (TitleHeight/Shape/Keyword/ Compartments are not yet in a published Rendering package). Revert to PackageReference once Rendering ships a release containing them. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…ences Reverts the temporary ProjectReferences to the local Rendering repo (used for testing against unreleased fixes) back to PackageReference, now that DemaConsulting.Rendering.Layout/.Svg/.Skia 0.1.0-beta.4 is published on nuget.org. Also bumps the test project's existing package references from the stale 0.1.0-beta.2 pin to 0.1.0-beta.4. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…ctly LayeredPlacement now delegates to the DemaConsulting.Rendering.Layout package's public LayoutEngine.Layout(LayoutGraph) facade rather than instantiating LayeredLayoutAlgorithm directly. Since LayeredPlacement's graphs are always flat (no container nodes), the facade's default hierarchical algorithm is guaranteed byte-for-byte identical to the layered algorithm applied directly. The requested flow direction now sets CoreOptions.Direction on the graph itself (via IPropertyHolder.Set) rather than on a LayoutOptions instance, since the facade always seeds its internal cascade with empty options and only honors settings declared directly on the graph. Also corrects the LayeredPlacement design doc and reqstream justification text, which still listed GeneralViewLayoutStrategy as a caller — that strategy now builds and places its own nested LayoutGraph directly via HierarchicalLayoutAlgorithm and no longer goes through this helper. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Regenerated all 8 gallery models (SVG + PNG) to confirm the LayeredPlacement change (LayoutEngine.Layout facade instead of direct LayeredLayoutAlgorithm.Apply) produces byte-identical layouts for the ActionFlow, Interconnection, and StateTransition gallery examples. DroneGeneralView.svg/.png also updated: unrelated to this change, its committed gallery images were stale from before the earlier Phase B GeneralViewLayoutStrategy rewrite (the container is now taller/wider per the current HierarchicalLayoutAlgorithm sizing) and had never been regenerated since. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…MAP.md - Stdlib.csproj's GenerateStdlibBin target previously used <Exec> to spawn a separate, uncoordinated 'dotnet build StdlibGen.csproj' process. Since StdlibGen.csproj ProjectReferences Language.csproj, that second process could race the outer solution build's own build of Language.csproj for the same net10.0 output, intermittently failing CI with CS2012 (DLL in use by another process). - Replaced the nested Exec 'dotnet build' with an in-process MSBuild task call (Targets="Restore;Build"), so StdlibGen is built within the same MSBuild engine/BuildManager session as the outer build. Deliberately not exposed as a ProjectReference item, since that made StdlibGen discoverable by other multi-targeted projects' own TFM-negotiation evaluations, which build referenced projects with a default Debug configuration independent of this target's guard. - Added a BuildingProject guard to the target, since BeforeTargets=PrepareForBuild also fires during lightweight non-build MSBuild evaluations (e.g. other projects' GetTargetFrameworks-style calls). - Fixed a related latent bug in StdlibGen's Program.cs: File.WriteAllBytesAsync writes in place (FileMode.Create, FileShare.Read), which does not tolerate a second concurrent writer to the same output path - exactly the scenario the solution's multi-project build graph can trigger. StdlibGen now writes to a uniquely-named temp file and atomically renames it onto the destination. - Verified via repeated clean rebuilds (plain and --graphBuild) and the full build.ps1 suite (0 warnings, 0 errors, all 441 tests x 3 TFMs passing). - Trimmed ROADMAP.md: removed the fully-implemented per-verb CLI architecture and query command sections (already documented in the User Guide and design docs), and removed all other completed-work summaries/callouts per the policy that ROADMAP.md contains only future/planned work. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Eliminates the recurring CS2012 file-in-use races and NETSDK1005 restore-corruption errors caused by Stdlib.csproj invoking StdlibGen via nested MSBuild/Exec tasks during the multi-targeted (net8.0/net9.0/net10.0) solution build. - StdlibGen now writes a gzip-compressed UTF-8 JSON artifact (stdlib.json.gz, ~463 KB) instead of an uncompressed stdlib.bin, and only overwrites its output when content actually changed (temp-file + binary compare), so it is safe and cheap to run on every build. - Diagnostic file paths embedded in the artifact are now normalized relative to --stdlib-dir, making the output byte-for-byte reproducible regardless of machine, checkout path, or absolute/relative invocation style. - stdlib.json.gz is committed to source control and embedded via a plain EmbeddedResource item in Stdlib.csproj - no MSBuild target, no ProjectReference to StdlibGen, no build-time generation step at all. - Fixed a related MSBuild culture-detection bug: naming the file stdlib.bin.gz caused AssignCulture to treat 'bin' as an ISO 639 culture code and silently route the resource into a satellite culture assembly. Renamed to stdlib.json.gz (accurately reflecting its content) and set WithCulture=false defensively. - build.ps1 now regenerates stdlib.json.gz as a plain sequential pre-build step (dotnet run StdlibGen) so it can never be forgotten after editing stdlib sources, instead of relying on a separate manually-run script. - StdlibProvider.LoadFromResource decompresses via GZipStream before deserializing. - Updated design docs (introduction.md, sysml2-tools-stdlib.md and subdocs, ast-serializer.md, ast-deserializer.md, reqstream yaml) to describe the new architecture and remove references to the old GenerateStdlibBin/EmbedStdlibBin MSBuild targets. Verified: full clean build.ps1 run passes (441 tests x3 TFMs), stdlib.json.gz regeneration is confirmed byte-identical across absolute/relative invocation styles (SHA256 match), and the skip-if-unchanged no-op path is confirmed working. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This was referenced Jul 27, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This pull request updates documentation to reflect recent architectural changes and improvements in the SysML2Tools project, particularly in how the standard library is pre-compiled and how general view layout is structured and described. The most important changes clarify the build process, update design documentation to match implementation, and provide a more accurate and detailed explanation of the general view layout strategy.
Build & Tooling Documentation:
build.ps1to always regenerate thestdlib.json.gzresource before building, ensuring the pre-compiled standard library never goes stale. This is now a sequential step outside the MSBuild graph for reliability and simplicity.stdlib.json.gz(notstdlib.bin), and thatStdlibGenis a standalone tool invoked bybuild.ps1rather than part of the MSBuild graph. [1] [2]General View Layout Strategy Documentation:
LayoutGraphand placed with one call toHierarchicalLayoutAlgorithm.Apply, with explicit separation of responsibilities for box sizing and placement.ModelEdge,Location, andTruncatedFolderrecords, and a new explanation of how edges and nodes are resolved, placed, and decorated. The documentation now matches the latest code structure and algorithms. [1] [2]Roadmap Updates:
querycommand, with a focus on dynamic (ad-hoc) views and further AI-analysis options, and trimmed implementation details from the roadmap to keep it forward-looking. [1] [2]