.. index:: single: hardware runtime single: HardwareManager; runtime single: HardwareObject; lifecycle single: bcInitInstrument single: bcTestConnection single: bcReadSettings single: CommunicationProtocol; runtime selection single: CustomInstrument; protocol selection single: GpibController; resolution single: CommunicationDialog single: HWDialog single: hardware threading; per-device QThread single: connectionResult single: allHardwareConnected single: auxiliary data; key prefixing single: rolling data; HardwareObject timer single: Python hardware; script reload Hardware Runtime ================ This page is the runtime companion to :doc:`/developer_guide/hardware_configuration`. The configuration page describes the four singletons that decide *which* hardware exists in the active loadout, *which* driver backs each profile, and *which* persisted settings each profile carries. This page picks up at the moment :cpp:func:`HardwareManager::initialize` runs: how the manager turns that configuration into a live set of :cpp:class:`HardwareObject` instances, places each one on the right thread, opens its communication channel, fans connection-state and sensor data out to the rest of the program, and reacts when the user edits hardware from the GUI. The two cross-system surfaces a contributor most often touches when working in this area are the :cpp:class:`CommunicationDialog` (for changing a device's protocol or connection parameters at runtime) and the :cpp:class:`HWDialog` (for editing a device's persistent settings and exercising its live controls). Both are mediated through :cpp:class:`HardwareManager`; nothing in the GUI ever touches a :cpp:class:`HardwareObject` directly, because the per-device threading rules require all interaction to be queued through the manager's slot and signal surface. HardwareManager: ownership and threading ---------------------------------------- :cpp:class:`HardwareManager` is the runtime owner of every live :cpp:class:`HardwareObject` instance for the active loadout. It is constructed by :cpp:class:`MainWindow` before the application's event loop begins serving widgets, immediately moved onto a dedicated ``QThread`` named ``HardwareManagerThread``, and started by wiring the thread's :cpp:func:`QThread::started` signal to :cpp:func:`HardwareManager::initialize`: .. code-block:: cpp QThread *hwmThread = new QThread(this); hwmThread->setObjectName("HardwareManagerThread"); connect(hwmThread, &QThread::started, p_hwm, &HardwareManager::initialize); p_hwm->moveToThread(hwmThread); After this point every public slot on :cpp:class:`HardwareManager` executes on the manager's thread. Callers in the GUI thread, in :cpp:class:`AcquisitionManager`, or anywhere else, reach the manager through queued connections (or :cpp:func:`QMetaObject::invokeMethod` for direct dispatch). The manager owns three things outright: - The **hardware map**, ``d_hardwareMap``, a ``std::map`` keyed by ``".