[SUPERSEDED by #122] feat: FilterTransform contract; lift Point2; tags#120
Closed
pabloinigoblasco wants to merge 6 commits into
Closed
[SUPERSEDED by #122] feat: FilterTransform contract; lift Point2; tags#120pabloinigoblasco wants to merge 6 commits into
pabloinigoblasco wants to merge 6 commits into
Conversation
e70458e to
8bee0fb
Compare
…t tags
Add pj_plugins/filter_protocol/ — a header-only sub-module exposing
the Strategy contract for Filter Editor transforms. The SDK ships
only the abstract interface + registry; plugins provide the concrete
strategies and register them with the factory at load time.
Headers:
- pj_plugins/sdk/filter_transform.hpp — abstract
PJ::sdk::FilterTransform. Two streaming surfaces: calculateNextPoint
(SISO, PJ3 mirror) and appendTail (chunked; default loops
calculateNextPoint; override per-transform when running state
makes it O(Δsamples)). Plus saveParams / loadParams JSON, and
clone() for host hand-off across the plugin DSO boundary.
- pj_plugins/sdk/filter_transform_factory.hpp — registry singleton,
stable registration order, plus PJ_REGISTER_FILTER_TRANSFORM macro
for auto-register at static init.
Lift PJ::sdk::Point2 to its own header:
- pj_base/point2.hpp — generic 2D vocab type (double x, double y).
Was defined inside image_annotations.hpp; promote so the Filter
Editor transform contract can reuse it without an artificial
coupling to image annotations. image_annotations.hpp now just
includes the new header.
Surface manifest tags:
- PluginDescriptor / RuntimeToolboxPlugin gain a tags field,
parsed from the manifest's tags array. Lets the host route a
generic action — e.g. the plot's right-click 'Apply Filter…'
slot — to whichever installed toolbox declares the matching tag,
instead of hardcoding a plugin id in the host. Empty for plugins
whose manifest omits the array (backward compatible).
The pj_filter_sdk INTERFACE target is declared inline in
pj_plugins/CMakeLists.txt (alongside dialog_protocol). It's a
header-only sub-module with one target, so a dedicated
filter_protocol/CMakeLists.txt was overhead — kept the layout to
match dialog_protocol/ for header organisation, but the build wiring
is now where it belongs.
Wires pj_filter_sdk into the plugin SDK umbrella so plugin authors
get the contract transitively from plotjuggler_sdk::plugin_sdk.
Additive surface — no existing header / struct / ABI changes
(Point2's struct definition + ABI layout are unchanged; only its
file location moved). Required release level when merged: MINOR.
Version bump kept out of this PR for release coordination.
8bee0fb to
421ad1b
Compare
The Filter Editor plugin and the host (PJ4 app) need the same math to keep preview, layout-restore, and streaming render in lockstep. Until now each side had its own copy. This commit lifts the 12 concrete strategy classes plus the BinaryOp enum and the registerAllTransforms() factory hook into the SDK header so there is one source of truth. Plugins are dlopen'd RTLD_LOCAL, so each DSO still has its own factory singleton — what is unified is the code, not the runtime instances. JSON saveParams/loadParams remains the on-the-wire contract between plugin and host. Header is part of pj_filter_sdk; reaches plugin authors transitively via plotjuggler_sdk::plugin_sdk (no CMake changes needed).
…brobotics.com/client-projets/p.2026-plotjuggler/plotjuggler_core into feat/filter-transform-contract-sdk
Adds the pj.filter_registry.v1 host service so the plugin can register its FilterTransform classes into the host's single FilterTransformFactory during loaderInit and resolve them by id from the same registry — preview, layout restore, and the streaming read path all go through the same instances now. - filter_registry_abi.h: 5-slot C ABI vtable + service id + min-size pin. registration carries paired (factory_fn, deleter_fn) so destruction happens in the DSO that did the new; library_owner shared_ptr<void> pins that DSO for the entry's life. - filter_registry_service.hpp: typed View + Traits. registerTransform<C>() generates the trampolines from a C++ class. - filter_transform_factory.hpp: drop the global static singleton. Each entry now carries (create_fn, delete_fn, library_owner shared_ptr<void>). create() returns shared_ptr<FilterTransform> whose deleter pins owner. - builtin_transforms.hpp: drop registerAllTransforms() helper — the plugin walks the catalogue itself in loaderInit now. - include/pj_plugins/host/filter_registry_host.hpp: C-ABI adapter that wraps an in-process FilterTransformFactory as the service ctx. Trampolines bridge the C ABI to the C++ factory; an optional LibraryOwnerResolver bridges plugin-side void* tokens to host-side shared_ptr<void>. pj_filter_sdk now links pj_base for the C ABI primitives.
…brobotics.com/client-projets/p.2026-plotjuggler/plotjuggler_core into feat/filter-transform-contract-sdk
…casts Two compile errors in the previous commit: 1. std::function<void(FilterTransform*) noexcept> is ill-formed under C++20: std::function does not specialise on noexcept function types. Drop the qualifier; the no-throw contract is enforced at the C ABI boundary instead (PJ_filter_transform_deleter_fn is still noexcept). 2. The View's generated factory lambda did not declare noexcept, so the conversion to PJ_filter_transform_factory_fn (a noexcept function pointer) failed under conformant ABIs. Add the qualifier. Verified with a g++ -std=c++20 smoke-test round-trip: registerHost -> service fat pointer -> View::registerTransform<ScaleTransform> -> View::create -> loadParams -> calculateNextPoint returns the expected value.
Collaborator
Author
|
Superseded by #122 — Filter Editor SDK contract + registry service. Closing. |
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.
Summary
Three additive changes that together close PR #160's
160-B(duplicated transform catalogue + drift) and160-F(hardcoded plugin id in the host) review items, plus a vocab-type cleanup that drops the SDK's accidental double-definition of a 2D point.1.
pj_plugins/filter_protocol/— Filter Editor Strategy contractA new header-only sub-module exposing the abstract contract plugins implement for Filter Editor transforms. The SDK owns the interface + registry; concrete strategies (MovingAverage, Derivative, …) are provided by the plugin that ships them (today:
pj-official-plugins/toolbox_filter_editorin pj-official-plugins#141).pj_plugins/sdk/filter_transform.hpp— abstractPJ::sdk::FilterTransform. Two streaming surfaces:calculateNextPoint(SISO, PJ3 mirror) andappendTail(chunked; default loopscalculateNextPoint; override per-transform when running state makes it O(Δsamples)). PlussaveParams/loadParamsJSON, andclone()for host hand-off across the plugin DSO boundary.pj_plugins/sdk/filter_transform_factory.hpp— registry singleton with stable registration order.PJ_REGISTER_FILTER_TRANSFORM(Class)macro for auto-register at static init.pj_filter_sdkwires into the plugin SDK umbrella so plugin authors get the contract transitively fromplotjuggler_sdk::plugin_sdk.2.
pj_base/point2.hpp— liftPoint2out ofimage_annotations.hppPJ::sdk::Point2lived insidepj_base/builtin/image_annotations.hppas a 2D-pixel-coordinates point. The Filter Editor contract needs the same plain{double x; double y;}shape for time/value samples but has no relation to image annotations — including that header just for the type would be the wrong kind of coupling.This PR moves the struct to its own
pj_base/point2.hpp.image_annotations.hppnow#includes the new header. The struct definition + ABI layout are unchanged; the only difference is the file location.abidiffshows additions only.3. Surface manifest
tagsinRuntimeToolboxPluginPluginDescriptoralready hadcapabilities: vector<string>(parsed from the manifest's"capabilities"key). It did not parse the manifest's"tags"array — Pmarin's plot_action tag in the Filter Editor plugin'smanifest.jsonwas dead metadata.This PR adds a parallel
tags: vector<string>field, parsed from the manifest's"tags"array, surfaced onPluginDescriptorand onRuntimeToolboxPlugin. Empty when the manifest omits the array (fully backward compatible).This lets the host route generic actions — e.g. the plot's right-click "Apply Filter…" slot in PJ4#161 — to whichever installed toolbox declares the matching tag, instead of hardcoding a plugin id in the host. Closes
160-F.Stack
FilterTransformstrategies, derived fromPJ::sdk::FilterTransform, registered via the factory atloaderInit. Manifest carries"tags": ["plot_action", ...].shared_ptr<sdk::FilterTransform>directly; the parallelIncrementalCurveTransformhost hierarchy is removed;launchFilterEditorroutes byplot_actiontag instead of literal plugin id.Both stack on this PR. Their CI on the matrix is red until this lands.
Versioning
Additive — no existing header, struct layout, or ABI signature changes. Required release level when merged: MINOR. Version bump intentionally NOT included; coordinated at release-tag time per the SDK versioning policy.
Test plan
abidiffagainst the previous baseline shows additions only.#include "pj_plugins/sdk/filter_transform.hpp"resolves transitively fromplotjuggler_sdk::plugin_sdk."tags": ["plot_action"]shows up inRuntimeToolboxPlugin::tagsafterscanDirectory.