Rename project from xserial to pipeview
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
56
AGENTS.md
56
AGENTS.md
@@ -8,25 +8,25 @@
|
||||
|
||||
## Project Structure
|
||||
|
||||
`xserial` is a Rust workspace. The root `Cargo.toml` defines four crates in `crates/`, with dependencies flowing:
|
||||
`pipeview` is a Rust workspace. The root `Cargo.toml` defines four crates in `crates/`, with dependencies flowing:
|
||||
|
||||
```
|
||||
xserial-core (no internal deps — transport, framing, protocol, pipeline)
|
||||
pipeview-core (no internal deps — transport, framing, protocol, pipeline)
|
||||
↑
|
||||
xserial-client (depends on xserial-core — sessions, history, commands, Lua)
|
||||
pipeview-client (depends on pipeview-core — sessions, history, commands, Lua)
|
||||
↑ ↑
|
||||
xserial-gui xserial-tui
|
||||
(both depend on xserial-core AND xserial-client)
|
||||
pipeview-gui pipeview-tui
|
||||
(both depend on pipeview-core AND pipeview-client)
|
||||
```
|
||||
|
||||
| Crate | Type | What goes here |
|
||||
|-------|------|---------------|
|
||||
| `xserial-core` | library (`src/lib.rs`) | `transport/`, `frame/`, `protocol/`, `pipeline.rs` — protocol and I/O. Integration tests: `tests/pipeline.rs`. |
|
||||
| `xserial-client` | library (`src/lib.rs`) | `session.rs`, `manager.rs`, `config.rs`, `history.rs`, `lua/` — state management and Lua bindings. Integration tests: `tests/session_lifecycle.rs`, `tests/lua_tests.rs`. |
|
||||
| `xserial-gui` | binary (`src/main.rs`) | egui/eframe app. Panels in `src/panels/`. Font helpers in `src/ui_fonts.rs`. Profiling in `src/perf.rs`. |
|
||||
| `xserial-tui` | binary (`src/main.rs`) | ratatui/crossterm app. **Still a placeholder** — zero tests, not at feature parity with GUI. |
|
||||
| `pipeview-core` | library (`src/lib.rs`) | `transport/`, `frame/`, `protocol/`, `pipeline.rs` — protocol and I/O. Integration tests: `tests/pipeline.rs`. |
|
||||
| `pipeview-client` | library (`src/lib.rs`) | `session.rs`, `manager.rs`, `config.rs`, `history.rs`, `lua/` — state management and Lua bindings. Integration tests: `tests/session_lifecycle.rs`, `tests/lua_tests.rs`. |
|
||||
| `pipeview-gui` | binary (`src/main.rs`) | egui/eframe app. Panels in `src/panels/`. Font helpers in `src/ui_fonts.rs`. Profiling in `src/perf.rs`. |
|
||||
| `pipeview-tui` | binary (`src/main.rs`) | ratatui/crossterm app. **Still a placeholder** — zero tests, not at feature parity with GUI. |
|
||||
|
||||
**Module boundaries**: transport/protocol → `xserial-core`. Session/Lua → `xserial-client`. UI state → `xserial-gui` or `xserial-tui`. Never put I/O logic in the UI crates, never put UI state in the client crate.
|
||||
**Module boundaries**: transport/protocol → `pipeview-core`. Session/Lua → `pipeview-client`. UI state → `pipeview-gui` or `pipeview-tui`. Never put I/O logic in the UI crates, never put UI state in the client crate.
|
||||
|
||||
## Build, Test, and Development Commands
|
||||
|
||||
@@ -40,21 +40,21 @@ cargo clippy --workspace --all-targets -- -D warnings # lint gate
|
||||
**Run specific tests:**
|
||||
|
||||
```bash
|
||||
cargo test -p xserial-core -- tcp_line_text_utf8
|
||||
cargo test -p xserial-client -- session_echo_send_and_read
|
||||
cargo test -p xserial-core -- --nocapture # show test output
|
||||
cargo test -p pipeview-core -- tcp_line_text_utf8
|
||||
cargo test -p pipeview-client -- session_echo_send_and_read
|
||||
cargo test -p pipeview-core -- --nocapture # show test output
|
||||
|
||||
# Integration tests only
|
||||
cargo test -p xserial-core --test pipeline
|
||||
cargo test -p xserial-client --test session_lifecycle
|
||||
cargo test -p xserial-client --test lua_tests
|
||||
cargo test -p pipeview-core --test pipeline
|
||||
cargo test -p pipeview-client --test session_lifecycle
|
||||
cargo test -p pipeview-client --test lua_tests
|
||||
```
|
||||
|
||||
**Launch:**
|
||||
|
||||
```bash
|
||||
cargo run -p xserial-gui
|
||||
cargo run -p xserial-tui
|
||||
cargo run -p pipeview-gui
|
||||
cargo run -p pipeview-tui
|
||||
```
|
||||
|
||||
## Environment & Configuration
|
||||
@@ -62,8 +62,8 @@ cargo run -p xserial-tui
|
||||
### Tracing (all entrypoints)
|
||||
|
||||
```bash
|
||||
RUST_LOG=info cargo run -p xserial-gui
|
||||
RUST_LOG=xserial_gui::perf=debug cargo run -p xserial-gui
|
||||
RUST_LOG=info cargo run -p pipeview-gui
|
||||
RUST_LOG=pipeview_gui::perf=debug cargo run -p pipeview-gui
|
||||
```
|
||||
|
||||
`tracing_subscriber::EnvFilter::from_default_env()` reads `RUST_LOG`. The workspace dep `tracing-subscriber` has `features = ["env-filter"]`.
|
||||
@@ -71,11 +71,11 @@ RUST_LOG=xserial_gui::perf=debug cargo run -p xserial-gui
|
||||
### GUI Profiling
|
||||
|
||||
```bash
|
||||
RUST_LOG=xserial_gui::perf=info XSERIAL_GUI_PROFILE=1 cargo run -p xserial-gui
|
||||
XSERIAL_GUI_PROFILE_INTERVAL_MS=500 cargo run -p xserial-gui # custom interval (default 1s)
|
||||
RUST_LOG=pipeview_gui::perf=info XSERIAL_GUI_PROFILE=1 cargo run -p pipeview-gui
|
||||
XSERIAL_GUI_PROFILE_INTERVAL_MS=500 cargo run -p pipeview-gui # custom interval (default 1s)
|
||||
```
|
||||
|
||||
Profiling logs go to target `xserial_gui::perf`.
|
||||
Profiling logs go to target `pipeview_gui::perf`.
|
||||
|
||||
### State & Config File Paths (runtime, not compile-time)
|
||||
|
||||
@@ -83,9 +83,9 @@ Uses `env::consts::OS` + env vars — no `cfg(target_os)` gating for path resolu
|
||||
|
||||
| Platform | Root config path |
|
||||
|----------|-----------------|
|
||||
| Linux | `$XDG_CONFIG_HOME/xserial/` or `~/.config/xserial/` |
|
||||
| macOS | `~/Library/Application Support/xserial/` |
|
||||
| Windows | `%APPDATA%\xserial\` |
|
||||
| Linux | `$XDG_CONFIG_HOME/pipeview/` or `~/.config/pipeview/` |
|
||||
| macOS | `~/Library/Application Support/pipeview/` |
|
||||
| Windows | `%APPDATA%\pipeview\` |
|
||||
|
||||
State files: `gui-state.json`, `tui-state.json`, `font-settings.json`.
|
||||
|
||||
@@ -120,9 +120,9 @@ Standard Rust conventions (`cargo fmt`). No crate-level lint attrs, no `[lints]`
|
||||
- **No feature flags** — zero `[features]` in any `Cargo.toml`. No `#[cfg(feature)]` in any source.
|
||||
- **No build scripts** — zero `build.rs` files. No codegen. No `include!`/`include_str!`/`include_bytes!`.
|
||||
- **All `unsafe` is test-only** — constructing noop wakers for poll-based unit tests in `transport/`. No non-test `unsafe` anywhere.
|
||||
- **`xserial-tui` is a stub** — no tests, minimal implementation. GUI is the primary target.
|
||||
- **`pipeview-tui` is a stub** — no tests, minimal implementation. GUI is the primary target.
|
||||
- **Platform font directories** use `#[cfg(target_os)]` in `ui_fonts.rs` (three blocks: Windows, macOS, Linux/BSD).
|
||||
- **`tokio` features differ by build**: `xserial-client` uses `["sync", "time"]` for production, `["full"]` for dev-dependencies (tests need net/IO).
|
||||
- **`tokio` features differ by build**: `pipeview-client` uses `["sync", "time"]` for production, `["full"]` for dev-dependencies (tests need net/IO).
|
||||
|
||||
## Commit & PR Guidelines
|
||||
|
||||
|
||||
136
Cargo.lock
generated
136
Cargo.lock
generated
@@ -3262,6 +3262,74 @@ dependencies = [
|
||||
"futures-io",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pipeview-client"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"mlua",
|
||||
"pipeview-core",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"thiserror 2.0.18",
|
||||
"tokio",
|
||||
"tracing",
|
||||
"tracing-subscriber",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pipeview-core"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"bytes",
|
||||
"hex",
|
||||
"nom 8.0.0",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"serialport",
|
||||
"thiserror 2.0.18",
|
||||
"tokio",
|
||||
"tokio-serial",
|
||||
"tracing",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pipeview-gui"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"eframe",
|
||||
"egui",
|
||||
"egui_plot",
|
||||
"hex",
|
||||
"pipeview-client",
|
||||
"pipeview-core",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"tokio",
|
||||
"tracing",
|
||||
"tracing-subscriber",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pipeview-tui"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"crossterm 0.28.1",
|
||||
"hex",
|
||||
"image",
|
||||
"mlua",
|
||||
"pipeview-client",
|
||||
"pipeview-core",
|
||||
"ratatui",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"tokio",
|
||||
"tracing",
|
||||
"tracing-appender",
|
||||
"tracing-subscriber",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pkg-config"
|
||||
version = "0.3.33"
|
||||
@@ -5750,74 +5818,6 @@ version = "0.8.28"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3ae8337f8a065cfc972643663ea4279e04e7256de865aa66fe25cec5fb912d3f"
|
||||
|
||||
[[package]]
|
||||
name = "xserial-client"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"mlua",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"thiserror 2.0.18",
|
||||
"tokio",
|
||||
"tracing",
|
||||
"tracing-subscriber",
|
||||
"xserial-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "xserial-core"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"bytes",
|
||||
"hex",
|
||||
"nom 8.0.0",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"serialport",
|
||||
"thiserror 2.0.18",
|
||||
"tokio",
|
||||
"tokio-serial",
|
||||
"tracing",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "xserial-gui"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"eframe",
|
||||
"egui",
|
||||
"egui_plot",
|
||||
"hex",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"tokio",
|
||||
"tracing",
|
||||
"tracing-subscriber",
|
||||
"xserial-client",
|
||||
"xserial-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "xserial-tui"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"crossterm 0.28.1",
|
||||
"hex",
|
||||
"image",
|
||||
"mlua",
|
||||
"ratatui",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"tokio",
|
||||
"tracing",
|
||||
"tracing-appender",
|
||||
"tracing-subscriber",
|
||||
"xserial-client",
|
||||
"xserial-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "yoke"
|
||||
version = "0.8.2"
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
[workspace]
|
||||
resolver = "2"
|
||||
members = [
|
||||
"crates/xserial-core",
|
||||
"crates/xserial-client",
|
||||
"crates/xserial-tui",
|
||||
"crates/xserial-gui",
|
||||
"crates/pipeview-core",
|
||||
"crates/pipeview-client",
|
||||
"crates/pipeview-tui",
|
||||
"crates/pipeview-gui",
|
||||
]
|
||||
|
||||
[workspace.dependencies]
|
||||
|
||||
56
README.md
56
README.md
@@ -1,4 +1,4 @@
|
||||
# xserial
|
||||
# pipeview
|
||||
|
||||
**跨平台串口 / TCP / UDP 数据观测工具** — 可配置分帧、协议解码、多会话管理、实时波形绘图,单二进制零依赖。
|
||||
|
||||
@@ -89,8 +89,8 @@
|
||||
|
||||
- **自定义分帧器** — 实现 `feed(bytes)`、`flush()`、`reset()`、`pending_len()` 四个函数
|
||||
- **自定义解码器** — 实现 `decode(frame)` 函数,返回 text/hex/plot/binary 四种类型
|
||||
- **会话 API** — `xserial.open()` 创建 Session、`session:on_data()` 事件回调、`session:send()` 发送数据
|
||||
- **工具函数** — `xserial.list_ports()`、`xserial.sleep(ms)`、`xserial.poll(limit)`、`xserial.log(msg)`
|
||||
- **会话 API** — `pipeview.open()` 创建 Session、`session:on_data()` 事件回调、`session:send()` 发送数据
|
||||
- **工具函数** — `pipeview.list_ports()`、`pipeview.sleep(ms)`、`pipeview.poll(limit)`、`pipeview.log(msg)`
|
||||
|
||||
### 快捷键
|
||||
|
||||
@@ -125,11 +125,11 @@
|
||||
|
||||
```bash
|
||||
# 克隆项目
|
||||
git clone https://github.com/your-org/xserial.git
|
||||
cd xserial
|
||||
git clone https://github.com/your-org/pipeview.git
|
||||
cd pipeview
|
||||
|
||||
# 编译运行
|
||||
cargo run -p xserial-gui
|
||||
cargo run -p pipeview-gui
|
||||
|
||||
# 运行测试
|
||||
cargo test --workspace # ~308 个测试
|
||||
@@ -139,9 +139,9 @@ cargo clippy --workspace --all-targets -- -D warnings
|
||||
### 发布构建
|
||||
|
||||
```bash
|
||||
cargo build -p xserial-gui --release
|
||||
# 二进制位于 target/release/xserial-gui (Linux/macOS)
|
||||
# 或 target/release/xserial-gui.exe (Windows)
|
||||
cargo build -p pipeview-gui --release
|
||||
# 二进制位于 target/release/pipeview-gui (Linux/macOS)
|
||||
# 或 target/release/pipeview-gui.exe (Windows)
|
||||
```
|
||||
|
||||
---
|
||||
@@ -168,7 +168,7 @@ Listening on 127.0.0.1:8091, waiting for connections...
|
||||
|
||||
### 步骤 2:配置 Session
|
||||
|
||||
在 xserial-gui 中创建 Session:
|
||||
在 pipeview-gui 中创建 Session:
|
||||
|
||||
| 配置项 | 值 |
|
||||
|--------|-----|
|
||||
@@ -277,23 +277,23 @@ return {
|
||||
|
||||
```
|
||||
┌──────────────────────────────────────────────────┐
|
||||
│ xserial-gui (egui) xserial-tui (ratatui) │
|
||||
│ pipeview-gui (egui) pipeview-tui (ratatui) │
|
||||
├──────────────────────────────────────────────────┤
|
||||
│ xserial-client │
|
||||
│ pipeview-client │
|
||||
│ SessionManager · Session · Config · History │
|
||||
│ Lua Runtime (mlua / LuaJIT) │
|
||||
├──────────────────────────────────────────────────┤
|
||||
│ xserial-core │
|
||||
│ pipeview-core │
|
||||
│ Transport ──▶ Frame ──▶ Protocol ──▶ Pipeline │
|
||||
└──────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
| Crate | 类型 | 职责 |
|
||||
|-------|------|------|
|
||||
| `xserial-core` | library | 传输层(Serial/TCP/UDP)、分帧器(Line/Fixed/Length/COBS/Mixed/Lua)、协议解码器(Text/Hex/Plot)、MultiPipeline |
|
||||
| `xserial-client` | library | Session 生命周期管理、SessionManager、事件广播(tokio broadcast)、RingBuffer 历史、Lua 运行时及会话 API |
|
||||
| `xserial-gui` | binary | egui 桌面应用,包含 sidebar/config/console/text/hex/plot 面板、键盘快捷键、字体管理、性能分析 |
|
||||
| `xserial-tui` | binary | ratatui 终端应用(功能未对齐 GUI,仍在开发中) |
|
||||
| `pipeview-core` | library | 传输层(Serial/TCP/UDP)、分帧器(Line/Fixed/Length/COBS/Mixed/Lua)、协议解码器(Text/Hex/Plot)、MultiPipeline |
|
||||
| `pipeview-client` | library | Session 生命周期管理、SessionManager、事件广播(tokio broadcast)、RingBuffer 历史、Lua 运行时及会话 API |
|
||||
| `pipeview-gui` | binary | egui 桌面应用,包含 sidebar/config/console/text/hex/plot 面板、键盘快捷键、字体管理、性能分析 |
|
||||
| `pipeview-tui` | binary | ratatui 终端应用(功能未对齐 GUI,仍在开发中) |
|
||||
|
||||
**依赖方向:** `core ← client ← {gui, tui}`
|
||||
|
||||
@@ -316,9 +316,9 @@ GUI 状态自动保存,路径遵循各平台规范:
|
||||
|
||||
| 平台 | 路径 |
|
||||
|------|------|
|
||||
| Linux | `$XDG_CONFIG_HOME/xserial/gui-state.json` 或 `~/.config/xserial/gui-state.json` |
|
||||
| macOS | `~/Library/Application Support/xserial/gui-state.json` |
|
||||
| Windows | `%APPDATA%\xserial\gui-state.json` |
|
||||
| Linux | `$XDG_CONFIG_HOME/pipeview/gui-state.json` 或 `~/.config/pipeview/gui-state.json` |
|
||||
| macOS | `~/Library/Application Support/pipeview/gui-state.json` |
|
||||
| Windows | `%APPDATA%\pipeview\gui-state.json` |
|
||||
|
||||
持久化的内容包括:Session 配置(传输参数、管线设置)、日志开关及路径、活动标签页、显示选项。
|
||||
|
||||
@@ -343,8 +343,8 @@ python tools/test_drone.py --rate 10 --port 8092
|
||||
### 性能分析
|
||||
|
||||
```bash
|
||||
RUST_LOG=xserial_gui::perf=info XSERIAL_GUI_PROFILE=1 cargo run -p xserial-gui
|
||||
XSERIAL_GUI_PROFILE_INTERVAL_MS=500 cargo run -p xserial-gui
|
||||
RUST_LOG=pipeview_gui::perf=info XSERIAL_GUI_PROFILE=1 cargo run -p pipeview-gui
|
||||
XSERIAL_GUI_PROFILE_INTERVAL_MS=500 cargo run -p pipeview-gui
|
||||
```
|
||||
|
||||
输出每帧的耗时、事件 drain 耗时、text/hex/plot 渲染耗时、plot 点数统计。
|
||||
@@ -352,8 +352,8 @@ XSERIAL_GUI_PROFILE_INTERVAL_MS=500 cargo run -p xserial-gui
|
||||
### 日志
|
||||
|
||||
```bash
|
||||
RUST_LOG=info cargo run -p xserial-gui # 应用日志
|
||||
RUST_LOG=xserial_gui=debug cargo run -p xserial-gui # 详细日志
|
||||
RUST_LOG=info cargo run -p pipeview-gui # 应用日志
|
||||
RUST_LOG=pipeview_gui=debug cargo run -p pipeview-gui # 详细日志
|
||||
```
|
||||
|
||||
使用 `tracing-subscriber` + `RUST_LOG` 环境变量控制。
|
||||
@@ -362,10 +362,10 @@ RUST_LOG=xserial_gui=debug cargo run -p xserial-gui # 详细日志
|
||||
|
||||
```
|
||||
crates/
|
||||
xserial-core/ # 传输、分帧、协议
|
||||
xserial-client/ # 会话管理、Lua 运行时
|
||||
xserial-gui/ # egui 桌面应用
|
||||
xserial-tui/ # ratatui 终端应用
|
||||
pipeview-core/ # 传输、分帧、协议
|
||||
pipeview-client/ # 会话管理、Lua 运行时
|
||||
pipeview-gui/ # egui 桌面应用
|
||||
pipeview-tui/ # ratatui 终端应用
|
||||
examples/ # Lua 脚本示例
|
||||
drone_plot.lua # 飞控遥测波形解码器
|
||||
drone_text.lua # 飞控遥测文本解码器
|
||||
|
||||
56
README_en.md
56
README_en.md
@@ -1,4 +1,4 @@
|
||||
# xserial
|
||||
# pipeview
|
||||
|
||||
**Cross-platform serial / TCP / UDP data inspection tool** with configurable framing, protocol decoding, multi-session management, and real-time waveform plotting — all in a single binary.
|
||||
|
||||
@@ -89,8 +89,8 @@ Built-in LuaJIT runtime:
|
||||
|
||||
- **Custom framers** — implement `feed(bytes)`, `flush()`, `reset()`, `pending_len()`
|
||||
- **Custom decoders** — implement `decode(frame)`, return text/hex/plot/binary
|
||||
- **Session API** — `xserial.open()` to create sessions, `session:on_data()` for event callbacks, `session:send()` to transmit data
|
||||
- **Utilities** — `xserial.list_ports()`, `xserial.sleep(ms)`, `xserial.poll(limit)`, `xserial.log(msg)`
|
||||
- **Session API** — `pipeview.open()` to create sessions, `session:on_data()` for event callbacks, `session:send()` to transmit data
|
||||
- **Utilities** — `pipeview.list_ports()`, `pipeview.sleep(ms)`, `pipeview.poll(limit)`, `pipeview.log(msg)`
|
||||
|
||||
### Keyboard Shortcuts
|
||||
|
||||
@@ -124,10 +124,10 @@ Built-in LuaJIT runtime:
|
||||
### Build & Run
|
||||
|
||||
```bash
|
||||
git clone https://github.com/your-org/xserial.git
|
||||
cd xserial
|
||||
git clone https://github.com/your-org/pipeview.git
|
||||
cd pipeview
|
||||
|
||||
cargo run -p xserial-gui
|
||||
cargo run -p pipeview-gui
|
||||
|
||||
# Run tests
|
||||
cargo test --workspace # ~308 tests
|
||||
@@ -137,9 +137,9 @@ cargo clippy --workspace --all-targets -- -D warnings
|
||||
### Release Build
|
||||
|
||||
```bash
|
||||
cargo build -p xserial-gui --release
|
||||
# Binary: target/release/xserial-gui (Linux/macOS)
|
||||
# target/release/xserial-gui.exe (Windows)
|
||||
cargo build -p pipeview-gui --release
|
||||
# Binary: target/release/pipeview-gui (Linux/macOS)
|
||||
# target/release/pipeview-gui.exe (Windows)
|
||||
```
|
||||
|
||||
---
|
||||
@@ -160,7 +160,7 @@ python tools/test_drone.py --rate 10 --port 8091
|
||||
|
||||
### Step 2: Configure the session
|
||||
|
||||
In xserial-gui, create a session with two pipelines:
|
||||
In pipeview-gui, create a session with two pipelines:
|
||||
|
||||
| Setting | Value |
|
||||
|---------|-------|
|
||||
@@ -265,23 +265,23 @@ More examples in `examples/`.
|
||||
|
||||
```
|
||||
┌──────────────────────────────────────────────────┐
|
||||
│ xserial-gui (egui) xserial-tui (ratatui) │
|
||||
│ pipeview-gui (egui) pipeview-tui (ratatui) │
|
||||
├──────────────────────────────────────────────────┤
|
||||
│ xserial-client │
|
||||
│ pipeview-client │
|
||||
│ SessionManager · Session · Config · History │
|
||||
│ Lua Runtime (mlua / LuaJIT) │
|
||||
├──────────────────────────────────────────────────┤
|
||||
│ xserial-core │
|
||||
│ pipeview-core │
|
||||
│ Transport ──▶ Frame ──▶ Protocol ──▶ Pipeline │
|
||||
└──────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
| Crate | Type | Purpose |
|
||||
|-------|------|---------|
|
||||
| `xserial-core` | library | Transport (Serial/TCP/UDP), framers (Line/Fixed/Length/COBS/Mixed/Lua), decoders (Text/Hex/Plot), MultiPipeline |
|
||||
| `xserial-client` | library | Session lifecycle, SessionManager, event broadcast (tokio broadcast), RingBuffer history, Lua runtime & session API |
|
||||
| `xserial-gui` | binary | egui desktop app: sidebar, config, console, text/hex/plot panels, keyboard shortcuts, font management, profiling |
|
||||
| `xserial-tui` | binary | ratatui terminal app (feature-incomplete, under development) |
|
||||
| `pipeview-core` | library | Transport (Serial/TCP/UDP), framers (Line/Fixed/Length/COBS/Mixed/Lua), decoders (Text/Hex/Plot), MultiPipeline |
|
||||
| `pipeview-client` | library | Session lifecycle, SessionManager, event broadcast (tokio broadcast), RingBuffer history, Lua runtime & session API |
|
||||
| `pipeview-gui` | binary | egui desktop app: sidebar, config, console, text/hex/plot panels, keyboard shortcuts, font management, profiling |
|
||||
| `pipeview-tui` | binary | ratatui terminal app (feature-incomplete, under development) |
|
||||
|
||||
**Dependency flow:** `core ← client ← {gui, tui}`
|
||||
|
||||
@@ -304,9 +304,9 @@ GUI state is saved automatically to platform-standard locations:
|
||||
|
||||
| Platform | Path |
|
||||
|----------|------|
|
||||
| Linux | `$XDG_CONFIG_HOME/xserial/gui-state.json` or `~/.config/xserial/gui-state.json` |
|
||||
| macOS | `~/Library/Application Support/xserial/gui-state.json` |
|
||||
| Windows | `%APPDATA%\xserial\gui-state.json` |
|
||||
| Linux | `$XDG_CONFIG_HOME/pipeview/gui-state.json` or `~/.config/pipeview/gui-state.json` |
|
||||
| macOS | `~/Library/Application Support/pipeview/gui-state.json` |
|
||||
| Windows | `%APPDATA%\pipeview\gui-state.json` |
|
||||
|
||||
Persisted data includes: session configurations (transport, pipelines), log settings, active tab, and display options.
|
||||
|
||||
@@ -331,25 +331,25 @@ python tools/test_drone.py --rate 10 --port 8092
|
||||
### Profiling
|
||||
|
||||
```bash
|
||||
RUST_LOG=xserial_gui::perf=info XSERIAL_GUI_PROFILE=1 cargo run -p xserial-gui
|
||||
XSERIAL_GUI_PROFILE_INTERVAL_MS=500 cargo run -p xserial-gui
|
||||
RUST_LOG=pipeview_gui::perf=info XSERIAL_GUI_PROFILE=1 cargo run -p pipeview-gui
|
||||
XSERIAL_GUI_PROFILE_INTERVAL_MS=500 cargo run -p pipeview-gui
|
||||
```
|
||||
|
||||
### Tracing
|
||||
|
||||
```bash
|
||||
RUST_LOG=info cargo run -p xserial-gui
|
||||
RUST_LOG=xserial_gui=debug cargo run -p xserial-gui
|
||||
RUST_LOG=info cargo run -p pipeview-gui
|
||||
RUST_LOG=pipeview_gui=debug cargo run -p pipeview-gui
|
||||
```
|
||||
|
||||
### Project Structure
|
||||
|
||||
```
|
||||
crates/
|
||||
xserial-core/ # Transport, framing, protocol
|
||||
xserial-client/ # Session management, Lua runtime
|
||||
xserial-gui/ # egui desktop application
|
||||
xserial-tui/ # ratatui terminal application
|
||||
pipeview-core/ # Transport, framing, protocol
|
||||
pipeview-client/ # Session management, Lua runtime
|
||||
pipeview-gui/ # egui desktop application
|
||||
pipeview-tui/ # ratatui terminal application
|
||||
examples/ # Lua script examples
|
||||
drone_plot.lua # Drone telemetry plot decoder
|
||||
drone_text.lua # Drone telemetry text decoder
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
[package]
|
||||
name = "xserial-client"
|
||||
name = "pipeview-client"
|
||||
version = "0.1.0"
|
||||
edition = "2024"
|
||||
|
||||
[dependencies]
|
||||
xserial-core = { path = "../xserial-core" }
|
||||
pipeview-core = { path = "../pipeview-core" }
|
||||
tokio = { workspace = true, features = ["sync", "time"] }
|
||||
tracing = { workspace = true }
|
||||
serde = { workspace = true }
|
||||
@@ -1,5 +1,5 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
use xserial_core::frame::{
|
||||
use pipeview_core::frame::{
|
||||
Endian, Framer,
|
||||
cobs::CobsFramer,
|
||||
fixed::FixedLengthFramer,
|
||||
@@ -7,14 +7,14 @@ use xserial_core::frame::{
|
||||
line::{LineConfig, LineFramer},
|
||||
mixed::{MixedTextPlotConfig as MixedFramerConfig, MixedTextPlotFramer},
|
||||
};
|
||||
use xserial_core::protocol::{
|
||||
use pipeview_core::protocol::{
|
||||
ProtocolDecoder,
|
||||
hex::{HexConfig, HexDecoder},
|
||||
mixed::{MixedTextPlotConfig as MixedDecoderConfig, MixedTextPlotDecoder},
|
||||
plot::{PlotConfig, PlotDecoder, PlotFormat, SampleType},
|
||||
text::{TextDecoder, TextEncoding},
|
||||
};
|
||||
use xserial_core::transport::TransportConfig;
|
||||
use pipeview_core::transport::TransportConfig;
|
||||
|
||||
use crate::error::Result;
|
||||
use crate::lua::codec::{LuaDecoder, LuaFramer};
|
||||
@@ -229,10 +229,10 @@ impl Default for SessionConfig {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use xserial_core::protocol::Endian;
|
||||
use xserial_core::protocol::plot::{PlotFormat, SampleType};
|
||||
use xserial_core::protocol::text::TextEncoding;
|
||||
use xserial_core::transport::TransportConfig;
|
||||
use pipeview_core::protocol::Endian;
|
||||
use pipeview_core::protocol::plot::{PlotFormat, SampleType};
|
||||
use pipeview_core::protocol::text::TextEncoding;
|
||||
use pipeview_core::transport::TransportConfig;
|
||||
|
||||
#[test]
|
||||
fn framer_line_serde_roundtrip() {
|
||||
@@ -1,4 +1,4 @@
|
||||
use xserial_core::protocol::DecodedData;
|
||||
use pipeview_core::protocol::DecodedData;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct DecodedEntry {
|
||||
@@ -3,9 +3,9 @@ use std::sync::Mutex;
|
||||
|
||||
use mlua::{Function, Lua, RegistryKey, Table, Value};
|
||||
use tracing::warn;
|
||||
use xserial_core::frame::Framer;
|
||||
use xserial_core::protocol::plot::{PlotFormat, PlotFrame, SampleType};
|
||||
use xserial_core::protocol::{DecodedData, ProtocolDecoder};
|
||||
use pipeview_core::frame::Framer;
|
||||
use pipeview_core::protocol::plot::{PlotFormat, PlotFrame, SampleType};
|
||||
use pipeview_core::protocol::{DecodedData, ProtocolDecoder};
|
||||
|
||||
use crate::error::{Error, Result};
|
||||
|
||||
@@ -297,7 +297,7 @@ mod tests {
|
||||
.duration_since(UNIX_EPOCH)
|
||||
.unwrap()
|
||||
.as_nanos();
|
||||
let path = std::env::temp_dir().join(format!("xserial_{name}_{nonce}.lua"));
|
||||
let path = std::env::temp_dir().join(format!("pipeview_{name}_{nonce}.lua"));
|
||||
fs::write(&path, script).unwrap();
|
||||
path
|
||||
}
|
||||
@@ -81,9 +81,9 @@ pub fn register(lua: &Lua) -> LuaResult<()> {
|
||||
|
||||
pub fn register_with_manager(lua: &Lua, manager: SessionManager) -> LuaResult<()> {
|
||||
let runtime = LuaRuntime::new(manager);
|
||||
let xserial = lua.create_table()?;
|
||||
let pipeview = lua.create_table()?;
|
||||
|
||||
xserial.set("open", {
|
||||
pipeview.set("open", {
|
||||
let runtime = runtime.clone();
|
||||
lua.create_async_function(move |lua, config: Table| {
|
||||
let runtime = runtime.clone();
|
||||
@@ -96,15 +96,15 @@ pub fn register_with_manager(lua: &Lua, manager: SessionManager) -> LuaResult<()
|
||||
})?
|
||||
})?;
|
||||
|
||||
xserial.set(
|
||||
pipeview.set(
|
||||
"list_ports",
|
||||
lua.create_function(|_, ()| {
|
||||
let ports = xserial_core::transport::serial::SerialTransport::list_ports();
|
||||
let ports = pipeview_core::transport::serial::SerialTransport::list_ports();
|
||||
Ok(ports.into_iter().map(|p| p.port_name).collect::<Vec<_>>())
|
||||
})?,
|
||||
)?;
|
||||
|
||||
xserial.set("sleep", {
|
||||
pipeview.set("sleep", {
|
||||
let runtime = runtime.clone();
|
||||
lua.create_async_function(move |lua, ms: u64| {
|
||||
let runtime = runtime.clone();
|
||||
@@ -116,7 +116,7 @@ pub fn register_with_manager(lua: &Lua, manager: SessionManager) -> LuaResult<()
|
||||
})?
|
||||
})?;
|
||||
|
||||
xserial.set("poll", {
|
||||
pipeview.set("poll", {
|
||||
let runtime = runtime.clone();
|
||||
lua.create_async_function(move |lua, limit_per_session: Option<usize>| {
|
||||
let runtime = runtime.clone();
|
||||
@@ -124,7 +124,7 @@ pub fn register_with_manager(lua: &Lua, manager: SessionManager) -> LuaResult<()
|
||||
})?
|
||||
})?;
|
||||
|
||||
xserial.set(
|
||||
pipeview.set(
|
||||
"log",
|
||||
lua.create_function(|_, msg: String| {
|
||||
tracing::info!("[lua] {}", msg);
|
||||
@@ -132,7 +132,7 @@ pub fn register_with_manager(lua: &Lua, manager: SessionManager) -> LuaResult<()
|
||||
})?,
|
||||
)?;
|
||||
|
||||
lua.globals().set("xserial", xserial)?;
|
||||
lua.globals().set("pipeview", pipeview)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -146,9 +146,9 @@ mod tests {
|
||||
let lua = Lua::new();
|
||||
register(&lua).unwrap();
|
||||
|
||||
let xserial: Table = lua.globals().get("xserial").unwrap();
|
||||
let pipeview: Table = lua.globals().get("pipeview").unwrap();
|
||||
for name in ["open", "list_ports", "sleep", "poll", "log"] {
|
||||
let value: Value = xserial.get(name).unwrap();
|
||||
let value: Value = pipeview.get(name).unwrap();
|
||||
assert!(
|
||||
matches!(value, Value::Function(_)),
|
||||
"{name} should be a function"
|
||||
@@ -162,8 +162,8 @@ mod tests {
|
||||
let manager = SessionManager::new();
|
||||
register_with_manager(&lua, manager.clone()).unwrap();
|
||||
|
||||
let xserial: Table = lua.globals().get("xserial").unwrap();
|
||||
let open: Value = xserial.get("open").unwrap();
|
||||
let pipeview: Table = lua.globals().get("pipeview").unwrap();
|
||||
let open: Value = pipeview.get("open").unwrap();
|
||||
assert!(matches!(open, Value::Function(_)));
|
||||
assert_eq!(manager.count(), 0);
|
||||
}
|
||||
@@ -8,7 +8,7 @@ use std::time::Duration;
|
||||
use mlua::{Function, Lua, LuaSerdeExt, RegistryKey, UserData, UserDataMethods, Value, Variadic};
|
||||
use tokio::sync::mpsc;
|
||||
use tokio::task::JoinHandle;
|
||||
use xserial_core::protocol::DecodedData;
|
||||
use pipeview_core::protocol::DecodedData;
|
||||
|
||||
use crate::config::SessionConfig;
|
||||
use crate::lua::LuaRuntime;
|
||||
@@ -11,8 +11,8 @@ use tokio::sync::{Mutex, broadcast, mpsc};
|
||||
use tokio::task::JoinHandle;
|
||||
use tracing::{debug, error, info, warn};
|
||||
|
||||
use xserial_core::pipeline::{MultiPipeline, Pipeline};
|
||||
use xserial_core::transport::Connection;
|
||||
use pipeview_core::pipeline::{MultiPipeline, Pipeline};
|
||||
use pipeview_core::transport::Connection;
|
||||
|
||||
use crate::cmd::SessionCmd;
|
||||
use crate::config::SessionConfig;
|
||||
@@ -499,7 +499,7 @@ async fn try_read(
|
||||
}
|
||||
}
|
||||
|
||||
fn to_io_error(err: xserial_core::error::Error) -> std::io::Error {
|
||||
fn to_io_error(err: pipeview_core::error::Error) -> std::io::Error {
|
||||
io::Error::other(err.to_string())
|
||||
}
|
||||
|
||||
@@ -510,7 +510,7 @@ mod tests {
|
||||
|
||||
fn tcp_config() -> SessionConfig {
|
||||
SessionConfig {
|
||||
transport: xserial_core::transport::TransportConfig::Tcp {
|
||||
transport: pipeview_core::transport::TransportConfig::Tcp {
|
||||
addr: "127.0.0.1:1".into(),
|
||||
},
|
||||
pipelines: vec![PipelineConfig {
|
||||
@@ -520,7 +520,7 @@ mod tests {
|
||||
max_line_len: 65536,
|
||||
},
|
||||
decoder: DecoderConfig::Text {
|
||||
encoding: xserial_core::protocol::text::TextEncoding::Utf8,
|
||||
encoding: pipeview_core::protocol::text::TextEncoding::Utf8,
|
||||
},
|
||||
}],
|
||||
..Default::default()
|
||||
@@ -11,7 +11,7 @@ static INIT: Once = Once::new();
|
||||
fn init_tracing() {
|
||||
INIT.call_once(|| {
|
||||
tracing_subscriber::fmt()
|
||||
.with_env_filter("xserial=trace")
|
||||
.with_env_filter("pipeview=trace")
|
||||
.try_init()
|
||||
.ok();
|
||||
});
|
||||
@@ -22,7 +22,7 @@ fn write_temp_lua(name: &str, script: &str) -> PathBuf {
|
||||
.duration_since(std::time::UNIX_EPOCH)
|
||||
.unwrap()
|
||||
.as_nanos();
|
||||
let path = std::env::temp_dir().join(format!("xserial_{name}_{nonce}.lua"));
|
||||
let path = std::env::temp_dir().join(format!("pipeview_{name}_{nonce}.lua"));
|
||||
fs::write(&path, script).unwrap();
|
||||
path
|
||||
}
|
||||
@@ -47,18 +47,18 @@ fn hex_pipeline_lua() -> &'static str {
|
||||
"#
|
||||
}
|
||||
|
||||
// ── xserial.sleep / xserial.log ──────────────────────────────────
|
||||
// ── pipeview.sleep / pipeview.log ──────────────────────────────────
|
||||
|
||||
#[tokio::test]
|
||||
async fn lua_sleep_and_log() {
|
||||
let lua = Lua::new();
|
||||
xserial_client::lua::register(&lua).unwrap();
|
||||
pipeview_client::lua::register(&lua).unwrap();
|
||||
|
||||
lua.load(
|
||||
r#"
|
||||
xserial.log("test start")
|
||||
xserial.sleep(50)
|
||||
xserial.log("test end")
|
||||
pipeview.log("test start")
|
||||
pipeview.sleep(50)
|
||||
pipeview.log("test end")
|
||||
"#,
|
||||
)
|
||||
.exec_async()
|
||||
@@ -66,15 +66,15 @@ async fn lua_sleep_and_log() {
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
// ── xserial.list_ports ───────────────────────────────────────────
|
||||
// ── pipeview.list_ports ───────────────────────────────────────────
|
||||
|
||||
#[tokio::test]
|
||||
async fn lua_list_ports() {
|
||||
let lua = Lua::new();
|
||||
xserial_client::lua::register(&lua).unwrap();
|
||||
pipeview_client::lua::register(&lua).unwrap();
|
||||
|
||||
let result: Vec<String> = lua
|
||||
.load(r#"return xserial.list_ports()"#)
|
||||
.load(r#"return pipeview.list_ports()"#)
|
||||
.eval_async()
|
||||
.await
|
||||
.unwrap();
|
||||
@@ -84,7 +84,7 @@ async fn lua_list_ports() {
|
||||
let _ = result;
|
||||
}
|
||||
|
||||
// ── xserial.open + session:send / session:read / session:close ────
|
||||
// ── pipeview.open + session:send / session:read / session:close ────
|
||||
|
||||
#[tokio::test]
|
||||
async fn lua_session_open_send_read_close() {
|
||||
@@ -102,11 +102,11 @@ async fn lua_session_open_send_read_close() {
|
||||
});
|
||||
|
||||
let lua = Lua::new();
|
||||
xserial_client::lua::register(&lua).unwrap();
|
||||
pipeview_client::lua::register(&lua).unwrap();
|
||||
|
||||
let script = format!(
|
||||
r#"
|
||||
local sess = xserial.open({{
|
||||
local sess = pipeview.open({{
|
||||
transport = {{ Tcp = {{ addr = "{}" }} }},
|
||||
pipelines = {{{}}}
|
||||
}})
|
||||
@@ -141,11 +141,11 @@ async fn lua_session_read_timeout() {
|
||||
});
|
||||
|
||||
let lua = Lua::new();
|
||||
xserial_client::lua::register(&lua).unwrap();
|
||||
pipeview_client::lua::register(&lua).unwrap();
|
||||
|
||||
let script = format!(
|
||||
r#"
|
||||
local sess = xserial.open({{
|
||||
local sess = pipeview.open({{
|
||||
transport = {{ Tcp = {{ addr = "{}" }} }},
|
||||
pipelines = {{{}}}
|
||||
}})
|
||||
@@ -162,7 +162,7 @@ async fn lua_session_read_timeout() {
|
||||
lua.load(&script).exec_async().await.unwrap();
|
||||
}
|
||||
|
||||
// ── xserial.open with hex decoder ────────────────────────────────
|
||||
// ── pipeview.open with hex decoder ────────────────────────────────
|
||||
|
||||
#[tokio::test]
|
||||
async fn lua_session_hex_decoder() {
|
||||
@@ -176,11 +176,11 @@ async fn lua_session_hex_decoder() {
|
||||
});
|
||||
|
||||
let lua = Lua::new();
|
||||
xserial_client::lua::register(&lua).unwrap();
|
||||
pipeview_client::lua::register(&lua).unwrap();
|
||||
|
||||
let script = format!(
|
||||
r#"
|
||||
local sess = xserial.open({{
|
||||
local sess = pipeview.open({{
|
||||
transport = {{ Tcp = {{ addr = "{}" }} }},
|
||||
pipelines = {{{}}}
|
||||
}})
|
||||
@@ -201,7 +201,7 @@ async fn lua_session_hex_decoder() {
|
||||
server.await.unwrap();
|
||||
}
|
||||
|
||||
// ── xserial.open with Lua framer + Lua decoder ───────────────────
|
||||
// ── pipeview.open with Lua framer + Lua decoder ───────────────────
|
||||
|
||||
#[tokio::test]
|
||||
async fn lua_session_custom_lua_pipeline() {
|
||||
@@ -259,11 +259,11 @@ async fn lua_session_custom_lua_pipeline() {
|
||||
});
|
||||
|
||||
let lua = Lua::new();
|
||||
xserial_client::lua::register(&lua).unwrap();
|
||||
pipeview_client::lua::register(&lua).unwrap();
|
||||
|
||||
let script = format!(
|
||||
r#"
|
||||
local sess = xserial.open({{
|
||||
local sess = pipeview.open({{
|
||||
transport = {{ Tcp = {{ addr = "{}" }} }},
|
||||
pipelines = {{
|
||||
{{
|
||||
@@ -311,12 +311,12 @@ async fn lua_session_on_data_callback() {
|
||||
});
|
||||
|
||||
let lua = Lua::new();
|
||||
xserial_client::lua::register(&lua).unwrap();
|
||||
pipeview_client::lua::register(&lua).unwrap();
|
||||
|
||||
let script = format!(
|
||||
r#"
|
||||
local received = {{}}
|
||||
local sess = xserial.open({{
|
||||
local sess = pipeview.open({{
|
||||
transport = {{ Tcp = {{ addr = "{}" }} }},
|
||||
pipelines = {{{}}}
|
||||
}})
|
||||
@@ -327,8 +327,8 @@ async fn lua_session_on_data_callback() {
|
||||
|
||||
for _ = 1, 50 do
|
||||
if #received < 2 then
|
||||
xserial.poll(1)
|
||||
xserial.sleep(10)
|
||||
pipeview.poll(1)
|
||||
pipeview.sleep(10)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -371,11 +371,11 @@ async fn lua_session_reconfigure() {
|
||||
});
|
||||
|
||||
let lua = Lua::new();
|
||||
xserial_client::lua::register(&lua).unwrap();
|
||||
pipeview_client::lua::register(&lua).unwrap();
|
||||
|
||||
let script = format!(
|
||||
r#"
|
||||
local sess = xserial.open({{
|
||||
local sess = pipeview.open({{
|
||||
transport = {{ Tcp = {{ addr = "{}" }} }},
|
||||
pipelines = {{{}}}
|
||||
}})
|
||||
@@ -420,11 +420,11 @@ async fn lua_session_next_event_stream() {
|
||||
});
|
||||
|
||||
let lua = Lua::new();
|
||||
xserial_client::lua::register(&lua).unwrap();
|
||||
pipeview_client::lua::register(&lua).unwrap();
|
||||
|
||||
let script = format!(
|
||||
r#"
|
||||
local sess = xserial.open({{
|
||||
local sess = pipeview.open({{
|
||||
transport = {{ Tcp = {{ addr = "{}" }} }},
|
||||
pipelines = {{{}}}
|
||||
}})
|
||||
@@ -450,7 +450,7 @@ async fn lua_session_next_event_stream() {
|
||||
server.await.unwrap();
|
||||
}
|
||||
|
||||
// ── session:off + xserial.poll ───────────────────────────────────
|
||||
// ── session:off + pipeview.poll ───────────────────────────────────
|
||||
|
||||
#[tokio::test]
|
||||
async fn lua_session_off_stops_future_callbacks() {
|
||||
@@ -466,12 +466,12 @@ async fn lua_session_off_stops_future_callbacks() {
|
||||
});
|
||||
|
||||
let lua = Lua::new();
|
||||
xserial_client::lua::register(&lua).unwrap();
|
||||
pipeview_client::lua::register(&lua).unwrap();
|
||||
|
||||
let script = format!(
|
||||
r#"
|
||||
local received = {{}}
|
||||
local sess = xserial.open({{
|
||||
local sess = pipeview.open({{
|
||||
transport = {{ Tcp = {{ addr = "{}" }} }},
|
||||
pipelines = {{{}}}
|
||||
}})
|
||||
@@ -482,8 +482,8 @@ async fn lua_session_off_stops_future_callbacks() {
|
||||
|
||||
for _ = 1, 50 do
|
||||
if #received == 0 then
|
||||
xserial.poll(1)
|
||||
xserial.sleep(10)
|
||||
pipeview.poll(1)
|
||||
pipeview.sleep(10)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -491,8 +491,8 @@ async fn lua_session_off_stops_future_callbacks() {
|
||||
assert(received[1] == "text:first")
|
||||
assert(sess:off(token) == true)
|
||||
|
||||
xserial.sleep(250)
|
||||
xserial.poll(10)
|
||||
pipeview.sleep(250)
|
||||
pipeview.poll(10)
|
||||
|
||||
assert(#received == 1, "callback should not fire after off")
|
||||
assert(sess:off(token) == false)
|
||||
@@ -3,11 +3,11 @@ use std::time::Duration;
|
||||
use tokio::io::{AsyncReadExt, AsyncWriteExt};
|
||||
use tokio::net::TcpListener;
|
||||
|
||||
use xserial_client::SessionManager;
|
||||
use xserial_client::config::{DecoderConfig, FramerConfig, PipelineConfig, SessionConfig};
|
||||
use xserial_client::session::{Session, SessionEvent};
|
||||
use xserial_core::protocol::DecodedData;
|
||||
use xserial_core::transport::TransportConfig;
|
||||
use pipeview_client::SessionManager;
|
||||
use pipeview_client::config::{DecoderConfig, FramerConfig, PipelineConfig, SessionConfig};
|
||||
use pipeview_client::session::{Session, SessionEvent};
|
||||
use pipeview_core::protocol::DecodedData;
|
||||
use pipeview_core::transport::TransportConfig;
|
||||
|
||||
fn tcp_config(addr: String) -> SessionConfig {
|
||||
SessionConfig {
|
||||
@@ -19,7 +19,7 @@ fn tcp_config(addr: String) -> SessionConfig {
|
||||
max_line_len: 1024 * 1024,
|
||||
},
|
||||
decoder: DecoderConfig::Text {
|
||||
encoding: xserial_core::protocol::text::TextEncoding::Utf8,
|
||||
encoding: pipeview_core::protocol::text::TextEncoding::Utf8,
|
||||
},
|
||||
}],
|
||||
history_limit: 100,
|
||||
@@ -113,7 +113,7 @@ async fn session_multi_pipeline_text_and_hex() {
|
||||
uppercase: false,
|
||||
separator: " ".into(),
|
||||
bytes_per_group: 1,
|
||||
endian: xserial_core::protocol::Endian::Big,
|
||||
endian: pipeview_core::protocol::Endian::Big,
|
||||
},
|
||||
});
|
||||
|
||||
@@ -285,7 +285,7 @@ async fn session_reconfigure_changes_pipeline() {
|
||||
uppercase: true,
|
||||
separator: " ".into(),
|
||||
bytes_per_group: 1,
|
||||
endian: xserial_core::protocol::Endian::Big,
|
||||
endian: pipeview_core::protocol::Endian::Big,
|
||||
};
|
||||
|
||||
handle.reconfigure(new_cfg).await.unwrap();
|
||||
@@ -1,5 +1,5 @@
|
||||
[package]
|
||||
name = "xserial-core"
|
||||
name = "pipeview-core"
|
||||
version = "0.1.0"
|
||||
edition = "2024"
|
||||
|
||||
@@ -61,11 +61,11 @@ pub struct PipelineResult {
|
||||
/// Manages multiple [`Pipeline`]s, feeding the same byte stream to all of them.
|
||||
///
|
||||
/// ```
|
||||
/// use xserial_core::pipeline::{MultiPipeline, Pipeline};
|
||||
/// use xserial_core::frame::line::{LineFramer, LineConfig};
|
||||
/// use xserial_core::frame::fixed::FixedLengthFramer;
|
||||
/// use xserial_core::protocol::text::{TextDecoder, TextEncoding};
|
||||
/// use xserial_core::protocol::hex::{HexDecoder, HexConfig};
|
||||
/// use pipeview_core::pipeline::{MultiPipeline, Pipeline};
|
||||
/// use pipeview_core::frame::line::{LineFramer, LineConfig};
|
||||
/// use pipeview_core::frame::fixed::FixedLengthFramer;
|
||||
/// use pipeview_core::protocol::text::{TextDecoder, TextEncoding};
|
||||
/// use pipeview_core::protocol::hex::{HexDecoder, HexConfig};
|
||||
///
|
||||
/// let mut mp = MultiPipeline::new();
|
||||
/// mp.add(
|
||||
@@ -4,7 +4,7 @@ use tokio::io::{AsyncReadExt, AsyncWriteExt};
|
||||
use tokio::net::{TcpListener, UdpSocket};
|
||||
use tokio::time::timeout;
|
||||
|
||||
use xserial_core::frame::{
|
||||
use pipeview_core::frame::{
|
||||
Endian, Framer,
|
||||
cobs::CobsFramer,
|
||||
cobs::cobs_encode as raw_cobs_encode,
|
||||
@@ -13,17 +13,17 @@ use xserial_core::frame::{
|
||||
line::{LineConfig, LineFramer},
|
||||
mixed::{MixedTextPlotConfig as MixedFramerConfig, MixedTextPlotFramer},
|
||||
};
|
||||
use xserial_core::protocol::{
|
||||
use pipeview_core::protocol::{
|
||||
DecodedData, ProtocolDecoder,
|
||||
hex::{HexConfig, HexDecoder},
|
||||
mixed::{MIXED_PLOT_ESCAPE, MIXED_PLOT_MARKER, MixedTextPlotConfig, MixedTextPlotDecoder},
|
||||
plot::{PlotConfig, PlotDecoder, PlotFormat, SampleType},
|
||||
text::{TextDecoder, TextEncoding},
|
||||
};
|
||||
use xserial_core::transport::serial::{
|
||||
use pipeview_core::transport::serial::{
|
||||
SerialDataBits, SerialFlowControl, SerialParity, SerialStopBits,
|
||||
};
|
||||
use xserial_core::transport::{Connection, TransportConfig, TransportType};
|
||||
use pipeview_core::transport::{Connection, TransportConfig, TransportType};
|
||||
|
||||
const TEST_TIMEOUT: Duration = Duration::from_secs(5);
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
[package]
|
||||
name = "xserial-gui"
|
||||
name = "pipeview-gui"
|
||||
version = "0.1.0"
|
||||
edition = "2024"
|
||||
|
||||
[[bin]]
|
||||
name = "xserial-gui"
|
||||
name = "pipeview-gui"
|
||||
path = "src/main.rs"
|
||||
|
||||
[dependencies]
|
||||
xserial-core = { path = "../xserial-core" }
|
||||
xserial-client = { path = "../xserial-client" }
|
||||
pipeview-core = { path = "../pipeview-core" }
|
||||
pipeview-client = { path = "../pipeview-client" }
|
||||
tokio = { workspace = true }
|
||||
egui = { workspace = true }
|
||||
eframe = { workspace = true }
|
||||
@@ -10,11 +10,11 @@ use crate::perf::{DrainStats, GuiProfiler, GuiSnapshot};
|
||||
use crate::shortcuts::{self, default_bindings};
|
||||
use crate::ui_fonts::{self, FontCandidate, FontChoice, UiFontSettings};
|
||||
use egui::{Color32, Layout, Panel, Pos2, Rect, TextEdit, UiBuilder};
|
||||
use xserial_client::SessionManager;
|
||||
use xserial_client::config::SessionConfig;
|
||||
use xserial_client::session::SessionEvent;
|
||||
use xserial_core::protocol::DecodedData;
|
||||
use xserial_core::transport::TransportConfig;
|
||||
use pipeview_client::SessionManager;
|
||||
use pipeview_client::config::SessionConfig;
|
||||
use pipeview_client::session::SessionEvent;
|
||||
use pipeview_core::protocol::DecodedData;
|
||||
use pipeview_core::transport::TransportConfig;
|
||||
|
||||
const DATA_REPAINT_INTERVAL: Duration = Duration::from_millis(33);
|
||||
|
||||
@@ -851,7 +851,7 @@ impl XserialApp {
|
||||
fn render_top_bar(&mut self, ui: &mut egui::Ui) {
|
||||
Panel::top("top_bar").show_inside(ui, |ui| {
|
||||
ui.horizontal_wrapped(|ui| {
|
||||
ui.heading("xserial");
|
||||
ui.heading("pipeview");
|
||||
ui.separator();
|
||||
// ui.label(format!(
|
||||
// "Fonts: {} + {} {:.1} pt",
|
||||
@@ -1434,8 +1434,8 @@ fn build_payload(tab: &SessionTab) -> Result<Option<Vec<u8>>, String> {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::transport_summary;
|
||||
use xserial_core::transport::TransportConfig;
|
||||
use xserial_core::transport::serial::{
|
||||
use pipeview_core::transport::TransportConfig;
|
||||
use pipeview_core::transport::serial::{
|
||||
SerialDataBits, SerialFlowControl, SerialParity, SerialStopBits,
|
||||
};
|
||||
|
||||
@@ -5,7 +5,7 @@ use std::path::{Path, PathBuf};
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
use tracing::warn;
|
||||
use xserial_client::config::SessionConfig;
|
||||
use pipeview_client::config::SessionConfig;
|
||||
|
||||
const GUI_STATE_FILE_NAME: &str = "gui-state.json";
|
||||
|
||||
@@ -54,7 +54,7 @@ fn gui_state_path() -> PathBuf {
|
||||
gui_state_path_for_os_and_env(env::consts::OS, |key| env::var(key).ok())
|
||||
}
|
||||
|
||||
/// Returns the xserial configuration directory (the parent of gui-state.json).
|
||||
/// Returns the pipeview configuration directory (the parent of gui-state.json).
|
||||
pub fn config_dir() -> PathBuf {
|
||||
gui_state_path()
|
||||
.parent()
|
||||
@@ -67,12 +67,12 @@ fn gui_state_path_for_os_and_env(os: &str, get_env: impl Fn(&str) -> Option<Stri
|
||||
"windows" => {
|
||||
if let Some(path) = get_env("APPDATA").filter(|path| !path.trim().is_empty()) {
|
||||
return PathBuf::from(path)
|
||||
.join("xserial")
|
||||
.join("pipeview")
|
||||
.join(GUI_STATE_FILE_NAME);
|
||||
}
|
||||
if let Some(path) = get_env("LOCALAPPDATA").filter(|path| !path.trim().is_empty()) {
|
||||
return PathBuf::from(path)
|
||||
.join("xserial")
|
||||
.join("pipeview")
|
||||
.join(GUI_STATE_FILE_NAME);
|
||||
}
|
||||
}
|
||||
@@ -81,20 +81,20 @@ fn gui_state_path_for_os_and_env(os: &str, get_env: impl Fn(&str) -> Option<Stri
|
||||
return PathBuf::from(home)
|
||||
.join("Library")
|
||||
.join("Application Support")
|
||||
.join("xserial")
|
||||
.join("pipeview")
|
||||
.join(GUI_STATE_FILE_NAME);
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
if let Some(path) = get_env("XDG_CONFIG_HOME").filter(|path| !path.trim().is_empty()) {
|
||||
return PathBuf::from(path)
|
||||
.join("xserial")
|
||||
.join("pipeview")
|
||||
.join(GUI_STATE_FILE_NAME);
|
||||
}
|
||||
if let Some(home) = get_env("HOME").filter(|path| !path.trim().is_empty()) {
|
||||
return PathBuf::from(home)
|
||||
.join(".config")
|
||||
.join("xserial")
|
||||
.join("pipeview")
|
||||
.join(GUI_STATE_FILE_NAME);
|
||||
}
|
||||
}
|
||||
@@ -124,7 +124,7 @@ const fn default_true() -> bool {
|
||||
mod tests {
|
||||
use super::*;
|
||||
use std::time::{SystemTime, UNIX_EPOCH};
|
||||
use xserial_core::transport::TransportConfig;
|
||||
use pipeview_core::transport::TransportConfig;
|
||||
|
||||
#[test]
|
||||
fn windows_gui_state_path_uses_appdata() {
|
||||
@@ -135,7 +135,7 @@ mod tests {
|
||||
assert_eq!(
|
||||
path,
|
||||
PathBuf::from(r"C:\Users\Test\AppData\Roaming")
|
||||
.join("xserial")
|
||||
.join("pipeview")
|
||||
.join(GUI_STATE_FILE_NAME)
|
||||
);
|
||||
}
|
||||
@@ -146,7 +146,7 @@ mod tests {
|
||||
.duration_since(UNIX_EPOCH)
|
||||
.unwrap()
|
||||
.as_nanos();
|
||||
let dir = env::temp_dir().join(format!("xserial-gui-state-{unique}"));
|
||||
let dir = env::temp_dir().join(format!("pipeview-gui-state-{unique}"));
|
||||
let path = dir.join(GUI_STATE_FILE_NAME);
|
||||
let state = PersistedGuiState {
|
||||
sessions: vec![SessionConfig {
|
||||
@@ -1,10 +1,10 @@
|
||||
use egui_plot::PlotBounds;
|
||||
use std::collections::VecDeque;
|
||||
use std::time::{Duration, Instant};
|
||||
use xserial_client::RingBuffer;
|
||||
use xserial_client::event::DecodedEntry;
|
||||
use xserial_core::protocol::DecodedData;
|
||||
use xserial_core::protocol::plot::{PlotFormat, PlotFrame};
|
||||
use pipeview_client::RingBuffer;
|
||||
use pipeview_client::event::DecodedEntry;
|
||||
use pipeview_core::protocol::DecodedData;
|
||||
use pipeview_core::protocol::plot::{PlotFormat, PlotFrame};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub enum LineDirection {
|
||||
@@ -716,9 +716,9 @@ impl PlotBuffer {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use xserial_client::event::DecodedEntry;
|
||||
use xserial_core::protocol::DecodedData;
|
||||
use xserial_core::protocol::plot::{PlotFrame, SampleType};
|
||||
use pipeview_client::event::DecodedEntry;
|
||||
use pipeview_core::protocol::DecodedData;
|
||||
use pipeview_core::protocol::plot::{PlotFrame, SampleType};
|
||||
|
||||
fn plot_entry() -> DecodedEntry {
|
||||
DecodedEntry {
|
||||
@@ -6,8 +6,8 @@ use std::thread;
|
||||
|
||||
use std::time::{SystemTime, UNIX_EPOCH};
|
||||
|
||||
use xserial_client::event::DecodedEntry;
|
||||
use xserial_core::protocol::DecodedData;
|
||||
use pipeview_client::event::DecodedEntry;
|
||||
use pipeview_core::protocol::DecodedData;
|
||||
|
||||
/// Manages background file logging via a dedicated writer thread.
|
||||
///
|
||||
@@ -30,7 +30,7 @@ impl LogWriter {
|
||||
let mut writer = BufWriter::with_capacity(1024, file);
|
||||
let (sender, receiver) = mpsc::channel::<String>();
|
||||
|
||||
let thread_name = format!("xserial-log-{}", path.display());
|
||||
let thread_name = format!("pipeview-log-{}", path.display());
|
||||
thread::Builder::new().name(thread_name).spawn(move || {
|
||||
while let Ok(line) = receiver.recv() {
|
||||
if writeln!(writer, "{line}").is_err() {
|
||||
@@ -7,7 +7,7 @@ mod perf;
|
||||
mod shortcuts;
|
||||
mod ui_fonts;
|
||||
|
||||
use xserial_client::SessionManager;
|
||||
use pipeview_client::SessionManager;
|
||||
|
||||
fn main() {
|
||||
tracing_subscriber::fmt()
|
||||
@@ -21,7 +21,7 @@ fn main() {
|
||||
let rx = mgr.subscribe();
|
||||
|
||||
let _ = eframe::run_native(
|
||||
"xserial",
|
||||
"pipeview",
|
||||
eframe::NativeOptions::default(),
|
||||
Box::new(|cc| Ok(Box::new(app::XserialApp::new(mgr, rx, cc.egui_ctx.clone())))),
|
||||
);
|
||||
@@ -1,10 +1,10 @@
|
||||
use egui::{ComboBox, DragValue, ScrollArea, TextEdit, Ui};
|
||||
use xserial_client::config::{DecoderConfig, FramerConfig, PipelineConfig, SessionConfig};
|
||||
use xserial_core::protocol::Endian;
|
||||
use xserial_core::protocol::plot::{PlotFormat, SampleType};
|
||||
use xserial_core::protocol::text::TextEncoding;
|
||||
use xserial_core::transport::TransportConfig;
|
||||
use xserial_core::transport::serial::{
|
||||
use pipeview_client::config::{DecoderConfig, FramerConfig, PipelineConfig, SessionConfig};
|
||||
use pipeview_core::protocol::Endian;
|
||||
use pipeview_core::protocol::plot::{PlotFormat, SampleType};
|
||||
use pipeview_core::protocol::text::TextEncoding;
|
||||
use pipeview_core::transport::TransportConfig;
|
||||
use pipeview_core::transport::serial::{
|
||||
SerialDataBits, SerialFlowControl, SerialParity, SerialStopBits, SerialTransport,
|
||||
};
|
||||
|
||||
@@ -202,7 +202,7 @@ impl GuiProfiler {
|
||||
|
||||
let repaints = self.repaint_counter.take();
|
||||
info!(
|
||||
target: "xserial_gui::perf",
|
||||
target: "pipeview_gui::perf",
|
||||
frames = self.interval_stats.frames.count,
|
||||
frame_avg_ms = self.interval_stats.frames.avg_ms(),
|
||||
frame_max_ms = self.interval_stats.frames.max_ms(),
|
||||
@@ -358,12 +358,12 @@ fn font_settings_path_for_os_and_env(
|
||||
"windows" => {
|
||||
if let Some(path) = get_env("APPDATA").filter(|path| !path.trim().is_empty()) {
|
||||
return PathBuf::from(path)
|
||||
.join("xserial")
|
||||
.join("pipeview")
|
||||
.join(FONT_SETTINGS_FILE_NAME);
|
||||
}
|
||||
if let Some(path) = get_env("LOCALAPPDATA").filter(|path| !path.trim().is_empty()) {
|
||||
return PathBuf::from(path)
|
||||
.join("xserial")
|
||||
.join("pipeview")
|
||||
.join(FONT_SETTINGS_FILE_NAME);
|
||||
}
|
||||
}
|
||||
@@ -372,20 +372,20 @@ fn font_settings_path_for_os_and_env(
|
||||
return PathBuf::from(home)
|
||||
.join("Library")
|
||||
.join("Application Support")
|
||||
.join("xserial")
|
||||
.join("pipeview")
|
||||
.join(FONT_SETTINGS_FILE_NAME);
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
if let Some(path) = get_env("XDG_CONFIG_HOME").filter(|path| !path.trim().is_empty()) {
|
||||
return PathBuf::from(path)
|
||||
.join("xserial")
|
||||
.join("pipeview")
|
||||
.join(FONT_SETTINGS_FILE_NAME);
|
||||
}
|
||||
if let Some(home) = get_env("HOME").filter(|path| !path.trim().is_empty()) {
|
||||
return PathBuf::from(home)
|
||||
.join(".config")
|
||||
.join("xserial")
|
||||
.join("pipeview")
|
||||
.join(FONT_SETTINGS_FILE_NAME);
|
||||
}
|
||||
}
|
||||
@@ -591,7 +591,7 @@ mod tests {
|
||||
.duration_since(UNIX_EPOCH)
|
||||
.unwrap()
|
||||
.as_nanos();
|
||||
let dir = env::temp_dir().join(format!("xserial-gui-font-settings-{unique}"));
|
||||
let dir = env::temp_dir().join(format!("pipeview-gui-font-settings-{unique}"));
|
||||
let path = dir.join("gui-fonts.json");
|
||||
let settings = UiFontSettings {
|
||||
primary_choice: FontChoice::System(String::from("primary")),
|
||||
@@ -622,7 +622,7 @@ mod tests {
|
||||
assert_eq!(
|
||||
path,
|
||||
PathBuf::from("/tmp/xdg-config")
|
||||
.join("xserial")
|
||||
.join("pipeview")
|
||||
.join(FONT_SETTINGS_FILE_NAME)
|
||||
);
|
||||
}
|
||||
@@ -636,7 +636,7 @@ mod tests {
|
||||
assert_eq!(
|
||||
path,
|
||||
PathBuf::from(r"C:\Users\Test\AppData\Roaming")
|
||||
.join("xserial")
|
||||
.join("pipeview")
|
||||
.join(FONT_SETTINGS_FILE_NAME)
|
||||
);
|
||||
}
|
||||
@@ -652,7 +652,7 @@ mod tests {
|
||||
PathBuf::from("/Users/tester")
|
||||
.join("Library")
|
||||
.join("Application Support")
|
||||
.join("xserial")
|
||||
.join("pipeview")
|
||||
.join(FONT_SETTINGS_FILE_NAME)
|
||||
);
|
||||
}
|
||||
@@ -1,15 +1,15 @@
|
||||
[package]
|
||||
name = "xserial-tui"
|
||||
name = "pipeview-tui"
|
||||
version = "0.1.0"
|
||||
edition = "2024"
|
||||
|
||||
[[bin]]
|
||||
name = "xserial-tui"
|
||||
name = "pipeview-tui"
|
||||
path = "src/main.rs"
|
||||
|
||||
[dependencies]
|
||||
xserial-core = { path = "../xserial-core" }
|
||||
xserial-client = { path = "../xserial-client" }
|
||||
pipeview-core = { path = "../pipeview-core" }
|
||||
pipeview-client = { path = "../pipeview-client" }
|
||||
tokio = { workspace = true }
|
||||
ratatui = { workspace = true }
|
||||
crossterm = { workspace = true }
|
||||
@@ -3,12 +3,12 @@ use std::{io, time::Duration};
|
||||
use crossterm::event::{self, Event, KeyCode, KeyEventKind, KeyModifiers};
|
||||
use ratatui::DefaultTerminal;
|
||||
use tokio::sync::broadcast;
|
||||
use xserial_client::{
|
||||
use pipeview_client::{
|
||||
DecoderConfig, FramerConfig, PipelineConfig, SessionConfig, SessionEvent, SessionId,
|
||||
SessionManager,
|
||||
};
|
||||
use xserial_core::protocol::DecodedData;
|
||||
use xserial_core::transport::{
|
||||
use pipeview_core::protocol::DecodedData;
|
||||
use pipeview_core::transport::{
|
||||
TransportConfig, TransportType,
|
||||
serial::{SerialDataBits, SerialFlowControl, SerialParity, SerialStopBits, SerialTransport},
|
||||
};
|
||||
@@ -5,7 +5,7 @@ use std::path::{Path, PathBuf};
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
use tracing::warn;
|
||||
use xserial_client::SessionConfig;
|
||||
use pipeview_client::SessionConfig;
|
||||
|
||||
const TUI_STATE_FILE_NAME: &str = "tui-state.json";
|
||||
|
||||
@@ -49,12 +49,12 @@ fn state_path_for_os_and_env(os: &str, get_env: impl Fn(&str) -> Option<String>)
|
||||
"windows" => {
|
||||
if let Some(path) = get_env("APPDATA").filter(|path| !path.trim().is_empty()) {
|
||||
return PathBuf::from(path)
|
||||
.join("xserial")
|
||||
.join("pipeview")
|
||||
.join(TUI_STATE_FILE_NAME);
|
||||
}
|
||||
if let Some(path) = get_env("LOCALAPPDATA").filter(|path| !path.trim().is_empty()) {
|
||||
return PathBuf::from(path)
|
||||
.join("xserial")
|
||||
.join("pipeview")
|
||||
.join(TUI_STATE_FILE_NAME);
|
||||
}
|
||||
}
|
||||
@@ -63,20 +63,20 @@ fn state_path_for_os_and_env(os: &str, get_env: impl Fn(&str) -> Option<String>)
|
||||
return PathBuf::from(home)
|
||||
.join("Library")
|
||||
.join("Application Support")
|
||||
.join("xserial")
|
||||
.join("pipeview")
|
||||
.join(TUI_STATE_FILE_NAME);
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
if let Some(path) = get_env("XDG_CONFIG_HOME").filter(|path| !path.trim().is_empty()) {
|
||||
return PathBuf::from(path)
|
||||
.join("xserial")
|
||||
.join("pipeview")
|
||||
.join(TUI_STATE_FILE_NAME);
|
||||
}
|
||||
if let Some(home) = get_env("HOME").filter(|path| !path.trim().is_empty()) {
|
||||
return PathBuf::from(home)
|
||||
.join(".config")
|
||||
.join("xserial")
|
||||
.join("pipeview")
|
||||
.join(TUI_STATE_FILE_NAME);
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
use std::time::{Duration, Instant};
|
||||
|
||||
use xserial_client::{DecodedEntry, RingBuffer};
|
||||
use xserial_core::protocol::DecodedData;
|
||||
use pipeview_client::{DecodedEntry, RingBuffer};
|
||||
use pipeview_core::protocol::DecodedData;
|
||||
|
||||
#[derive(Clone, Copy, PartialEq, Eq)]
|
||||
pub enum LineDirection {
|
||||
@@ -10,7 +10,7 @@ use crossterm::{
|
||||
terminal::{EnterAlternateScreen, LeaveAlternateScreen, disable_raw_mode, enable_raw_mode},
|
||||
};
|
||||
use ratatui::{Terminal, backend::CrosstermBackend};
|
||||
use xserial_client::SessionManager;
|
||||
use pipeview_client::SessionManager;
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() -> io::Result<()> {
|
||||
@@ -100,7 +100,7 @@ fn render_main(frame: &mut Frame, app: &App, area: Rect) {
|
||||
app.help_text(),
|
||||
app.notice().unwrap_or("")
|
||||
))
|
||||
.block(Block::default().borders(Borders::ALL).title("xserial-tui"))
|
||||
.block(Block::default().borders(Borders::ALL).title("pipeview-tui"))
|
||||
.wrap(Wrap { trim: false }),
|
||||
area,
|
||||
);
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Generate fake drone telemetry data for testing xserial Lua decoder."""
|
||||
"""Generate fake drone telemetry data for testing pipeview Lua decoder."""
|
||||
|
||||
import argparse
|
||||
import math
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python3
|
||||
"""TCP server that sends plot waveform frames or text lines for xserial GUI."""
|
||||
"""TCP server that sends plot waveform frames or text lines for pipeview GUI."""
|
||||
|
||||
import argparse
|
||||
import math
|
||||
@@ -116,7 +116,7 @@ def is_disconnect_error(err: OSError) -> bool:
|
||||
|
||||
|
||||
def main() -> None:
|
||||
parser = argparse.ArgumentParser(description="xserial plot test server")
|
||||
parser = argparse.ArgumentParser(description="pipeview plot test server")
|
||||
parser.add_argument("--host", default="127.0.0.1")
|
||||
parser.add_argument("--port", type=int, default=8080)
|
||||
parser.add_argument("--channels", type=int, default=1)
|
||||
|
||||
@@ -429,7 +429,7 @@ int main(int argc, char **argv) {
|
||||
double frame_interval = (double)args.samples_per_channel / args.rate;
|
||||
double frame_rate = args.rate / (double)args.samples_per_channel;
|
||||
|
||||
printf("═══ xserial Serial Plot Generator ═══\n");
|
||||
printf("═══ pipeview Serial Plot Generator ═══\n");
|
||||
printf("串口: %s @ %d baud\n", args.port, args.baudrate);
|
||||
printf("通道: %u 格式: %s\n", args.channels, format_name);
|
||||
printf("频率: %.1f Hz 振幅: %.1f\n", args.freq, args.amp);
|
||||
|
||||
@@ -208,7 +208,7 @@ int main(int argc, char **argv) {
|
||||
|
||||
double interval = 1.0 / args.rate;
|
||||
|
||||
printf("═══ xserial Plain Text Generator ═══\n");
|
||||
printf("═══ pipeview Plain Text Generator ═══\n");
|
||||
printf("串口: %s @ %d baud\n", args.port, args.baudrate);
|
||||
printf("通道: %u 振幅: %.1f 频率: %.1f Hz\n", args.channels, args.amp, args.freq);
|
||||
printf("速率: %.0f lines/sec (间隔 %.3f ms)\n", args.rate, interval * 1000.0);
|
||||
|
||||
Reference in New Issue
Block a user