3.6 KiB
DynaLab Architecture and Naming
Goals
DynaLab accepts live data from multiple connector implementations and presents it in a desktop UI. The architecture keeps transport code, application state, and Dear PyGui code independent so that adding a connector or UI feature does not require edits across unrelated modules.
Data Flow
connector session -> ConnectorEvent queue -> UI feature controller -> feature state -> view
The connector thread owns sockets, handshakes, and heartbeat bookkeeping. It communicates with the main thread only through immutable events. The main thread owns application state and all Dear PyGui calls.
Package Layout
src/dynalab/
app.py composition, lifecycle, frame loop, shutdown
state.py focused application, signal, and recording state
connectors/
events.py typed connector-to-application events
protocol_server.py asyncio server and connector sessions
ui/
shell.py top-level window, menus, and feature navigation
loading/ loading view and tags
errors/ error modal view and tags
live_data/ gauge view, event controller, and tags
recording/ recording view, controller, presenter, and tags
Feature folders own their widgets, tags, callbacks, and model-to-widget synchronization.
Avoid global tag collections and modules named after generic implementation techniques,
such as windows, routines, or render.
Naming
build_*creates widgets once.refresh_*synchronizes existing widgets from state.on_*is a thin Dear PyGui callback.handle_*processes an application event or user intent.start_*andstop_*control service lifecycle.load_*andsave_*access persistent storage.*_tagfunctions generate dynamic Dear PyGui identifiers.*Stateholds mutable state owned by the main thread.*Eventis immutable communication across a boundary.
Tags are feature-qualified strings, for example recording.dialog and
live_data.gauge.<uuid>. Display labels are never parsed to recover domain identifiers;
features maintain explicit label-to-ID mappings.
Ownership Rules
- Only the connector thread accesses streams, sessions, and heartbeat timestamps.
- Only the main thread mutates
ApplicationStateand calls Dear PyGui. app.pycomposes services and dispatches events; it does not build feature widgets.- Controllers translate intent or events into state changes and view operations.
- Views construct widgets and contain no connector logic.
- Presenters format state for existing widgets and contain no networking logic.
Adding a Connector
A connector adapts its transport into the event types in connectors/events.py. It must
not mutate application state or invoke Dear PyGui. Connector-specific handshake and
framing stay within its own server/session implementation.
Adding a UI Feature
Create a folder under ui/ containing only the pieces the feature needs. A typical
feature has view.py, controller.py, presenter.py, and tags.py; small features may
use fewer files. Register its top-level view in ui/shell.py and dispatch relevant events
from the application loop.
Testing Boundaries
- Test event and state behavior without importing Dear PyGui.
- Test controllers with a stubbed gauge or Dear PyGui adapter.
- Test connector sessions with local asyncio streams or protocol fakes.
- Keep manual connector simulators under
test/or move them totools/when the automated integration suite is introduced.