Centralize item module wiring in one registry
This commit is contained in:
@@ -3,23 +3,16 @@
|
|||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from dataclasses import dataclass
|
from dataclasses import dataclass
|
||||||
from typing import Literal
|
from typing import Literal, cast
|
||||||
|
|
||||||
from .items import clock, dice, radio, wheel
|
from .items import clock, radio
|
||||||
|
from .items.registry import ITEM_MODULES, ITEM_TYPE_ORDER
|
||||||
|
|
||||||
ItemType = Literal["radio_station", "dice", "wheel", "clock"]
|
ItemType = Literal["radio_station", "dice", "wheel", "clock"]
|
||||||
ITEM_TYPE_SEQUENCE: tuple[ItemType, ...] = ("clock", "dice", "radio_station", "wheel")
|
ITEM_TYPE_SEQUENCE: tuple[ItemType, ...] = cast(tuple[ItemType, ...], ITEM_TYPE_ORDER)
|
||||||
ITEM_TYPE_LABELS: dict[ItemType, str] = {
|
ITEM_TYPE_LABELS: dict[ItemType, str] = {item_type: ITEM_MODULES[item_type].LABEL for item_type in ITEM_TYPE_SEQUENCE}
|
||||||
"radio_station": radio.LABEL,
|
|
||||||
"dice": dice.LABEL,
|
|
||||||
"wheel": wheel.LABEL,
|
|
||||||
"clock": clock.LABEL,
|
|
||||||
}
|
|
||||||
ITEM_TYPE_EDITABLE_PROPERTIES: dict[ItemType, tuple[str, ...]] = {
|
ITEM_TYPE_EDITABLE_PROPERTIES: dict[ItemType, tuple[str, ...]] = {
|
||||||
"radio_station": radio.EDITABLE_PROPERTIES,
|
item_type: ITEM_MODULES[item_type].EDITABLE_PROPERTIES for item_type in ITEM_TYPE_SEQUENCE
|
||||||
"dice": dice.EDITABLE_PROPERTIES,
|
|
||||||
"wheel": wheel.EDITABLE_PROPERTIES,
|
|
||||||
"clock": clock.EDITABLE_PROPERTIES,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CLOCK_DEFAULT_TIME_ZONE = clock.DEFAULT_TIME_ZONE
|
CLOCK_DEFAULT_TIME_ZONE = clock.DEFAULT_TIME_ZONE
|
||||||
@@ -68,46 +61,17 @@ def _build_definition(
|
|||||||
|
|
||||||
|
|
||||||
ITEM_DEFINITIONS: dict[ItemType, ItemDefinition] = {
|
ITEM_DEFINITIONS: dict[ItemType, ItemDefinition] = {
|
||||||
"radio_station": _build_definition(
|
item_type: _build_definition(
|
||||||
default_title=radio.DEFAULT_TITLE,
|
default_title=ITEM_MODULES[item_type].DEFAULT_TITLE,
|
||||||
capabilities=radio.CAPABILITIES,
|
capabilities=ITEM_MODULES[item_type].CAPABILITIES,
|
||||||
use_sound=radio.USE_SOUND,
|
use_sound=ITEM_MODULES[item_type].USE_SOUND,
|
||||||
emit_sound=radio.EMIT_SOUND,
|
emit_sound=ITEM_MODULES[item_type].EMIT_SOUND,
|
||||||
default_params=radio.DEFAULT_PARAMS,
|
default_params=ITEM_MODULES[item_type].DEFAULT_PARAMS,
|
||||||
use_cooldown_ms=radio.USE_COOLDOWN_MS,
|
use_cooldown_ms=ITEM_MODULES[item_type].USE_COOLDOWN_MS,
|
||||||
emit_range=radio.EMIT_RANGE,
|
emit_range=ITEM_MODULES[item_type].EMIT_RANGE,
|
||||||
directional=radio.DIRECTIONAL,
|
directional=ITEM_MODULES[item_type].DIRECTIONAL,
|
||||||
),
|
)
|
||||||
"dice": _build_definition(
|
for item_type in ITEM_TYPE_SEQUENCE
|
||||||
default_title=dice.DEFAULT_TITLE,
|
|
||||||
capabilities=dice.CAPABILITIES,
|
|
||||||
use_sound=dice.USE_SOUND,
|
|
||||||
emit_sound=dice.EMIT_SOUND,
|
|
||||||
default_params=dice.DEFAULT_PARAMS,
|
|
||||||
use_cooldown_ms=dice.USE_COOLDOWN_MS,
|
|
||||||
emit_range=dice.EMIT_RANGE,
|
|
||||||
directional=dice.DIRECTIONAL,
|
|
||||||
),
|
|
||||||
"wheel": _build_definition(
|
|
||||||
default_title=wheel.DEFAULT_TITLE,
|
|
||||||
capabilities=wheel.CAPABILITIES,
|
|
||||||
use_sound=wheel.USE_SOUND,
|
|
||||||
emit_sound=wheel.EMIT_SOUND,
|
|
||||||
default_params=wheel.DEFAULT_PARAMS,
|
|
||||||
use_cooldown_ms=wheel.USE_COOLDOWN_MS,
|
|
||||||
emit_range=wheel.EMIT_RANGE,
|
|
||||||
directional=wheel.DIRECTIONAL,
|
|
||||||
),
|
|
||||||
"clock": _build_definition(
|
|
||||||
default_title=clock.DEFAULT_TITLE,
|
|
||||||
capabilities=clock.CAPABILITIES,
|
|
||||||
use_sound=clock.USE_SOUND,
|
|
||||||
emit_sound=clock.EMIT_SOUND,
|
|
||||||
default_params=clock.DEFAULT_PARAMS,
|
|
||||||
use_cooldown_ms=clock.USE_COOLDOWN_MS,
|
|
||||||
emit_range=clock.EMIT_RANGE,
|
|
||||||
directional=clock.DIRECTIONAL,
|
|
||||||
),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ITEM_PROPERTY_OPTIONS: dict[str, tuple[str, ...]] = {
|
ITEM_PROPERTY_OPTIONS: dict[str, tuple[str, ...]] = {
|
||||||
@@ -117,10 +81,7 @@ ITEM_PROPERTY_OPTIONS: dict[str, tuple[str, ...]] = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ITEM_TYPE_TOOLTIPS: dict[ItemType, str] = {
|
ITEM_TYPE_TOOLTIPS: dict[ItemType, str] = {
|
||||||
"radio_station": radio.TOOLTIP,
|
item_type: ITEM_MODULES[item_type].TOOLTIP for item_type in ITEM_TYPE_SEQUENCE
|
||||||
"dice": dice.TOOLTIP,
|
|
||||||
"wheel": wheel.TOOLTIP,
|
|
||||||
"clock": clock.TOOLTIP,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
GLOBAL_ITEM_PROPERTY_METADATA: dict[str, dict[str, object]] = {
|
GLOBAL_ITEM_PROPERTY_METADATA: dict[str, dict[str, object]] = {
|
||||||
@@ -132,10 +93,7 @@ GLOBAL_ITEM_PROPERTY_METADATA: dict[str, dict[str, object]] = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ITEM_TYPE_PROPERTY_METADATA: dict[ItemType, dict[str, dict[str, object]]] = {
|
ITEM_TYPE_PROPERTY_METADATA: dict[ItemType, dict[str, dict[str, object]]] = {
|
||||||
"radio_station": {**GLOBAL_ITEM_PROPERTY_METADATA, **radio.PROPERTY_METADATA},
|
item_type: {**GLOBAL_ITEM_PROPERTY_METADATA, **ITEM_MODULES[item_type].PROPERTY_METADATA} for item_type in ITEM_TYPE_SEQUENCE
|
||||||
"dice": {**GLOBAL_ITEM_PROPERTY_METADATA, **dice.PROPERTY_METADATA},
|
|
||||||
"wheel": {**GLOBAL_ITEM_PROPERTY_METADATA, **wheel.PROPERTY_METADATA},
|
|
||||||
"clock": {**GLOBAL_ITEM_PROPERTY_METADATA, **clock.PROPERTY_METADATA},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -166,4 +124,3 @@ def get_item_global_properties(item_type: ItemType) -> dict[str, str | int | boo
|
|||||||
"emitRange": definition.emit_range if isinstance(definition.emit_range, int) and definition.emit_range > 0 else 15,
|
"emitRange": definition.emit_range if isinstance(definition.emit_range, int) and definition.emit_range > 0 else 15,
|
||||||
"directional": bool(definition.directional),
|
"directional": bool(definition.directional),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,14 +3,12 @@
|
|||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from .item_catalog import ItemType
|
from .item_catalog import ItemType
|
||||||
from .items import clock, dice, radio, wheel
|
from .items.registry import ITEM_MODULES
|
||||||
from .item_types import ItemTypeHandler
|
from .item_types import ItemTypeHandler
|
||||||
|
|
||||||
ITEM_TYPE_HANDLERS: dict[ItemType, ItemTypeHandler] = {
|
ITEM_TYPE_HANDLERS: dict[ItemType, ItemTypeHandler] = {
|
||||||
"radio_station": ItemTypeHandler(validate_update=radio.validate_update, use=radio.use_item),
|
item_type: ItemTypeHandler(validate_update=module.validate_update, use=module.use_item)
|
||||||
"dice": ItemTypeHandler(validate_update=dice.validate_update, use=dice.use_item),
|
for item_type, module in ITEM_MODULES.items()
|
||||||
"wheel": ItemTypeHandler(validate_update=wheel.validate_update, use=wheel.use_item),
|
|
||||||
"clock": ItemTypeHandler(validate_update=clock.validate_update, use=clock.use_item),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -18,4 +16,3 @@ def get_item_type_handler(item_type: ItemType) -> ItemTypeHandler:
|
|||||||
"""Resolve item-type handler from registry."""
|
"""Resolve item-type handler from registry."""
|
||||||
|
|
||||||
return ITEM_TYPE_HANDLERS[item_type]
|
return ITEM_TYPE_HANDLERS[item_type]
|
||||||
|
|
||||||
|
|||||||
39
server/app/items/registry.py
Normal file
39
server/app/items/registry.py
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
"""Single source of truth for item-type module registration."""
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from typing import Callable, Protocol
|
||||||
|
|
||||||
|
from ..item_types import ItemUseResult
|
||||||
|
from ..models import WorldItem
|
||||||
|
|
||||||
|
from . import clock, dice, radio, wheel
|
||||||
|
|
||||||
|
|
||||||
|
class ItemModule(Protocol):
|
||||||
|
"""Shape required by item modules consumed by catalog/handlers."""
|
||||||
|
|
||||||
|
LABEL: str
|
||||||
|
TOOLTIP: str
|
||||||
|
EDITABLE_PROPERTIES: tuple[str, ...]
|
||||||
|
CAPABILITIES: tuple[str, ...]
|
||||||
|
USE_SOUND: str | None
|
||||||
|
EMIT_SOUND: str | None
|
||||||
|
USE_COOLDOWN_MS: int
|
||||||
|
EMIT_RANGE: int
|
||||||
|
DIRECTIONAL: bool
|
||||||
|
DEFAULT_TITLE: str
|
||||||
|
DEFAULT_PARAMS: dict
|
||||||
|
PROPERTY_METADATA: dict[str, dict[str, object]]
|
||||||
|
validate_update: Callable[[WorldItem, dict], dict]
|
||||||
|
use_item: Callable[[WorldItem, str, Callable[[dict], str]], ItemUseResult]
|
||||||
|
|
||||||
|
|
||||||
|
ITEM_TYPE_ORDER: tuple[str, ...] = ("clock", "dice", "radio_station", "wheel")
|
||||||
|
|
||||||
|
ITEM_MODULES: dict[str, ItemModule] = {
|
||||||
|
"clock": clock,
|
||||||
|
"dice": dice,
|
||||||
|
"radio_station": radio,
|
||||||
|
"wheel": wheel,
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user