Skip to content

Modernize architecture and harden core application workflows - #12

Merged
russlank merged 21 commits into
mainfrom
feature/modernization
Jul 21, 2026
Merged

Modernize architecture and harden core application workflows#12
russlank merged 21 commits into
mainfrom
feature/modernization

Conversation

@russlank

@russlank russlank commented Jul 20, 2026

Copy link
Copy Markdown
Owner

Summary

This PR completes a broad architectural modernization of XpressFormula.

The application has been reorganized as a modular C++ monolith with explicit boundaries between expression processing, domain state, plotting, infrastructure, UI, application workflows, and the executable host.

The work also strengthens formula validation, project persistence, export handling, geometry generation, resource limits, update checking, CI validation, and public documentation.

Motivation

The previous structure had several responsibilities concentrated in the UI/application layer, with persistence, rendering, export, formula editing, and platform operations closely coupled.

This made the code harder to test, extend, and reason about.

The modernization aims to provide:

  • clearer ownership of responsibilities;
  • enforceable dependency direction;
  • smaller and more testable components;
  • safer persistence and export workflows;
  • more predictable dirty-state handling;
  • reusable expression and plotting foundations;
  • stronger handling of malformed or excessive input.

Main changes

Architecture

Introduces first-party static-library boundaries for:

  • Expression
  • Model
  • Plotting
  • Infrastructure
  • UI
  • Application
  • Executable host

Architecture rules are documented and enforced through:

tools/check-architecture-boundaries.ps1

The CI check validates include dependencies, project references, production source ownership, test linkage, warning/toolset policy, and public/private documentation separation.

Document and application state

  • Added Model::Document as the live project aggregate.
  • Added revision-based dirty-state tracking.
  • Persistent mutations increment the document revision.
  • No-op operations do not dirty the document.
  • Runtime viewport and auto-rotation state remain transient.
  • Added focused document commands for formula, view, and plot-setting changes.
  • Added ProjectController for New, Open, Save, Save As, recent projects, and unsaved-change workflows.

Expression compiler and runtime

  • Centralized built-in functions and constants in registries.
  • Added fixed-slot evaluation for x, y, and z.
  • Removed map lookups and per-function-call heap allocation from plotting evaluation paths.
  • Added non-throwing numeric-literal parsing.
  • Added compile-time function-arity validation.
  • Added formula length, token, nesting, AST-node, and AST-depth limits.
  • Improved diagnostics for malformed expressions and equations.
  • Prevented stale compiled formula state after expression changes.

Formula editor

  • Replaced per-frame mutable formula snapshots with explicit typed commands.
  • Added stable formula-ID targeting.
  • Made Add Formula transactional:
    • Apply inserts the formula.
    • Cancel leaves the document unchanged.
  • Edit operations preserve identity and ignore stale targets safely.
  • Added dynamic, lossless formula text editing and live validation.

Plotting and geometry

  • Separated pure sampling and meshing from ImGui rendering.
  • Added reusable geometry generation for:
    • curves;
    • scalar grids;
    • implicit contours;
    • explicit surfaces;
    • implicit 3D surfaces.
  • Added render-plan and cache foundations.
  • Added centralized plot-quality and rendering policies.
  • Added Marching Squares saddle disambiguation.
  • Improved exact-zero, non-finite, and degenerate geometry handling.
  • Added unique Surface Nets cell-intersection handling and degenerate-triangle rejection.

Persistence and JSON

  • Added versioned project DTOs, serializer, mapper, repository, and recent-project store.
  • Kept .xfplot schema version 1.
  • Added strict internal JSON parsing with:
    • duplicate-key rejection;
    • UTF-8 validation;
    • surrogate validation;
    • nesting and value-count limits;
    • strict numeric parsing.
  • Added bounded project-file reads.
  • Added formula-count, expression-length, and serialized-size validation.
  • Added unique same-directory temporary files and atomic replacement.
  • Failed loads preserve the active document.
  • Failed saves preserve the previous target file.

Export and Windows services

  • Extracted export settings, image processing, output workflow, and metadata handling.
  • Extracted Windows services for dialogs, clipboard, shell operations, WIC encoding, UTF conversion, and HTTP.
  • Added checked image-buffer arithmetic.
  • Added safe fallback handling for invalid or non-finite export bounds.
  • Added HTTP response-size limits.
  • Update checks no longer block application shutdown.

