Feature/reactive forms bridge#7
Merged
Merged
Conversation
Plans replacing the forms demo's direct RemoteServer/wire::Envelope usage with Bridge/BridgeHandler, and making forms fire live via set<>/subscribe<> instead of an explicit submit button, without new per-action boilerplate. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…mits set<&Action::field> needs a compile-time member pointer per field, and glaze's plain-aggregate reflection (reflectable<T>, no glz::meta) exposes only field names, not member pointers -- confirmed directly against glaze/core/reflect.hpp. Replaced the set<>/subscribe<>-based design with a generic executeJson(actionType, bodyJson) path backed by a registry populated automatically inside BRIDGE_REGISTER_ACTION, preserving the zero-new-boilerplate-per-action goal. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Six tasks: ActionExecuteRegistry + BridgeHandler::executeJson (with unit tests), FormsController rewrite onto Bridge/BridgeHandler, reactive DynamicForm.qml (auto-fire, no submit button), Qt Quick Test coverage, README update, and a full regression pass. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…DLLs FindQt.cmake was only included under MORPH_BUILD_QT, so enabling MORPH_BUILD_FORMS_QML alone failed to find Qt6 on Windows. Also adds a windeployqt post-build step so morph_forms_qml.exe can run standalone without Qt's bin directory on PATH. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
BridgeHandler::executeJson(actionType, bodyJson) resolves a runtime action-type string to the real compile-time execute<Action>() call, registered automatically inside BRIDGE_REGISTER_ACTION. Lets a schema-driven UI dispatch through Bridge/BridgeHandler without knowing concrete C++ action types at compile time, with zero new declarations per action. Changes: - Add ActionExecuteRegistry singleton to bridge.hpp with string->executor mapping - Add BridgeHandler::executeJson() and ::guiExecutor() methods - Hook registerActionExecutorOnce into BRIDGE_REGISTER_ACTION_4 macro - Add 3 test cases for successful dispatch, parse error handling, and unknown action - Update test files to include bridge.hpp (now required by macro change) All 352 tests pass (3 new, 349 existing regressions = 0).
registerActionExecutorOnce<Model, Action> is declared in registry.hpp but only defined in bridge.hpp (to avoid a registry.hpp -> bridge.hpp include cycle). BRIDGE_REGISTER_ACTION_4 calls it unconditionally at static-init time, so any translation unit that invokes BRIDGE_REGISTER_ACTION without also including <morph/bridge.hpp> in that same TU fails to link with an unresolved external symbol. A prior commit patched 3 files that broke the default ctest build (examples/forms/main.cpp, tests/test_quantity_forms.cpp, tests/test_server_limits.cpp) but left every other call site unaudited. A repo-wide grep for BRIDGE_REGISTER_ACTION turned up 19 more call sites needing the include: the 10 bank model headers under examples/bank/include/bank/models/ (only built with -DMORPH_BUILD_BANK_EXAMPLE=ON, off by default, which is why the default build never caught this), the 7 WASM-shadow bank model headers under examples/bank/gui_wasm/include/bank/models/, tests/qt/qt_test_models.hpp, and examples/forms/lab_model.hpp. Fix: add #include <morph/bridge.hpp> to every header that calls BRIDGE_REGISTER_ACTION, and document the requirement as a hard rule on registerActionExecutorOnce's declaration, on BRIDGE_REGISTER_ACTION's own doc comment, and symmetrically on ActionExecuteRegistry's doc comment in bridge.hpp. Verified: default ctest suite still passes 352/352 with no regressions. The bank example itself could not be built end-to-end in this environment (Lightweight's yaml-cpp dependency isn't provisioned, and even once it is, Lightweight fails to *compile* against this MSVC toolset independent of this fix) -- instead verified the exact link mechanism in isolation with a throwaway two-TU repro, confirming the predicted LNK2019 on registerActionExecutorOnce without the fix and a clean link with it. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Replaces hand-built wire::Envelope + RemoteServer plumbing with the framework's real client API, matching how examples/bank's GUI talks to its models. submit() is renamed submitIfValid() and now goes through BridgeHandler::executeJson (added in the previous commit) instead of a manually assembled envelope.
DynamicForm.qml now calls controller.submitIfValid() directly from revalidate() whenever the assembled body passes client-side checks, instead of waiting for a button click. Matches the live-recompute UX the framework's fielded-action API models, without requiring a compile-time set<&Action::field> hook per field.
Adds a Qt Quick Test driving DynamicForm through simulated field edits against a mock controller, asserting submitIfValid fires exactly once the form becomes valid and not before — without any button click.
The existing windeployqt POST_BUILD step only covered morph_forms_qml (the GUI app), not morph_forms_qml_tests. Running ctest -R forms_qml_logic outside a shell with Qt's bin/plugins already on PATH hung ~200s then crashed with STATUS_DLL_NOT_FOUND (missing Qt6QuickTestd.dll and, even with a full PATH, the offscreen QPA plugin the test forces via QT_QPA_PLATFORM=offscreen -- windeployqt's static analysis doesn't see that env-var-only platform selection, so it skipped deploying qoffscreend.dll by default). Fix: run windeployqt for morph_forms_qml_tests too, with --include-plugins qoffscreen forcing the plugin deployment windeployqt would otherwise omit. Verified ctest -R forms_qml_logic now passes in under a second with no Qt-related PATH/QT_PLUGIN_PATH setup at all. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Updates the forms demo README to match FormsController's new transport (Bridge/BridgeHandler via executeJson) and UX (auto-fire on valid edit, no submit button), replacing the outdated RemoteServer/wire::Envelope description.
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
The Docs CI job failed because ActionExecuteRegistry's registerAction, execute, and instance were missing @param/@return documentation, which FAIL_ON_WARNINGS turns into a build failure. Also merge the reactive forms design spec and implementation plan into a single docs/superpowers/2026-07-06-reactive-forms-bridge.md. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Rewrite the superpowers feature doc to describe only the existing behavior in present tense (no previous-state narration or task checklists), keeping it well under 500 lines. Record the documentation convention and the Doxygen FAIL_ON_WARNINGS local-repro steps in a new repo CLAUDE.md. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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.
No description provided.