Step 2 - LDF Loading: - ldfparser integration (Python) / custom regex parser (C++) - QTreeWidget with expandable signal rows, merged Value column - Hex/Dec toggle, FreeFormat schedule entries, auto-reload - Baud rate auto-detection from LDF Step 3 - Signal Editing: - Bit packing/unpacking (signal value ↔ frame bytes) - ReadOnlyColumnDelegate for per-column editability - Value clamping to signal width, recursion guard Step 4 - Rx Panel: - receive_rx_frame() API with timestamp, signal unpacking - Change highlighting (yellow), auto-scroll toggle, clear button - Dashboard view (in-place update per frame_id) Step 5 - Connection Panel: - ConnectionManager with state machine (Disconnected/Connecting/Connected/Error) - Port scanning (pyserial / QSerialPort), connect/disconnect with UI mapping Step 6 - BabyLIN Backend: - BabyLinBackend wrapping Lipowsky BabyLIN_library.py DLL - Mock mode for macOS/CI, device scan, SDF loading, signal access - Frame callbacks, raw command access Step 7 - Master Scheduler: - QTimer-based schedule execution with start/stop/pause - Frame sent callback with visual highlighting - Mock Rx simulation, manual send, global rate override Tests: Python 171 | C++ 124 (Steps 1-5 parity, Steps 6-7 Python-first) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
83 lines
3.6 KiB
Markdown
83 lines
3.6 KiB
Markdown
# Step 2 — LDF Loading & Display (C++)
|
|
|
|
## What Was Built
|
|
|
|
Custom LDF file parser, GUI table population, baud rate detection, schedule table loading, and auto-reload on file change — all in C++, matching the Python implementation feature-for-feature.
|
|
|
|
## Architecture
|
|
|
|
```
|
|
User clicks Browse → QFileDialog → filePath
|
|
│
|
|
▼
|
|
loadLdfFile(path)
|
|
│
|
|
┌────────────┼────────────┐
|
|
▼ ▼ ▼
|
|
parseLdf() On error: Setup file
|
|
(ldf_parser) show dialog watcher
|
|
│
|
|
▼
|
|
LdfData
|
|
┌────┼────────────┬──────────────┐
|
|
▼ ▼ ▼ ▼
|
|
Baud Tx table Rx table Schedule
|
|
rate (master (slave dropdown
|
|
label frames) frames)
|
|
```
|
|
|
|
## Key Module: ldf_parser.h / ldf_parser.cpp
|
|
|
|
Custom parser (no third-party library). Parses LDF sections using QRegularExpression.
|
|
|
|
| C++ Struct | Python Equivalent | Purpose |
|
|
|-----------|-------------------|---------|
|
|
| `LdfData` | `LdfData` | Complete parsed result |
|
|
| `FrameInfo` | `FrameInfo` | One frame with signals |
|
|
| `SignalInfo` | `SignalInfo` | One signal's metadata |
|
|
| `ScheduleTableInfo` | `ScheduleTableInfo` | One schedule table |
|
|
|
|
### Python vs C++ Parser Differences
|
|
|
|
| Aspect | Python | C++ |
|
|
|--------|--------|-----|
|
|
| Library | `ldfparser` (3rd party) | Custom regex parser |
|
|
| Baud rate | `ldf.baudrate / 1000` (lib returns *1000) | Read raw value from file (already correct) |
|
|
| Frame classification | `isinstance(frame.publisher, LinMaster)` | `frame.publisher == masterName` (string compare) |
|
|
| Schedule delay | `entry.delay * 1000` (lib returns seconds) | Read raw ms value from file |
|
|
| Signal field name | `frame.signals` | `frame.signal_list` (Qt `signals` macro conflict) |
|
|
|
|
## C++ Concepts Introduced
|
|
|
|
### struct vs @dataclass
|
|
Python `@dataclass` → C++ `struct`. Both are data containers, but C++ structs have compile-time type enforcement.
|
|
|
|
### std::optional
|
|
`self._ldf_data: LdfData | None` → `std::optional<LdfData>`. Holds a value or is empty. Access with `->` and `*`.
|
|
|
|
### Raw string delimiters
|
|
When a regex contains `"` characters: `R"re(pattern with "quotes")re"` uses custom delimiter `re` so `"` inside is safe.
|
|
|
|
### Qt macro collision
|
|
`signals` is a Qt macro — can't use as a variable name. Renamed to `signal_list`.
|
|
|
|
### QTimer for test modal dialogs
|
|
Python uses `monkeypatch` to suppress QMessageBox. C++ uses `QTimer::singleShot(0, ...)` to auto-dismiss the dialog.
|
|
|
|
## Files
|
|
|
|
| File | Purpose |
|
|
|------|---------|
|
|
| `cpp/src/ldf_parser.h` | Data structs + parseLdf() declaration |
|
|
| `cpp/src/ldf_parser.cpp` | Custom LDF parser (regex-based) |
|
|
| `cpp/src/main_window.h` | Updated: LdfData, file watcher, new methods |
|
|
| `cpp/src/main_window.cpp` | Updated: loadLdfFile(), table population, auto-reload |
|
|
| `cpp/tests/test_ldf_parser.cpp` | 28 parser unit tests |
|
|
| `cpp/tests/test_ldf_loading.cpp` | 22 GUI integration tests |
|
|
| `cpp/CMakeLists.txt` | Updated: new sources + 2 new test targets |
|
|
|
|
## Test Results
|
|
- **84 total C++ tests passing** (Step 1: 34 + Step 2: 50)
|
|
- Parser tests: valid/invalid files, frame classification, signal extraction, schedules
|
|
- GUI tests: table population, baud rate, schedule combo, error handling, auto-reload
|