Documentation and CI

Added or substantially updated:

  • architecture overview;
  • dependency rules;
  • architecture decision records;
  • expression-language reference;
  • algorithms guide;
  • testing guide;
  • run and debugging guide;
  • release-packaging guide;
  • contributing guide.

PR Validation now performs:

  1. architecture-boundary checks;
  2. Debug application build;
  3. Debug test build and execution;
  4. Release application build;
  5. Release test build and execution.

Release packaging also runs architecture and Release test checks before packaging.

Compatibility

  • .xfplot remains at schema version 1.
  • Existing project workflows remain supported.
  • Export metadata compatibility is preserved.
  • No private modernization roadmap or prompt-tracking material is included.
  • The repository and CI now default to Visual Studio 2026 / MSVC toolset v145.
  • Visual Studio 2022 users may explicitly retarget local builds to an installed toolset such as v143.

Verification

Automated verification on the current branch:

  • Architecture-boundary check passes.
  • Debug x64 application builds.
  • Release x64 application builds.
  • Debug test project builds.
  • Release test project builds.
  • Debug tests: 531/531 passed.
  • Release tests: 531/531 passed.
  • Zero first-party compiler warnings and errors.
  • Local release workflow dry run passes.
  • PR Validation run #8 passed.

The expression benchmark was not rerun for the final closure commit because that commit did not change evaluator runtime behavior.

Manual verification before release

The following interactive checks should still be completed before creating the release tag:

  • Formula editor Add/Apply, Add/Cancel, Edit/Apply, and Edit/Cancel.
  • Closing the application during a pending update check.
  • 2D curves, discontinuities, contours, heatmaps, and scalar slices.
  • Explicit and implicit 3D surfaces, including multiple surfaces.
  • Camera presets, auto-rotation, grid, coordinates, wires, and envelope.
  • New, Open, Save, Save As, Recent, and unsaved-change dialogs.
  • Malformed, unsupported, oversized, and Unicode project files.
  • PNG/BMP, transparent, grayscale, metadata, clipboard, and shell export actions.
  • Wide, compact, narrow, and high-DPI UI layouts.

Review notes

Because this is a large architectural PR, review is easiest by area:

  1. project and document ownership;
  2. expression compiler/runtime;
  3. plotting and meshing;
  4. persistence and JSON;
  5. export and platform services;
  6. CI, tests, and documentation.

russlank added 17 commits July 19, 2026 01:58
- Introduced a new static library project for Plotting functionality.
- Added UI project to encapsulate user interface components.
- Enhanced FormulaEntry tests to validate default startup formula characteristics.
- Implemented ProjectSession tests to ensure serialized snapshots accurately reflect dirty states.
- Updated project references in the solution and various project files to include new Plotting and UI projects.
- Refactored include directories for consistency across projects.
- Removed commented-out code and unnecessary includes from XpressFormula project files.
- Improved organization of project filters for better maintainability.
- Removed the use of inputBuffer in FormulaEntry, replacing it with a direct expression string for better clarity and maintainability.
- Updated parsing logic to utilize the new expression management, ensuring compatibility with existing functionality.
- Introduced a new FormulaCompiler for parsing and classifying formulas, enhancing the separation of concerns.
- Added AstQueries for shared operations on AST nodes, improving code reuse and readability.
- Updated tests to reflect changes in formula handling, ensuring that truncation warnings are correctly managed.
- Enhanced UI components to work with the new formula structure, ensuring a seamless user experience.
- Introduced a ColorRgba structure for better color management in formulas.
- Added FormulaId for stable identity management of formulas.
- Introduced SceneSummary and FormulaSceneItem structures to analyze and manage visible scene elements.
- Added ViewState structure to encapsulate persistent and transient view geometry.
- Updated PlotRenderer to utilize viewport properties instead of screen dimensions for rendering.
- Refactored Application class to refresh scene summary upon project reset and loading.
- Simplified rendering logic in ControlPanel and PlotPanel by leveraging SceneSummary for visibility checks.
- Enhanced PlotSettings to resolve render modes based on the new scene analysis.
- Created FormulaSceneAdapter to convert FormulaEntry to FormulaSceneItem for scene analysis.
- Replace FormulaEntry with Model::Formula in various UI components to streamline formula management.
- Introduce FormulaEditorState to encapsulate the state of the formula editor, allowing for better handling of formula editing and previewing.
- Update FormulaListActions to work with Model::Formula, enhancing the consistency of formula operations across the UI.
- Modify FormulaPanel to utilize the new FormulaEditorState and improve the editor dialog for better user experience.
- Remove deprecated FormulaSceneAdapter and related code, simplifying the overall structure.
- Ensure all formula-related rendering and actions are aligned with the new Model::Formula structure.
…dling

