refactor: remove per-type module.py and simplify plugin wiring
This commit is contained in:
@@ -7,7 +7,6 @@ This is a reference layout for adding a new server item type plugin.
|
||||
- `definition.py`: static metadata/defaults/schema constants.
|
||||
- `validator.py`: `validate_update(item, next_params)` normalization and validation.
|
||||
- `actions.py`: `use_item(item, nickname, clock_formatter)` runtime behavior.
|
||||
- `module.py`: thin exported surface combining the three files.
|
||||
- `plugin.py`: registration payload consumed by plugin auto-discovery.
|
||||
|
||||
Use this folder as a copy template when creating a real item under:
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
"""Counter item plugin module surface."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from .actions import use_item
|
||||
from .definition import (
|
||||
CAPABILITIES,
|
||||
DEFAULT_PARAMS,
|
||||
DEFAULT_TITLE,
|
||||
DIRECTIONAL,
|
||||
EDITABLE_PROPERTIES,
|
||||
EMIT_RANGE,
|
||||
EMIT_SOUND,
|
||||
LABEL,
|
||||
PROPERTY_METADATA,
|
||||
TOOLTIP,
|
||||
USE_COOLDOWN_MS,
|
||||
USE_SOUND,
|
||||
)
|
||||
from .validator import validate_update
|
||||
@@ -2,10 +2,11 @@
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from . import module
|
||||
from ..plugin_helpers import build_item_module
|
||||
from . import actions, definition, validator
|
||||
|
||||
ITEM_TYPE_PLUGIN = {
|
||||
"type": "counter",
|
||||
"order": 25,
|
||||
"module": module,
|
||||
"module": build_item_module(definition, validate_update=validator.validate_update, use_item=actions.use_item),
|
||||
}
|
||||
|
||||
@@ -49,7 +49,7 @@
|
||||
|
||||
- Persisted state stores only instance data.
|
||||
- Global/type-level properties are loaded from server registry in `server/app/item_catalog.py`.
|
||||
- Per-type use/update validation and message behavior are implemented in per-item modules under `server/app/items/types/*/module.py`, discovered via plugins in `server/app/items/types/*/plugin.py`.
|
||||
- Per-type use/update validation and message behavior are implemented in per-item modules under `server/app/items/types/*/definition.py`, `validator.py`, and `actions.py`, discovered via plugins in `server/app/items/types/*/plugin.py`.
|
||||
- Client-side add/edit metadata is consumed from `welcome.uiDefinitions` via `client/src/items/itemRegistry.ts` (no local fallback definitions).
|
||||
- End-to-end add-item template: `docs/item-type-template.md`.
|
||||
|
||||
|
||||
@@ -11,7 +11,6 @@ When adding a new item type:
|
||||
- `definition.py` for metadata/constants
|
||||
- `validator.py` for `validate_update(item, next_params)`
|
||||
- `actions.py` for `use_item(item, nickname, clock_formatter)`
|
||||
- `module.py` as thin exported surface
|
||||
- `plugin.py` for registration
|
||||
|
||||
2. Server plugin file
|
||||
@@ -20,11 +19,9 @@ When adding a new item type:
|
||||
- `order`
|
||||
- `module`
|
||||
|
||||
3. Shared item-type unions
|
||||
- Add the type in:
|
||||
- `server/app/models.py`
|
||||
- `client/src/network/protocol.ts`
|
||||
- `client/src/state/gameState.ts`
|
||||
3. Shared type acceptance
|
||||
- Item type ids are string-based in protocol/state models.
|
||||
- For generic new types, no enum/union list updates are required.
|
||||
|
||||
4. Client runtime behavior (optional)
|
||||
- Default: no item-specific client module needed.
|
||||
@@ -34,14 +31,19 @@ That is enough for a first working item type.
|
||||
|
||||
## Reference Sample Folder
|
||||
|
||||
See `docs/examples/item-type-sample/` for a complete copyable folder with all five files.
|
||||
See `docs/examples/item-type-sample/` for a complete copyable folder.
|
||||
|
||||
## Minimal `module.py` Example
|
||||
## Minimal `plugin.py` Example
|
||||
|
||||
```py
|
||||
from .actions import use_item
|
||||
from .definition import LABEL, TOOLTIP, EDITABLE_PROPERTIES, CAPABILITIES, USE_SOUND, EMIT_SOUND, USE_COOLDOWN_MS, EMIT_RANGE, DIRECTIONAL, DEFAULT_TITLE, DEFAULT_PARAMS, PROPERTY_METADATA
|
||||
from .validator import validate_update
|
||||
from ..plugin_helpers import build_item_module
|
||||
from . import actions, definition, validator
|
||||
|
||||
ITEM_TYPE_PLUGIN = {
|
||||
"type": "counter",
|
||||
"order": 25,
|
||||
"module": build_item_module(definition, validate_update=validator.validate_update, use_item=actions.use_item),
|
||||
}
|
||||
```
|
||||
|
||||
## Checklist Before Commit
|
||||
|
||||
@@ -197,14 +197,12 @@ For a full copy/paste example with plain-English explanation, see `docs/item-typ
|
||||
- `definition.py` (defaults/capabilities/metadata/options)
|
||||
- `validator.py` (`validate_update`)
|
||||
- `actions.py` (`use_item`)
|
||||
- `module.py` (thin exported surface)
|
||||
2. Server plugin: add `server/app/items/types/<item_type>/plugin.py` exporting `ITEM_TYPE_PLUGIN` with:
|
||||
- `type`
|
||||
- `order`
|
||||
- `module`
|
||||
The server auto-discovers plugins at boot, so no central registry edit is needed.
|
||||
3. Server models: extend `ItemType` literals in `server/app/models.py` and any packet enums that list item types.
|
||||
4. Client protocol/state types: update item-type unions in `client/src/network/protocol.ts` and `client/src/state/gameState.ts`.
|
||||
3. Server/client protocol/state models are now string-based for item type ids; for generic types no enum/union list updates are required.
|
||||
5. Client runtime behavior: add `client/src/items/types/<item_type>/behavior.ts` only if custom client runtime is needed (for example piano mode).
|
||||
6. Tests: add or update server tests under `server/tests/` for use/update validation, unknown-key stripping, and `uiDefinitions` completeness.
|
||||
|
||||
|
||||
@@ -285,7 +285,8 @@ When adding a new item type:
|
||||
- Missing/invalid schema now disables item menus with explicit status.
|
||||
- Phase 4:
|
||||
- Property editor behavior is metadata-driven by `valueType/range/options/maxLength`.
|
||||
- `visibleWhen` is supported and item property rows recompute live after updates.
|
||||
- `visibleWhen` now survives protocol parsing and item property rows recompute live after updates.
|
||||
- List options are now carried in `propertyMetadata[key].options` (no separate `propertyOptions` map).
|
||||
- Phase 5:
|
||||
- Client runtime behavior remains modular per item via behavior registry; `main.ts` orchestration no longer carries item-specific business branches.
|
||||
- Phase 6:
|
||||
@@ -294,11 +295,16 @@ When adding a new item type:
|
||||
- Save timing now configurable via:
|
||||
- `storage.state_save_debounce_ms`
|
||||
- `storage.state_save_max_delay_ms`
|
||||
- Additional:
|
||||
- Added plugin contract tests to validate required item package files/exports.
|
||||
- Added unknown-item-type rejection for `item_add`.
|
||||
- Added `capabilities` in `welcome.uiDefinitions.itemTypes`.
|
||||
- Removed hardcoded client/server item-type enum restrictions (string-based ids + runtime known-type checks).
|
||||
|
||||
### Notes
|
||||
- Client item-specific runtime is now reduced to only `piano`; simple items (`dice`, `wheel`, `clock`, `radio_station`, `widget`) run through generic client flows with no custom behavior module.
|
||||
- Server item implementations now live inside per-type folders (`server/app/items/types/*/module.py`) and plugins point directly to those modules.
|
||||
- Server type packages are now split into `definition.py` / `validator.py` / `actions.py` plus a thin `module.py` export surface.
|
||||
- Server item implementations now live inside per-type folders (`server/app/items/types/*/definition.py`, `validator.py`, `actions.py`).
|
||||
- Plugins now compose module surfaces via a shared helper (`server/app/items/types/plugin_helpers.py`), so per-type `module.py` is no longer required.
|
||||
- Added docs sample folder at `docs/examples/item-type-sample/` and updated template docs to reflect the package layout.
|
||||
## Completion Review (2026-02-24)
|
||||
|
||||
@@ -306,64 +312,11 @@ When adding a new item type:
|
||||
- **Phase 0 (docs + guardrails):** ✅ Complete. `docs/item-schema.md` exists and server tests cover UI schema completeness + unknown-key stripping behavior.
|
||||
- **Phase 1 (server package standardization + auto-discovery):** ✅ Complete. Item types are standardized under `server/app/items/types/*` with `plugin.py` entrypoints and discovered by `server/app/items/registry.py`.
|
||||
- **Phase 2 (strict validation + unknown-key stripping):** ✅ Complete. Type validators enforce allowed keys and normalize values; tests verify unknown params are stripped.
|
||||
- **Phase 3 (client removes fallback authority):** ✅ Mostly complete. Client consumes `welcome.uiDefinitions` and disables item menus when schema is missing.
|
||||
- **Phase 4 (metadata-driven editor + visibility dependencies):** ⚠️ Partially complete. Generic metadata-driven editing is in place, but `visibleWhen` is not included in the client protocol schema, so dependency visibility rules from server metadata are dropped during message validation.
|
||||
- **Phase 3 (client removes fallback authority):** ✅ Complete. Client consumes `welcome.uiDefinitions` and disables item menus when schema is missing.
|
||||
- **Phase 4 (metadata-driven editor + visibility dependencies):** ✅ Complete. Generic metadata-driven editing is in place and `visibleWhen` survives client protocol parsing.
|
||||
- **Phase 5 (behavior registry completion):** ✅ Complete. Runtime behavior is registry-driven with generic path + optional piano module.
|
||||
- **Phase 6 (coalesced persistence):** ✅ Complete. Debounced/max-delay state save and flush-on-shutdown are implemented in server lifecycle.
|
||||
|
||||
### Recommendations / Cleanup (for simplest new-item creation)
|
||||
1. **Unblock `visibleWhen` end-to-end (high priority).**
|
||||
Scope:
|
||||
- Carry `visibleWhen` from server metadata through client protocol validation into `itemRegistry`.
|
||||
Problem today:
|
||||
- Server emits `visibleWhen`, but client protocol schema drops unknown metadata fields, so dependency visibility can silently fail.
|
||||
Implementation:
|
||||
- Update `client/src/network/protocol.ts` `welcome.uiDefinitions.itemTypes[].propertyMetadata` schema to allow `visibleWhen` object values of `string | number | boolean`.
|
||||
- Keep `client/src/items/itemRegistry.ts` normalization strict (ignore invalid `visibleWhen` entries).
|
||||
- Add a client test/fixture (or lightweight runtime assertion) that confirms `visibleWhen` survives parse.
|
||||
Acceptance criteria:
|
||||
- For a property like `facing` with `visibleWhen: { directional: true }`, toggling `directional` updates property visibility without hardcoded client logic.
|
||||
|
||||
2. **Remove hardcoded item-type literals (high priority).**
|
||||
Scope:
|
||||
- Reduce manual edits needed when adding a new item type.
|
||||
Problem today:
|
||||
- Type additions still touch multiple literal lists (`Literal[...]`, unions, enums) across server/client protocol/state models.
|
||||
Implementation:
|
||||
- Server:
|
||||
- Keep runtime source of truth in plugin registry.
|
||||
- Limit literal usage to protocol boundary where needed; validate item type membership against discovered registry set.
|
||||
- Client:
|
||||
- Replace rigid item-type enums in parse paths with string + runtime membership checks from server-provided definitions where feasible.
|
||||
- Keep compile-time unions only where they materially improve safety and can be generated/centralized.
|
||||
Acceptance criteria:
|
||||
- Adding a new item plugin does not require editing multiple type-literal lists in unrelated files.
|
||||
- New type appears in add/edit flows after server metadata update with minimal client changes.
|
||||
|
||||
3. **Include `capabilities` in `welcome.uiDefinitions.itemTypes` (medium).**
|
||||
Scope:
|
||||
- Complete server metadata contract for item UI/runtime decisions.
|
||||
Problem today:
|
||||
- `capabilities` exist on `WorldItem`, but not consistently in type definition metadata payload for menu/rules decisions.
|
||||
Implementation:
|
||||
- Add `capabilities` per item type in server `uiDefinitions.itemTypes[]` payload.
|
||||
- Parse/store on client registry model.
|
||||
- Use this metadata for UI gating where applicable (for example, show/hide unsupported actions for a type).
|
||||
Acceptance criteria:
|
||||
- Client can decide type-level action affordances from `uiDefinitions` alone, without extra hardcoded assumptions.
|
||||
|
||||
4. **Move list options into per-property metadata (medium).**
|
||||
Scope:
|
||||
- Consolidate split item property config sources.
|
||||
Problem today:
|
||||
- Options are split between `propertyOptions` and `propertyMetadata`, causing parallel maintenance.
|
||||
Implementation:
|
||||
- Server emits list options at `propertyMetadata[key].options`.
|
||||
- Client reads options from metadata first.
|
||||
- Remove separate `propertyOptions` map.
|
||||
Acceptance criteria:
|
||||
- One canonical place (`propertyMetadata`) defines type, range, tooltip, options, and visibility for each property.
|
||||
- New list property requires server-only metadata changes for options.
|
||||
|
||||
5. **Eliminate manual property label mapping in client (medium):** either include labels in server metadata or auto-humanize keys so new properties are readable without code changes.
|
||||
6. **Add a script/check for “new item completeness” (low):** one CI check that verifies plugin discovery, protocol acceptance, docs presence, and test coverage for each discovered type.
|
||||
### Recommendations / Cleanup (remaining)
|
||||
1. **Eliminate manual property label mapping in client (medium):** either include labels for all properties in server metadata or auto-humanize keys so new properties are readable without code changes.
|
||||
2. **Strengthen new-item completeness checks (low):** extend the plugin contract tests to optionally assert docs coverage and richer protocol examples per discovered type.
|
||||
|
||||
@@ -1,3 +1 @@
|
||||
"""Item type package exposing plugin module surface."""
|
||||
|
||||
from .module import * # noqa: F401,F403
|
||||
"""Clock item type plugin package."""
|
||||
|
||||
@@ -1,41 +0,0 @@
|
||||
"""Clock item plugin module surface."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from .actions import use_item
|
||||
from .definition import (
|
||||
CAPABILITIES,
|
||||
DEFAULT_PARAMS,
|
||||
DEFAULT_TIME_ZONE,
|
||||
DEFAULT_TITLE,
|
||||
DIRECTIONAL,
|
||||
EDITABLE_PROPERTIES,
|
||||
EMIT_RANGE,
|
||||
EMIT_SOUND,
|
||||
LABEL,
|
||||
PROPERTY_METADATA,
|
||||
TIME_ZONE_OPTIONS,
|
||||
TOOLTIP,
|
||||
USE_COOLDOWN_MS,
|
||||
USE_SOUND,
|
||||
)
|
||||
from .validator import validate_update
|
||||
|
||||
__all__ = [
|
||||
"LABEL",
|
||||
"TOOLTIP",
|
||||
"EDITABLE_PROPERTIES",
|
||||
"CAPABILITIES",
|
||||
"USE_SOUND",
|
||||
"EMIT_SOUND",
|
||||
"USE_COOLDOWN_MS",
|
||||
"EMIT_RANGE",
|
||||
"DIRECTIONAL",
|
||||
"DEFAULT_TITLE",
|
||||
"DEFAULT_TIME_ZONE",
|
||||
"TIME_ZONE_OPTIONS",
|
||||
"DEFAULT_PARAMS",
|
||||
"PROPERTY_METADATA",
|
||||
"validate_update",
|
||||
"use_item",
|
||||
]
|
||||
@@ -2,10 +2,11 @@
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from . import module
|
||||
from ..plugin_helpers import build_item_module
|
||||
from . import actions, definition, validator
|
||||
|
||||
ITEM_TYPE_PLUGIN = {
|
||||
"type": "clock",
|
||||
"order": 10,
|
||||
"module": module,
|
||||
"module": build_item_module(definition, validate_update=validator.validate_update, use_item=actions.use_item),
|
||||
}
|
||||
|
||||
@@ -1,3 +1 @@
|
||||
"""Item type package exposing plugin module surface."""
|
||||
|
||||
from .module import * # noqa: F401,F403
|
||||
"""Dice item type plugin package."""
|
||||
|
||||
@@ -1,37 +0,0 @@
|
||||
"""Dice item plugin module surface."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from .actions import use_item
|
||||
from .definition import (
|
||||
CAPABILITIES,
|
||||
DEFAULT_PARAMS,
|
||||
DEFAULT_TITLE,
|
||||
DIRECTIONAL,
|
||||
EDITABLE_PROPERTIES,
|
||||
EMIT_RANGE,
|
||||
EMIT_SOUND,
|
||||
LABEL,
|
||||
PROPERTY_METADATA,
|
||||
TOOLTIP,
|
||||
USE_COOLDOWN_MS,
|
||||
USE_SOUND,
|
||||
)
|
||||
from .validator import validate_update
|
||||
|
||||
__all__ = [
|
||||
"LABEL",
|
||||
"TOOLTIP",
|
||||
"EDITABLE_PROPERTIES",
|
||||
"CAPABILITIES",
|
||||
"USE_SOUND",
|
||||
"EMIT_SOUND",
|
||||
"USE_COOLDOWN_MS",
|
||||
"EMIT_RANGE",
|
||||
"DIRECTIONAL",
|
||||
"DEFAULT_TITLE",
|
||||
"DEFAULT_PARAMS",
|
||||
"PROPERTY_METADATA",
|
||||
"validate_update",
|
||||
"use_item",
|
||||
]
|
||||
@@ -2,10 +2,11 @@
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from . import module
|
||||
from ..plugin_helpers import build_item_module
|
||||
from . import actions, definition, validator
|
||||
|
||||
ITEM_TYPE_PLUGIN = {
|
||||
"type": "dice",
|
||||
"order": 20,
|
||||
"module": module,
|
||||
"module": build_item_module(definition, validate_update=validator.validate_update, use_item=actions.use_item),
|
||||
}
|
||||
|
||||
@@ -1,3 +1 @@
|
||||
"""Item type package exposing plugin module surface."""
|
||||
|
||||
from .module import * # noqa: F401,F403
|
||||
"""Piano item type plugin package."""
|
||||
|
||||
@@ -1,41 +0,0 @@
|
||||
"""Piano item plugin module surface."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from .actions import use_item
|
||||
from .definition import (
|
||||
CAPABILITIES,
|
||||
DEFAULT_PARAMS,
|
||||
DEFAULT_TITLE,
|
||||
DIRECTIONAL,
|
||||
EDITABLE_PROPERTIES,
|
||||
EMIT_RANGE,
|
||||
EMIT_SOUND,
|
||||
INSTRUMENT_OPTIONS,
|
||||
LABEL,
|
||||
PROPERTY_METADATA,
|
||||
TOOLTIP,
|
||||
USE_COOLDOWN_MS,
|
||||
USE_SOUND,
|
||||
VOICE_MODE_OPTIONS,
|
||||
)
|
||||
from .validator import validate_update
|
||||
|
||||
__all__ = [
|
||||
"LABEL",
|
||||
"TOOLTIP",
|
||||
"EDITABLE_PROPERTIES",
|
||||
"CAPABILITIES",
|
||||
"USE_SOUND",
|
||||
"EMIT_SOUND",
|
||||
"USE_COOLDOWN_MS",
|
||||
"EMIT_RANGE",
|
||||
"DIRECTIONAL",
|
||||
"DEFAULT_TITLE",
|
||||
"DEFAULT_PARAMS",
|
||||
"PROPERTY_METADATA",
|
||||
"INSTRUMENT_OPTIONS",
|
||||
"VOICE_MODE_OPTIONS",
|
||||
"validate_update",
|
||||
"use_item",
|
||||
]
|
||||
@@ -2,10 +2,11 @@
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from . import module
|
||||
from ..plugin_helpers import build_item_module
|
||||
from . import actions, definition, validator
|
||||
|
||||
ITEM_TYPE_PLUGIN = {
|
||||
"type": "piano",
|
||||
"order": 30,
|
||||
"module": module,
|
||||
"module": build_item_module(definition, validate_update=validator.validate_update, use_item=actions.use_item),
|
||||
}
|
||||
|
||||
19
server/app/items/types/plugin_helpers.py
Normal file
19
server/app/items/types/plugin_helpers.py
Normal file
@@ -0,0 +1,19 @@
|
||||
"""Helpers for composing item plugin module surfaces."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from types import SimpleNamespace
|
||||
from typing import Any
|
||||
|
||||
|
||||
def build_item_module(definition: Any, *, validate_update: Any, use_item: Any) -> Any:
|
||||
"""Compose a plugin module-like object from split definition/validator/actions files."""
|
||||
|
||||
exports: dict[str, Any] = {
|
||||
name: getattr(definition, name)
|
||||
for name in dir(definition)
|
||||
if name.isupper()
|
||||
}
|
||||
exports["validate_update"] = validate_update
|
||||
exports["use_item"] = use_item
|
||||
return SimpleNamespace(**exports)
|
||||
@@ -1,3 +1 @@
|
||||
"""Item type package exposing plugin module surface."""
|
||||
|
||||
from .module import * # noqa: F401,F403
|
||||
"""Radio station item type plugin package."""
|
||||
|
||||
@@ -1,41 +0,0 @@
|
||||
"""Radio item plugin module surface."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from .actions import use_item
|
||||
from .definition import (
|
||||
CAPABILITIES,
|
||||
CHANNEL_OPTIONS,
|
||||
DEFAULT_PARAMS,
|
||||
DEFAULT_TITLE,
|
||||
DIRECTIONAL,
|
||||
EDITABLE_PROPERTIES,
|
||||
EFFECT_OPTIONS,
|
||||
EMIT_RANGE,
|
||||
EMIT_SOUND,
|
||||
LABEL,
|
||||
PROPERTY_METADATA,
|
||||
TOOLTIP,
|
||||
USE_COOLDOWN_MS,
|
||||
USE_SOUND,
|
||||
)
|
||||
from .validator import validate_update
|
||||
|
||||
__all__ = [
|
||||
"LABEL",
|
||||
"TOOLTIP",
|
||||
"EDITABLE_PROPERTIES",
|
||||
"CAPABILITIES",
|
||||
"USE_SOUND",
|
||||
"EMIT_SOUND",
|
||||
"USE_COOLDOWN_MS",
|
||||
"EMIT_RANGE",
|
||||
"DIRECTIONAL",
|
||||
"DEFAULT_TITLE",
|
||||
"DEFAULT_PARAMS",
|
||||
"PROPERTY_METADATA",
|
||||
"CHANNEL_OPTIONS",
|
||||
"EFFECT_OPTIONS",
|
||||
"validate_update",
|
||||
"use_item",
|
||||
]
|
||||
@@ -2,10 +2,11 @@
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from . import module
|
||||
from ..plugin_helpers import build_item_module
|
||||
from . import actions, definition, validator
|
||||
|
||||
ITEM_TYPE_PLUGIN = {
|
||||
"type": "radio_station",
|
||||
"order": 40,
|
||||
"module": module,
|
||||
"module": build_item_module(definition, validate_update=validator.validate_update, use_item=actions.use_item),
|
||||
}
|
||||
|
||||
@@ -1,3 +1 @@
|
||||
"""Item type package exposing plugin module surface."""
|
||||
|
||||
from .module import * # noqa: F401,F403
|
||||
"""Wheel item type plugin package."""
|
||||
|
||||
@@ -1,37 +0,0 @@
|
||||
"""Wheel item plugin module surface."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from .actions import use_item
|
||||
from .definition import (
|
||||
CAPABILITIES,
|
||||
DEFAULT_PARAMS,
|
||||
DEFAULT_TITLE,
|
||||
DIRECTIONAL,
|
||||
EDITABLE_PROPERTIES,
|
||||
EMIT_RANGE,
|
||||
EMIT_SOUND,
|
||||
LABEL,
|
||||
PROPERTY_METADATA,
|
||||
TOOLTIP,
|
||||
USE_COOLDOWN_MS,
|
||||
USE_SOUND,
|
||||
)
|
||||
from .validator import validate_update
|
||||
|
||||
__all__ = [
|
||||
"LABEL",
|
||||
"TOOLTIP",
|
||||
"EDITABLE_PROPERTIES",
|
||||
"CAPABILITIES",
|
||||
"USE_SOUND",
|
||||
"EMIT_SOUND",
|
||||
"USE_COOLDOWN_MS",
|
||||
"EMIT_RANGE",
|
||||
"DIRECTIONAL",
|
||||
"DEFAULT_TITLE",
|
||||
"DEFAULT_PARAMS",
|
||||
"PROPERTY_METADATA",
|
||||
"validate_update",
|
||||
"use_item",
|
||||
]
|
||||
@@ -2,10 +2,11 @@
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from . import module
|
||||
from ..plugin_helpers import build_item_module
|
||||
from . import actions, definition, validator
|
||||
|
||||
ITEM_TYPE_PLUGIN = {
|
||||
"type": "wheel",
|
||||
"order": 50,
|
||||
"module": module,
|
||||
"module": build_item_module(definition, validate_update=validator.validate_update, use_item=actions.use_item),
|
||||
}
|
||||
|
||||
@@ -1,3 +1 @@
|
||||
"""Item type package exposing plugin module surface."""
|
||||
|
||||
from .module import * # noqa: F401,F403
|
||||
"""Widget item type plugin package."""
|
||||
|
||||
@@ -1,39 +0,0 @@
|
||||
"""Widget item plugin module surface."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from .actions import use_item
|
||||
from .definition import (
|
||||
CAPABILITIES,
|
||||
DEFAULT_PARAMS,
|
||||
DEFAULT_TITLE,
|
||||
DIRECTIONAL,
|
||||
EDITABLE_PROPERTIES,
|
||||
EFFECT_OPTIONS,
|
||||
EMIT_RANGE,
|
||||
EMIT_SOUND,
|
||||
LABEL,
|
||||
PROPERTY_METADATA,
|
||||
TOOLTIP,
|
||||
USE_COOLDOWN_MS,
|
||||
USE_SOUND,
|
||||
)
|
||||
from .validator import validate_update
|
||||
|
||||
__all__ = [
|
||||
"LABEL",
|
||||
"TOOLTIP",
|
||||
"EDITABLE_PROPERTIES",
|
||||
"CAPABILITIES",
|
||||
"USE_SOUND",
|
||||
"EMIT_SOUND",
|
||||
"USE_COOLDOWN_MS",
|
||||
"EMIT_RANGE",
|
||||
"DIRECTIONAL",
|
||||
"DEFAULT_TITLE",
|
||||
"DEFAULT_PARAMS",
|
||||
"PROPERTY_METADATA",
|
||||
"EFFECT_OPTIONS",
|
||||
"validate_update",
|
||||
"use_item",
|
||||
]
|
||||
@@ -2,10 +2,11 @@
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from . import module
|
||||
from ..plugin_helpers import build_item_module
|
||||
from . import actions, definition, validator
|
||||
|
||||
ITEM_TYPE_PLUGIN = {
|
||||
"type": "widget",
|
||||
"order": 60,
|
||||
"module": module,
|
||||
"module": build_item_module(definition, validate_update=validator.validate_update, use_item=actions.use_item),
|
||||
}
|
||||
|
||||
@@ -28,5 +28,4 @@ def test_item_plugin_folders_have_required_files() -> None:
|
||||
assert (type_dir / "definition.py").is_file()
|
||||
assert (type_dir / "validator.py").is_file()
|
||||
assert (type_dir / "actions.py").is_file()
|
||||
assert (type_dir / "module.py").is_file()
|
||||
assert (type_dir / "plugin.py").is_file()
|
||||
|
||||
Reference in New Issue
Block a user