# Structural verification (NOT part of the shipped app; under .preflight/, gitignored). # # Proves on disk -- not by prose -- that the two structural requirements are satisfied: # [1] The giant implementation files were split by responsibility into sibling files # under each component's own Src/ (and each new translation unit is compiled). # [2] The common UI controls live in a real `Components/Shared` component, are compiled # into the binary, and are consumed by the other components. # # Run: powershell -File .preflight\perf\structcheck.ps1 # ASCII only (PowerShell 5.1 reads .ps1 as ANSI). $ErrorActionPreference = "Stop" $root = Split-Path -Parent $PSScriptRoot Set-Location $root $pass = 0 $fail = 0 function Check([bool]$ok, [string]$what) { if ($ok) { $script:pass++ ; Write-Host (" OK " + $what) } else { $script:fail++ ; Write-Host (" FAIL " + $what) } } function Lines([string]$path) { if (-not (Test-Path $path)) { return -1 } return (Get-Content $path | Measure-Object -Line).Lines } Write-Host "== [1] split of the giant implementation files ==" # 1a. every expected file of the split exists and is a sibling under the component's Src/ $split = @( "Components/PlotView/Src/PlotView.cpp", "Components/PlotView/Src/PlotViewPaint.cpp", "Components/PlotView/Src/PlotViewInteraction.cpp", "Components/PlotView/Src/PlotViewFeatures.cpp", "Components/PlotView/Src/PlotViewInternal.hpp", "Components/SignalPanel/Src/SignalPanel.cpp", "Components/SignalPanel/Src/SignalPanelPaint.cpp", "Components/SignalPanel/Src/SignalPanelInteraction.cpp", "Components/SignalPanel/Src/SignalPanelInternal.hpp", "Components/Application/Src/Application.cpp", "Components/Application/Src/ApplicationCommands.cpp", "Components/Application/Src/ApplicationLoading.cpp", "Components/Application/Src/ApplicationInternal.hpp", "Utilities/Src/DataModel.cpp", "Utilities/Src/DataModelTab.cpp", "Utilities/Src/DataModelInternal.hpp" ) foreach ($f in $split) { $n = Lines $f Check ($n -gt 0) ("exists + non-empty: " + $f + " (" + $n + " lines)") } # 1b. the core file of each split is a small fraction of the original monster file Check ((Lines "Components/PlotView/Src/PlotView.cpp") -lt 900) "PlotView.cpp shrunk to < 900 lines (was 13 695)" Check ((Lines "Components/PlotView/Src/PlotViewPaint.cpp") -gt 4000) "PlotViewPaint.cpp carries the rendering (> 4000 lines)" Check ((Lines "Components/SignalPanel/Src/SignalPanel.cpp") -lt 1200) "SignalPanel.cpp shrunk to < 1200 lines (was 4 184)" Check ((Lines "Components/Application/Src/Application.cpp") -lt 1500) "Application.cpp shrunk to < 1500 lines (was 3 135)" Check ((Lines "Utilities/Src/DataModel.cpp") -lt 1600) "DataModel.cpp shrunk to < 1600 lines (was 2 615)" # 1c. responsibility really moved: each concern is defined in exactly one file $concerns = @( @{ symbol = "PlotView::Paint"; file = "PlotViewPaint.cpp" }, @{ symbol = "PlotView::PaintLane"; file = "PlotViewPaint.cpp" }, @{ symbol = "PlotView::PaintHint"; file = "PlotViewPaint.cpp" }, @{ symbol = "PlotView::LaneAtY"; file = "PlotViewInteraction.cpp" }, @{ symbol = "PlotView::CancelDrag"; file = "PlotViewInteraction.cpp" }, @{ symbol = "PlotView::FitAll"; file = "PlotViewFeatures.cpp" }, @{ symbol = "PlotView::SetHint"; file = "PlotViewFeatures.cpp" }, @{ symbol = "PlotView::Layout"; file = "PlotView.cpp" }, @{ symbol = "PlotView::BuildLaneVisuals"; file = "PlotView.cpp" }, @{ symbol = "SignalPanel::Paint"; file = "SignalPanelPaint.cpp" }, @{ symbol = "SignalPanel::OnLButtonDown"; file = "SignalPanelInteraction.cpp" }, @{ symbol = "SignalPanel::EnsureRows"; file = "SignalPanel.cpp" } ) foreach ($c in $concerns) { $hits = @(Select-String -Path "Components/*/Src/*.cpp", "Utilities/Src/*.cpp" -Pattern ("^\s*\w[\w:<>, ]* " + [regex]::Escape($c.symbol) + "\(") | ForEach-Object { Split-Path $_.Path -Leaf }) $ok = ($hits.Count -eq 1) -and ($hits[0] -eq $c.file) Check $ok ($c.symbol + " defined only in " + $c.file + " (found: " + ($hits -join ",") + ")") } # 1d. the constant/tool block of each big file became a named internal header + using-declaration $internal = @( @{ file = "Components/PlotView/Src/PlotViewInternal.hpp"; ns = "pvdetail" }, @{ file = "Components/SignalPanel/Src/SignalPanelInternal.hpp"; ns = "spdetail" }, @{ file = "Components/Application/Src/ApplicationInternal.hpp"; ns = "appdetail" }, @{ file = "Utilities/Src/DataModelInternal.hpp"; ns = "dmdetail" } ) foreach ($i in $internal) { $text = Get-Content $i.file -Raw $hasNs = $text -match ("namespace\s+" + $i.ns) $hasUsing = $text -match ("using namespace\s+" + $i.ns + "\s*;") $inlineCount = ([regex]::Matches($text, "(?m)^\s*(?:\[\[[^\]]*\]\]\s*)?inline\s")).Count Check $hasNs ($i.file + " declares namespace " + $i.ns) Check $hasUsing ($i.file + " injects it via the using-declaration for " + $i.ns) Check ($inlineCount -ge 4) ($i.file + " marks the shared helpers inline (" + $inlineCount + " definitions)") } # 1e. the split files are compiled, and their objects hold the moved code $objs = @("PlotView.o","PlotViewPaint.o","PlotViewInteraction.o","PlotViewFeatures.o", "SignalPanel.o","SignalPanelPaint.o","SignalPanelInteraction.o", "Application.o","ApplicationCommands.o","ApplicationLoading.o", "DataModel.o","DataModelTab.o") $missing = @() foreach ($o in $objs) { if (-not (Test-Path ("Build/Release/" + $o))) { $missing += $o } } Check ($missing.Count -eq 0) ("all split translation units were compiled (missing: " + ($missing -join ",") + ")") $nm = Get-Command nm -ErrorAction SilentlyContinue if ($nm -ne $null) { $paintInPaint = @(nm --defined-only -C "Build/Release/PlotViewPaint.o" 2>$null | Select-String "jdi::PlotView::Paint") $paintInCore = @(nm --defined-only -C "Build/Release/PlotView.o" 2>$null | Select-String "jdi::PlotView::Paint") Check ($paintInPaint.Count -gt 0) "nm: paint symbols live in PlotViewPaint.o" Check ($paintInCore.Count -eq 0) "nm: no paint symbol left in PlotView.o" } else { Check $false "nm not available (cannot verify symbol placement)" } # 1f. every implementation file of every component is registered in the Makefile $srcFiles = @(Get-ChildItem "Components/*/Src/*.cpp", "Utilities/Src/*.cpp" | ForEach-Object { $_.FullName.Substring($root.Length + 1).Replace("\", "/") }) $makefile = Get-Content "Makefile" -Raw $unregistered = @() foreach ($s in $srcFiles) { $dir = $s.Substring(0, $s.LastIndexOf("/")) if ($makefile -notmatch [regex]::Escape($dir)) { $unregistered += $s } } Check ($unregistered.Count -eq 0) ("every implementation directory is registered in the Makefile (missing: " + ($unregistered -join ",") + ")") Check ($srcFiles.Count -ge 24) ("implementation files in the tree: " + $srcFiles.Count) Write-Host "" Write-Host "== [2] Components/Shared ==" Check (Test-Path "Components/Shared/Inc/UiControls.hpp") "Components/Shared/Inc/UiControls.hpp exists" Check (Test-Path "Components/Shared/Src/UiControls.cpp") "Components/Shared/Src/UiControls.cpp exists" Check ((Lines "Components/Shared/Inc/UiControls.hpp") -gt 100) ("UiControls.hpp declares the control API (" + (Lines "Components/Shared/Inc/UiControls.hpp") + " lines)") # 2a. the shared header really owns the enumerated control families $families = @("UiDrawPlusIcon","UiDrawCrossIcon","UiDrawTriangleIcon","UiDrawCheckBox", "UiDrawSlider","UiDrawEditField","UiEditFieldMouseDown","UiDrawSwatch", "UiSwatchNeedsOutline","UiContrastInk","UiSliderRatioFromX") $header = Get-Content "Components/Shared/Inc/UiControls.hpp" -Raw $missingFamilies = @() foreach ($f in $families) { if ($header -notmatch ("\b" + $f + "\b")) { $missingFamilies += $f } } Check ($missingFamilies.Count -eq 0) ("shared header exposes all control families (missing: " + ($missingFamilies -join ",") + ")") # 2b. symbol-level proof: every declared control is DEFINED by UiControls.o and by no other object. # (Text matching cannot tell a definition from a call, so ask the linker's view instead.) $declared = @([regex]::Matches($header, "(?m)^\s*[\w:<>, ]+\s+(Ui\w+)\s*\(") | ForEach-Object { $_.Groups[1].Value } | Sort-Object -Unique) Check ($declared.Count -ge 15) ("UiControls.hpp declares " + $declared.Count + " control functions") $definitionOwner = @{} $objectFiles = @(Get-ChildItem "Build/Release/*.o" -ErrorAction SilentlyContinue) if ($nm -eq $null) { Check $false "nm not available (cannot verify control definitions)" } else { foreach ($o in $objectFiles) { $syms = nm --defined-only -C $o.FullName 2>$null foreach ($name in $declared) { if ($syms | Select-String (" T jdi::" + [regex]::Escape($name) + "\(")) { $definitionOwner[$name] = $o.Name } } } $wrongOwner = @($declared | Where-Object { -not $definitionOwner.ContainsKey($_) -or $definitionOwner[$_] -ne "UiControls.o" }) Check ($wrongOwner.Count -eq 0) ("nm: all " + $declared.Count + " declared controls are defined in UiControls.o (wrong/undefined: " + ($wrongOwner -join ",") + ")") $uiControlsSymbols = @(nm --defined-only -C "Build/Release/UiControls.o" 2>$null | Select-String " T jdi::Ui").Count Check ($uiControlsSymbols -ge 15) ("nm: UiControls.o defines " + $uiControlsSymbols + " Ui* symbols") } # 2c. other components actually consume them (>= 3 components, >= 30 call sites) $consumers = @(Select-String -Path "Components/*/Src/*.cpp", "Components/*/Inc/*.hpp" -Pattern "UiDrawPlusIcon|UiDrawCrossIcon|UiDrawTriangleIcon|UiDrawCheckBox|UiDrawSlider|UiDrawEditField|UiEditFieldMouseDown|UiEditFieldMouseMove|UiDrawSwatch|UiSwatchNeedsOutline|UiContrastInk|UiSliderRatioFromX|UiEditTextLeft|UiEditOffsetAt" | Where-Object { (Split-Path $_.Path -Leaf) -ne "UiControls.hpp" } | Group-Object { ($_.Path.Substring($root.Length + 1) -split "[\\/]")[1] }) $componentNames = @($consumers | ForEach-Object { $_.Name }) $totalCalls = 0 foreach ($g in $consumers) { $totalCalls += $g.Count } Check ($componentNames.Count -ge 3) ("shared controls consumed by >= 3 components (" + ($componentNames -join ",") + ")") Check ($totalCalls -ge 30) ("shared control call sites across components: " + $totalCalls) # 2d. layering, stated exactly as the code obeys it: # Components/Shared -> Utilities only (it must not include any component header) # Utilities/PaintUtil = base layer (must not include UiControls.hpp) # Utilities must not include feature components (PlotView / SignalPanel / Toolbar / TabBar) # NOTE: Utilities/Src/PopupMenu.cpp and Utilities/Src/ColorPickerPopup.cpp are hand-drawn UI # widgets that live in the Utilities folder historically; they consume the shared controls # (same direction as the components do) and are deliberately excluded from the ban below. $sharedIncludes = @(Select-String -Path "Components/Shared/Inc/*.hpp", "Components/Shared/Src/*.cpp" -Pattern '^#include "' | Where-Object { $_.Line -match '"(Application|PlotView|SignalPanel|Toolbar|TabBar|PopupMenu|ColorPickerPopup)\.hpp"' }) Check ($sharedIncludes.Count -eq 0) "Components/Shared depends on Utilities only (no component header)" $paintUtilIncludes = @(Select-String -Path "Utilities/Inc/PaintUtil.hpp", "Utilities/Src/PaintUtil.cpp" -Pattern '#include "UiControls.hpp"' -ErrorAction SilentlyContinue) Check ($paintUtilIncludes.Count -eq 0) "Utilities/PaintUtil (base layer) does not depend on Components/Shared" $badDir = @(Select-String -Path "Utilities/Src/*.cpp", "Utilities/Inc/*.hpp" -Pattern '#include "(PlotView|SignalPanel|Toolbar|TabBar)' -ErrorAction SilentlyContinue) Check ($badDir.Count -eq 0) "Utilities never includes a feature component" Write-Host "" Write-Host ("structcheck: " + $pass + " passed, " + $fail + " failed") if ($fail -ne 0) { exit 1 } exit 0