docs: settle source-plugin implementation details in the spec
This commit is contained in:
1 parent
5bc14b1163
commit
71b904a93b
1 file changed
+20
-9
@@ -42,19 +42,24 @@ later plugins need.
|
|||||||
(a TOML table), the `--source-opt` form, and what a config widget reads and writes.
|
(a TOML table), the `--source-opt` form, and what a config widget reads and writes.
|
||||||
- **`Frame`**: source-neutral, mirrors `udps_frame_t`: `counter`, `lost`, `late`,
|
- **`Frame`**: source-neutral, mirrors `udps_frame_t`: `counter`, `lost`, `late`,
|
||||||
`recv_time`, `publish_mode`, `num_samples`, `signals[]` (the existing `SignalInfo`) and
|
`recv_time`, `publish_mode`, `num_samples`, `signals[]` (the existing `SignalInfo`) and
|
||||||
`values[]` (doubles). The hole, backfill and time-base logic needs `counter/lost/late`; a
|
`values[]` (doubles). `signals` and `values` are pointers into the source's own buffers,
|
||||||
|
valid only for the duration of `on_data`; `Acquisition` copies what it keeps. The hole, backfill and time-base logic needs `counter/lost/late`; a
|
||||||
source with no counter supplies a running counter and `lost = 0`. `Frame::value(sig, k,
|
source with no counter supplies a running counter and `lost = 0`. `Frame::value(sig, k,
|
||||||
col)` replaces `udps_frame_value`.
|
col)` replaces `udps_frame_value`.
|
||||||
- **`DataSource`**: the per-connection object.
|
- **`DataSource`**: the per-connection object.
|
||||||
- `open()`, `poll(timeout_ms)`, `close()`.
|
- `open()`, `poll(timeout_ms)`, `close()`.
|
||||||
- `stats()` returns the counters now in `StreamStats`; `connected()` reports link state.
|
- `stats()` returns the counters now in `StreamStats`; `connected()` reports link state.
|
||||||
- `post(Command)`: thread-safe queue, drained inside `poll()`.
|
- `post(Command)`: thread-safe queue, drained inside `poll()`. `Command` is
|
||||||
|
`std::function<void()>`.
|
||||||
- `set_datagram_tap(fn)`: optional; lets UDP-based sources feed the raw-packet capture.
|
- `set_datagram_tap(fn)`: optional; lets UDP-based sources feed the raw-packet capture.
|
||||||
- Output goes to a `SourceSink` (`on_config`, `on_data`, `on_event`) called inside
|
- Output goes to a `SourceSink` (`on_config`, `on_data`, `on_event`) called inside
|
||||||
`poll()`, as `udps_client` does today.
|
`poll()`, as `udps_client` does today.
|
||||||
- **`SourceKind`**: factory and UI description of one plugin type: `id`, `display_name`,
|
- **`SourceKind`**: factory and UI description of one plugin type: `id`, `display_name`,
|
||||||
`identity(cfg)`, `make(cfg)`, `make_config_form(cfg)` (a `GtkWidget*` plus a `read()`
|
`identity(cfg)`, `make(cfg)`, `make_config_form()` and `make_panels(source)` (each
|
||||||
closure) and `make_panels(source)` (each `{id, title, GtkWidget*}`).
|
`{id, title, GtkWidget*}`). `make_config_form()` takes no argument: the chooser calls
|
||||||
|
`form.write(cfg)` to fill the form. A `ConfigForm` is a list of `AdwPreferencesRow` widgets
|
||||||
|
plus `write` / `read` / `valid` / `on_change` closures, so the chooser can place the rows in
|
||||||
|
its own group and gate its Connect button on `valid()`.
|
||||||
- **`SourceRegistry`**: filled by an explicit `register_builtin_sources()` call. No
|
- **`SourceRegistry`**: filled by an explicit `register_builtin_sources()` call. No
|
||||||
static-init self-registration (linkers can drop it). A future `dlopen` loader would only
|
static-init self-registration (linkers can drop it). A future `dlopen` loader would only
|
||||||
call `register_kind()`.
|
call `register_kind()`.
|
||||||
@@ -62,7 +67,8 @@ later plugins need.
|
|||||||
### 2. Acquisition and the UDPS plugin
|
### 2. Acquisition and the UDPS plugin
|
||||||
|
|
||||||
- `Acquisition` takes a `std::unique_ptr<DataSource>` instead of building a `udps_client_t`
|
- `Acquisition` takes a `std::unique_ptr<DataSource>` instead of building a `udps_client_t`
|
||||||
and implements `SourceSink`; the four trampolines go away.
|
and implements `SourceSink`; it creates the source lazily in `start()`, from the kind and
|
||||||
|
`SourceConfig` it was given; the four trampolines go away.
|
||||||
- `on_config` / `on_data` change only in the type they read. Time base, holes, backfill,
|
- `on_config` / `on_data` change only in the type they read. Time base, holes, backfill,
|
||||||
decimation, trigger and math code are untouched.
|
decimation, trigger and math code are untouched.
|
||||||
- `run()` calls `source_->poll(50)` and copies `source_->stats()` into
|
- `run()` calls `source_->poll(50)` and copies `source_->stats()` into
|
||||||
@@ -81,7 +87,8 @@ later plugins need.
|
|||||||
interface) moves into the UDPS plugin. The dialog keeps the known-sources list, buffer
|
interface) moves into the UDPS plugin. The dialog keeps the known-sources list, buffer
|
||||||
size, relative time and capture ring size.
|
size, relative time and capture ring size.
|
||||||
- **Capability panels**: after the source is created the app calls `make_panels()` and adds
|
- **Capability panels**: after the source is created the app calls `make_panels()` and adds
|
||||||
each panel as a page of a "Source" stack in the side area. A panel is insensitive when
|
each panel as a page of the existing `side_stack` (the side area's page stack, owned by
|
||||||
|
the tab switcher). A panel is insensitive when
|
||||||
disconnected (disabled, not hidden; the tab switcher owns visibility). A source with no
|
disconnected (disabled, not hidden; the tab switcher owns visibility). A source with no
|
||||||
panels adds no tab; UDPS has none. Panels call `source->post(Command)`, never the source
|
panels adds no tab; UDPS has none. Panels call `source->post(Command)`, never the source
|
||||||
directly, so cross-thread safety lives in one place. A helper kit for common panels (DIO
|
directly, so cross-thread safety lives in one place. A helper kit for common panels (DIO
|
||||||
@@ -90,8 +97,10 @@ later plugins need.
|
|||||||
- **Config / CLI**: `Config` gains `source_kind` (default `udps`) and a `SourceConfig`.
|
- **Config / CLI**: `Config` gains `source_kind` (default `udps`) and a `SourceConfig`.
|
||||||
`--server/--port/--multicast/--interface` populate the UDPS entries. `--source NAME` and
|
`--server/--port/--multicast/--interface` populate the UDPS entries. `--source NAME` and
|
||||||
repeatable `--source-opt k=v` work for any kind. `--help` lists the registered kinds.
|
repeatable `--source-opt k=v` work for any kind. `--help` lists the registered kinds.
|
||||||
- **Sessions**: file `<kind>_<identity>.toml` with the source's config in a `[source]`
|
- **Sessions**: the source's config is stored as top-level TOML keys, `source_kind` and
|
||||||
table. Legacy `host_port.toml` is read as `udps`; nothing is migrated destructively.
|
`source_opt_<key>`, written only for non-UDPS kinds (a UDPS session file is unchanged, so
|
||||||
|
legacy `host_port.toml` files read as `udps` with nothing migrated). It is not a `[source]`
|
||||||
|
table. A non-UDPS session file is named by a pseudo-host `<kind>-<identity>` with port 1.
|
||||||
- **Mocks**: `tools/mock_udpstreamer.py` remains the UDPS mock. Each later plugin ships its
|
- **Mocks**: `tools/mock_udpstreamer.py` remains the UDPS mock. Each later plugin ships its
|
||||||
own mock under `tools/` so the headless self-check keeps working.
|
own mock under `tools/` so the headless self-check keeps working.
|
||||||
|
|
||||||
@@ -99,7 +108,9 @@ later plugins need.
|
|||||||
|
|
||||||
- This is a pure refactor for UDPS: the existing headless self-check must read exactly as on
|
- This is a pure refactor for UDPS: the existing headless self-check must read exactly as on
|
||||||
`main` -- exactly three build warnings, no `Gtk-CRITICAL` (see `docs/claude/verification.md`).
|
`main` -- exactly three build warnings, no `Gtk-CRITICAL` (see `docs/claude/verification.md`).
|
||||||
- New probe `UDPSCOPE_PROBE_SOURCES`, extending the probe/dump in `src/ui.cpp` rather than
|
- New probe `UDPSCOPE_PROBE_SOURCE_KINDS` (`UDPSCOPE_PROBE_SOURCES` is already the chooser
|
||||||
|
discovery probe). Its value is a delay in ms, and its presence also registers the stub
|
||||||
|
`probe` kind. It extends the probe/dump in `src/ui.cpp` rather than
|
||||||
adding a harness. It checks that the registry lists its kinds, that a config form
|
adding a harness. It checks that the registry lists its kinds, that a config form
|
||||||
round-trips its `SourceConfig`, and -- with a stub test-only kind carrying one panel --
|
round-trips its `SourceConfig`, and -- with a stub test-only kind carrying one panel --
|
||||||
that the panel's tab is built, insensitive while disconnected, and that a posted command is
|
that the panel's tab is built, insensitive while disconnected, and that a posted command is
|
||||||
|
|||||||
Reference in new issue
Block a user