| | from __future__ import annotations |
| | from dataclasses import dataclass, field |
| | from typing import Callable |
| | from .enums import NodeKind |
| | from .types import DataType |
| | from .nodes_base import NodeType, NodeInstance |
| |
|
| |
|
| | @dataclass(slots=True) |
| | class Registry: |
| | datatypes: dict[DataType, DataType] = field(default_factory=dict) |
| | node_types: dict[NodeKind, NodeType] = field(default_factory=dict) |
| | factories: dict[NodeKind, Callable[[str], NodeInstance]] = field(default_factory=dict) |
| |
|
| | def register_datatype(self, dt: DataType) -> None: |
| | self.datatypes[dt] = dt |
| |
|
| | def register_node_type(self, t: NodeType, factory: Callable[[str], NodeInstance]) -> None: |
| | self.node_types[t.kind] = t |
| | self.factories[t.kind] = factory |
| |
|
| | def create(self, type_ref: NodeType | NodeKind | str, node_id: str) -> NodeInstance: |
| | """Create node by NodeType, NodeKind, or name. Prefer NodeType or NodeKind.""" |
| | if isinstance(type_ref, NodeType): |
| | kind = type_ref.kind |
| | elif isinstance(type_ref, NodeKind): |
| | kind = type_ref |
| | elif isinstance(type_ref, str): |
| | |
| | match = next((k for k, t in self.node_types.items() |
| | if t.display_name == type_ref or k.value == type_ref), None) |
| | if match is None: |
| | raise KeyError(f"Unknown node type name {type_ref}") |
| | kind = match |
| | else: |
| | raise TypeError("Unsupported type_ref") |
| | return self.factories[kind](node_id) |
| |
|