- Updated the `PlotPanel::render` method to accept a new parameter for `PlotQualityDecision`, allowing for more granular control over rendering quality.
- Consolidated rendering settings into an `EffectivePlotSettings` structure to streamline the rendering process and reduce redundancy.
- Removed the previous `PlotRenderOverrides` structure and integrated its functionality into the new effective settings.
- Enhanced background drawing and grid rendering logic to utilize the new effective settings.
- Updated the handling of interactive rendering to improve performance during user interactions.
- Refactored the `PlotSettings` and `PlotPanel` header files to align with the new structure and removed deprecated code.
- Ensured compatibility with existing project sessions by normalizing plot settings during session parsing and application.
- Removed custom JSON parsing and escaping implementations in favor of reusable helpers from Infrastructure::Serialization.
- Updated ProjectSession to utilize new JsonParser and JsonValue types.
- Simplified jsonEscape and related functions to leverage centralized implementations.
- Improved export metadata sidecar path handling with atomic file operations.
- Cleaned up includes and removed unnecessary code for better maintainability.
…tory, and ProjectSerializer

- Added ProjectMapper.h and ProjectMapper.cpp for mapping between live model state and project persistence DTOs.
- Introduced ProjectRepository.h and ProjectRepository.cpp to handle file I/O for .xfplot project sessions.
- Created ProjectSerializer.h and ProjectSerializer.cpp for DTO/JSON conversion for .xfplot schema v1.
- Defined ProjectSession.h to encapsulate versioned .xfplot persistence DTOs.
- Implemented RecentProjectsStore.h and RecentProjectsStore.cpp for managing recent project paths with UTF-safe handling.
- Updated Application.cpp and Application.h to integrate the new persistence layer, including loading and saving recent project paths.
- Refactored project session management to utilize the new ProjectRepository and ProjectMapper for improved structure and maintainability.
- Added WinHttpClient class for handling HTTP GET requests using WinHTTP.
- Created WinHttpGetRequest and WinHttpResponse structs for request and response management.
- Implemented JSON parsing for GitHub release information.
- Refactored Application class to utilize the new WinHttpClient for checking updates from GitHub.
- Removed legacy WinHTTP code from Application class and replaced it with the new client.
- Introduced services for clipboard, file dialog, and shell operations to streamline UI interactions.
- Introduced ExportDialog component for managing export settings in ImGui.
- Moved export dialog logic from Application.h and ExportDialog.cpp to a dedicated ExportDialog.h and ExportDialog.cpp.
- Integrated ExportController and ExportPreviewTexture into Application.h for better resource management.
- Updated ExportMetadata.h to use new infrastructure-owned export metadata helpers, improving code organization and readability.
- Removed deprecated functions and variables related to export preview and settings from Application.h.
- Enhanced export dialog with improved UI elements for better user experience.
…plication

