Skip to content

Commit c31f1c5

Browse files
feat(filter_protocol): FilterTransform SDK contract + pj.filter_registry.v1 service
Replaces the originally-proposed split where the host carried its own copy of the FilterTransform catalogue. Now ONE FilterTransformFactory exists at runtime, owned by the host, populated by the Filter Editor plugin via the new pj.filter_registry.v1 service. Preview, layout-restore, and the streaming read path all resolve through the same instances — no math drift possible. Contents: - Abstract contract: PJ::sdk::FilterTransform (filter_transform.hpp) - The 12 builtin strategies vendored as header-only (builtin_transforms.hpp): NoneTransform / AbsoluteTransform / ScaleTransform / DerivativeTransform / IntegralTransform / MovingAverageTransform / MovingRMSTransform / MovingVarianceTransform / OutlierRemovalTransform / SamplesCounterTransform / BinaryFilterTransform / TimeSincePreviousTransform - FilterTransformFactory: keeps (create_fn, delete_fn, library_owner) per entry. Cross-DSO destruction goes through the registered deleter; library_owner pins the registering DSO while any of its entries is live. - New host service pj.filter_registry.v1: C ABI vtable + Traits + C++ View. Plugins receive the View at bind() and register their classes into the host's factory; host code resolves via factory.create(id). - FilterRegistryHost: in-process adapter that wraps a FilterTransformFactory as the C-ABI service ctx, with paired thunks and a LibraryOwnerResolver. - Lift Point2 from pj_base/builtin/image_annotations.hpp to pj_base/point2.hpp (unchanged ABI; same struct). - Surface manifest 'tags' array on PluginDescriptor + RuntimeToolboxPlugin. Versioning: additive — no existing header, struct layout, or ABI signature changes; required release level when merged is MINOR. Verified locally: build green, 44/44 tests pass.
1 parent 9003e55 commit c31f1c5

13 files changed

Lines changed: 1563 additions & 7 deletions

File tree

pj_base/include/pj_base/builtin/image_annotations.hpp

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include <string>
2020
#include <vector>
2121

22+
#include "pj_base/point2.hpp"
2223
#include "pj_base/types.hpp"
2324

2425
namespace PJ {
@@ -32,12 +33,8 @@ enum class AnnotationTopology : uint8_t {
3233
kLineLoop, ///< Like LineStrip but closes back to the first point. 4-point loop = rectangle.
3334
};
3435

35-
/// 2D point in image-pixel coordinates (origin top-left).
36-
struct Point2 {
37-
double x = 0.0;
38-
double y = 0.0;
39-
bool operator==(const Point2&) const = default;
40-
};
36+
// `Point2` lives in pj_base/point2.hpp (generic 2D vocab type). In this header
37+
// it's used in image-pixel coordinates (origin top-left).
4138

4239
/// 8-bit per-channel RGBA color. a=0 means transparent / disabled.
4340
struct ColorRGBA {

pj_base/include/pj_base/point2.hpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// Copyright 2026 Davide Faconti
2+
// SPDX-License-Identifier: Apache-2.0
3+
#pragma once
4+
5+
// Plain (x, y) 2D point. Generic double-precision vocab type — used by image
6+
// annotations (pixel coordinates), Filter Editor transforms (time/value
7+
// samples), and any other 2D context where a tagged shape would be overkill.
8+
// The semantic of x / y is owned by the caller.
9+
10+
namespace PJ::sdk {
11+
12+
struct Point2 {
13+
double x = 0.0;
14+
double y = 0.0;
15+
bool operator==(const Point2&) const = default;
16+
};
17+
18+
} // namespace PJ::sdk

pj_plugins/CMakeLists.txt

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,25 @@ target_link_libraries(pj_plugin_loader_detail PUBLIC pj_base)
1717

1818
add_subdirectory(dialog_protocol)
1919

20+
# Filter Editor transform contract (header-only) — plugins implement the 12
21+
# concrete strategies and self-register with the factory at load time. See
22+
# pj_plugins/filter_protocol/include/pj_plugins/sdk/filter_transform.hpp.
23+
add_library(pj_filter_sdk INTERFACE)
24+
target_compile_features(pj_filter_sdk INTERFACE cxx_std_20)
25+
target_include_directories(pj_filter_sdk INTERFACE
26+
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/filter_protocol/include>
27+
$<INSTALL_INTERFACE:include>
28+
)
29+
# Builtin strategies (in the plugin) use nlohmann/json for saveParams /
30+
# loadParams; propagate the dep so consumers get it transitively. Also pulls
31+
# pj_base for the C ABI primitives (PJ_string_view_t, PJ_error_t, PJ_NOEXCEPT)
32+
# referenced by the filter registry service.
33+
target_link_libraries(pj_filter_sdk INTERFACE pj_base nlohmann_json::nlohmann_json)
34+
set_target_properties(pj_filter_sdk PROPERTIES EXPORT_NAME filter_sdk)
35+
add_library(plotjuggler_sdk::filter_sdk ALIAS pj_filter_sdk)
36+
install(DIRECTORY filter_protocol/include/ DESTINATION include)
37+
install(TARGETS pj_filter_sdk EXPORT plotjuggler_sdkTargets ARCHIVE DESTINATION lib LIBRARY DESTINATION lib INCLUDES DESTINATION include)
38+
2039
# ---------------------------------------------------------------------------
2140
# pj_plugin_sdk — umbrella INTERFACE library that exposes the full plugin-author
2241
# SDK surface: C++ SDK headers (MessageParserPluginBase, ObjectIngestPolicy,
@@ -29,7 +48,7 @@ target_include_directories(pj_plugin_sdk INTERFACE
2948
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
3049
$<INSTALL_INTERFACE:include>
3150
)
32-
target_link_libraries(pj_plugin_sdk INTERFACE pj_base pj_dialog_sdk)
51+
target_link_libraries(pj_plugin_sdk INTERFACE pj_base pj_dialog_sdk pj_filter_sdk)
3352
set_target_properties(pj_plugin_sdk PROPERTIES EXPORT_NAME plugin_sdk)
3453
add_library(plotjuggler_sdk::plugin_sdk ALIAS pj_plugin_sdk)
3554

0 commit comments

Comments
 (0)