97 lines
4.7 KiB
Python
97 lines
4.7 KiB
Python
# -*- coding: utf-8 -*-
|
||
# dispatch/null_hardware_gateway.py
|
||
|
||
"""Пустой реализатор `TicketHardwareGateway` для приложения Dispatch.
|
||
|
||
Назначение модуля:
|
||
В составе Dispatch модуль работы с COM-портом отключён по требованию
|
||
приложения. Application-сервис Ticket по архитектурному контракту
|
||
обязан получать на вход реализацию `TicketHardwareGateway` и
|
||
обращаться к ней при старте, остановке и обновлении состояний кнопок.
|
||
|
||
Данный класс предоставляет канонически совместимую, но полностью
|
||
бездействующую реализацию шлюза:
|
||
- `start` / `stop` ничего не делают;
|
||
- `set_observer` принимает наблюдателя и сразу публикует ему
|
||
нейтральный статус подключения;
|
||
- методы управления состояниями кнопок принимают вызовы и
|
||
молча игнорируют их;
|
||
- `get_status` всегда возвращает «отключён».
|
||
|
||
Архитектурные ограничения:
|
||
- Реализация полностью независима от каталога `gui/`.
|
||
- Никакой предметной логики Ticket здесь не содержится: класс
|
||
исключительно закрывает контракт `TicketHardwareGateway`.
|
||
"""
|
||
|
||
from __future__ import annotations
|
||
|
||
from typing import Any, Mapping
|
||
|
||
from PySide6.QtCore import QObject
|
||
|
||
from domain import TicketConnectionStatus, TicketHardwareStatus
|
||
from services import TicketHardwareObserver
|
||
|
||
|
||
class NullHardwareGateway(QObject):
|
||
"""Бездействующий шлюз: закрывает контракт `TicketHardwareGateway`."""
|
||
|
||
def __init__(self, parent: QObject | None = None):
|
||
super().__init__(parent)
|
||
self._observer: TicketHardwareObserver | None = None
|
||
self._status = TicketHardwareStatus(
|
||
connection_status=TicketConnectionStatus.DISCONNECTED,
|
||
message="hardware module is disabled in Dispatch",
|
||
buttons_initialized=False,
|
||
button_count=0,
|
||
)
|
||
|
||
# ── управление жизненным циклом ──
|
||
|
||
def start(self) -> None:
|
||
"""Обозначить факт «запуска» без обращения к внешнему оборудованию."""
|
||
if self._observer is not None:
|
||
self._observer.on_gateway_status(self._status)
|
||
|
||
def stop(self) -> None:
|
||
"""Завершить работу: ничего не освобождаем, состояние уже нейтральное."""
|
||
return
|
||
|
||
# ── подписка наблюдателя ──
|
||
|
||
def set_observer(self, observer: TicketHardwareObserver | None) -> None:
|
||
"""Назначить получателя событий и сразу опубликовать текущий статус."""
|
||
self._observer = observer
|
||
if observer is not None:
|
||
observer.on_gateway_status(self._status)
|
||
|
||
def get_status(self) -> TicketHardwareStatus:
|
||
"""Вернуть постоянно-нейтральный статус шлюза."""
|
||
return self._status
|
||
|
||
# ── управление состояниями кнопок ──
|
||
|
||
def set_button_state(self, button_id: int, state_code: int) -> None:
|
||
"""Принять обновление состояния кнопки и проигнорировать его."""
|
||
return
|
||
|
||
def remove_button_state(self, button_id: int) -> None:
|
||
"""Принять снятие состояния кнопки и проигнорировать его."""
|
||
return
|
||
|
||
def reset_button_states(self) -> None:
|
||
"""Сбросить «состояния»: для null-шлюза это операция без эффекта."""
|
||
return
|
||
|
||
# ── совместимость с возможными внешними действиями ──
|
||
|
||
def emit_external_action(self, raw_action: Mapping[str, Any]) -> None:
|
||
"""Доставить внешнее действие наблюдателю, если он назначен.
|
||
|
||
Метод оставлен для возможной интеграции внешних источников событий
|
||
в будущем; в текущем составе Dispatch не вызывается.
|
||
"""
|
||
if self._observer is not None:
|
||
self._observer.on_task_action(raw_action)
|