- Added Document class to encapsulate project state, including formulas, view transform, and plot settings.
- Refactored Application class to utilize Document for managing project state instead of individual members.
- Implemented ProjectController to handle project-related actions and state management.
- Updated UI components to interact with the new Document structure, including project controls and rendering logic.
- Enhanced plot rendering to use formulas and settings from the Document class.
- Introduced ProjectControls component for better project management UI.
- Improved handling of unsaved changes with a dedicated dialog.
- Removed unused includes and code related to previous UI panels in Application.h.
- Introduced MainWindow class to encapsulate the primary workspace UI logic.
- Moved rendering logic for the sidebar, plot, and export dialog into MainWindow.
- Simplified Application class by delegating responsibilities to MainWindow.
- Updated Application to use ApplicationComposition and ApplicationState for better state management.
- Added MainWindow.cpp and MainWindow.h files to implement the new MainWindow class.
- Enhanced update notification handling and plot toolbar interactions within MainWindow.
- Added Projection3D class to encapsulate 3D projection logic, improving code organization and readability.
- Updated PlotRenderer to utilize Projection3D for projecting 3D points and directions, enhancing performance and maintainability.
- Introduced Meshing::ImplicitMeshCache to cache implicit surface meshes, reducing redundant calculations during rendering.
- Modified drawImplicitSurface3D to leverage the new mesh cache, improving rendering efficiency for implicit surfaces.
- Implemented auto-rotation for 3D plots in Application, allowing for dynamic camera adjustments based on user settings.
- Updated PlotPanel to integrate implicit mesh caching and streamline rendering logic for various plot types.
- Enhanced handling of plot settings to ensure consistent camera angles and rendering options across frames.
- Implemented ImGuiPlotBackend for rendering polylines, line segments, and scalar cell grids.
- Added heat color mapping functionality for visualizing scalar values.
- Introduced CurveSampler for sampling 2D curves based on provided AST nodes and options.
- Developed ScalarGridSampler for generating scalar grids and lattices for heatmaps and contours.
- Enhanced geometry handling with new Polyline and Bounds2D structures.
- Updated FormulaPanel methods to accept std::span for formulas instead of std::vector.
- Introduced FormulaPanelCommand and FormulaPanelActions structs to encapsulate actions performed on formulas.
- Modified render method to return actions instead of directly modifying formulas.
- Implemented applyFormulaPanelCommand function in MainWindow to handle command execution.
- Added architecture boundary checks to ensure separation of concerns between UI and other components.
- Introduced FunctionEvaluator type for function evaluation.
- Updated FunctionInfo structure to include evaluate function pointer.
- Replaced static constant handling in Parser with dynamic constant retrieval.
- Refactored evaluation context in meshing and sampling components to use a unified EvaluationContext instead of Variables.
- Enhanced FormulaPanel to dynamically list available constants instead of hardcoding.
- Cleaned up unused constant definitions and improved error handling for unknown functions.
… guidelines

- Added a PowerShell script to check architecture boundaries in the release workflow.
- Created a CONTRIBUTING.md file outlining quality gates, architecture rules, and documentation standards.
- Updated README.md to include a badge for PR validation and mention the modular monolith architecture.
- Documented architecture decisions in ADRs, including modular monolith structure and internal JSON handling.
- Enhanced architecture dependency documentation to clarify production library boundaries and forbidden dependencies.
- Updated various project files to enforce MSVC warning level `/W4` and conformance mode.
- Improved test scripts to include architecture boundary checks and ensure compliance before packaging.
- Refactored FormulaCard component to use local variable for color handling.
@russlank
russlank force-pushed the feature/modernization branch from 9f74299 to 467a828 Compare July 21, 2026 16:32
- Introduced normalization functions for color channels, z-slices, and view states in Document.cpp to ensure consistent data handling.
- Updated formula management to include normalization during addition, updating, and duplication of formulas.
- Improved plot settings normalization in PlotSettingsEdit and added validation for image byte counts in ClipboardService and WicImageEncoder.
- Enhanced HTTP response handling in WinHttpClient to check for response size limits.
- Added checks for valid grid and lattice requests in ScalarGridSampler and CurveSampler, incorporating input limits.
- Refactored FormulaEditorState to support adding and editing formulas with improved state management.
- Updated FormulaPanel to handle new formula addition and editing workflows, ensuring UI reflects the current state accurately.
- Implemented architecture boundary checks in PowerShell script to enforce project reference rules and documentation consistency.
@russlank
russlank force-pushed the feature/modernization branch from 09f002a to e7a42d2 Compare July 21, 2026 17:08
@russlank russlank changed the title Feature/modernization Modernize architecture and harden core application workflows Jul 21, 2026
@russlank
russlank merged commit 427ed18 into main Jul 21, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant