Add Dispatch_V0.1.1

This commit is contained in:
2026-04-29 08:18:54 +04:00
commit a7ede6ded4
404 changed files with 39167 additions and 0 deletions

View File

@@ -0,0 +1,96 @@
# -*- 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)