Skip to content

feat(filter_protocol): Filter Editor SDK contract + registry service#122

Open
pabloinigoblasco wants to merge 1 commit into
mainfrom
gh/filter-registry-service
Open

feat(filter_protocol): Filter Editor SDK contract + registry service#122
pabloinigoblasco wants to merge 1 commit into
mainfrom
gh/filter-registry-service

Conversation

@pabloinigoblasco

@pabloinigoblasco pabloinigoblasco commented Jun 12, 2026

Copy link
Copy Markdown
Collaborator

Summary

SDK surface for the Filter Editor: the abstract FilterTransform contract plugins implement, the 12 builtin strategy classes vendored header-only, and the pj.filter_registry.v1 host service through which plugins register their classes and consumers resolve transforms by id at runtime.

What this PR delivers

  • pj_plugins/sdk/filter_transform.hpp — abstract FilterTransform interface. Streaming-friendly: calculateNextPoint (SISO), appendTail (chunked, default loops calculateNextPoint, classes override for O(Δsamples)), applyBatch (one-shot). Plus saveParams / loadParams (JSON) and clone(). POD inputs/outputs only (PJ::sdk::Point2 + std::string JSON).
  • pj_plugins/sdk/builtin_transforms.hpp — 12 strategies, header-only. Mirrors PJ3's TransformFunction_SISO catalogue:
    • NoneTransform, AbsoluteTransform, ScaleTransform, DerivativeTransform, IntegralTransform
    • MovingAverageTransform, MovingRMSTransform, MovingVarianceTransform
    • OutlierRemovalTransform, SamplesCounterTransform, BinaryFilterTransform, TimeSincePreviousTransform
  • pj_plugins/sdk/filter_transform_factory.hpp — id → (create_fn, delete_fn, library_owner) registry. create(id) returns a shared_ptr<FilterTransform> whose deleter pairs with the entry's deleter and pins the library_owner ref, so cross-DSO destruction happens on the side that did the new and the registering DSO stays loaded while any of its entries is reachable.
  • pj_plugins/sdk/filter_registry_abi.h + filter_registry_service.hpp — C ABI fat-pointer for pj.filter_registry.v1 plus the typed FilterRegistryView (registerTransform<Class>(id, owner) / create(id) / registeredIds()) and Traits for ServiceRegistry lookup.
  • pj_plugins/host/filter_registry_host.hpp — in-process adapter wrapping a FilterTransformFactory as the C-ABI service ctx. A host instantiates one, exposes it via ServiceRegistryBuilder, plugins consume it from their bind().
  • pj_base/point2.hpp — lift PJ::sdk::Point2 out of pj_base/builtin/image_annotations.hpp into its own header (struct layout unchanged). Lets filter-protocol pull the type without dragging in image-annotations.
  • Manifest tagsPluginDescriptor and RuntimeToolboxPlugin now carry a tags string vector parsed from manifest.json's "tags" array. Lets the host route generic actions (e.g. a plot's right-click "Apply Filter…") to whichever toolbox declares the matching tag.

Versioning

Additive vs the previous installed surface — no existing header, struct layout, or signature changes. Required release level when merged: MINOR.

Stack

  • pj-official-plugins PR — Filter Editor toolbox plugin.
  • PJ4 PR — Filter Editor host integration.

Test plan

  • ./build.sh + ctest: 44/44 pass.
  • Plugin author check: #include "pj_plugins/sdk/filter_transform.hpp" resolves transitively from plotjuggler_sdk::plugin_sdk.
  • Plugin author check: a toolbox that registers a class via the v1 service and asks for it back by id receives a working instance whose virtual calls dispatch to the registering DSO's vtable.

@pabloinigoblasco pabloinigoblasco changed the title feat(filter_protocol): FilterTransform contract + pj.filter_registry.v1 host service feat(filter_protocol): host-owned FilterTransformFactory via service Jun 12, 2026
@pabloinigoblasco pabloinigoblasco force-pushed the gh/filter-registry-service branch from cb85861 to c31f1c5 Compare June 12, 2026 14:13
@pabloinigoblasco pabloinigoblasco changed the title feat(filter_protocol): host-owned FilterTransformFactory via service feat(filter_protocol): Filter Editor SDK contract + registry service Jun 12, 2026
@pabloinigoblasco pabloinigoblasco force-pushed the gh/filter-registry-service branch from c31f1c5 to ae50933 Compare June 12, 2026 14:23
Exposes the FilterTransform contract and the FilterRegistryService as a
shared cross-DSO surface so the host (PJ4) and the Filter Editor toolbox
plugin can agree on a single set of builtin transforms — same registry,
same instances, no duplicated factories.

- pj_plugins/filter_protocol/sdk:
  - FilterTransform + builtin_transforms (12 vendored stateful operators:
    scale, offset, abs, derivative, integral, moving_average, moving_rms,
    moving_variance, outlier_removal, samples_counter, binary_filter,
    time_since_previous, none).
  - FilterTransformFactory: typed registry keyed by string id; create()
    returns shared_ptr<FilterTransform> with a deleter that pins the
    library_owner (cross-DSO lifetime safety).
  - FilterRegistryService C ABI + FilterRegistryView C++ wrapper that
    plugins use to register transforms during bind() and resolve them
    later. Live instances bridged via a static catalogue so the per-id
    deleter handed back to plugins can free them after the host shuts
    down.

- pj_plugins/host/filter_registry_host.hpp: thin adapter that wraps a
  FilterTransformFactory in the service vtable, with a noexcept-correct
  C ABI and idempotent unregister.
@pabloinigoblasco pabloinigoblasco force-pushed the gh/filter-registry-service branch from 6f44d81 to c3c9ec2 Compare June 13, 2026 18:41
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