| | from __future__ import annotations |
| |
|
| | from dataclasses import dataclass, field |
| | from typing import Iterable, Callable |
| |
|
| | from .enums import NodeKind, DataPortState |
| | from .ports import PortSchema, PortState |
| |
|
| |
|
| | @dataclass(slots=True) |
| | class NodeType: |
| | """Static node type metadata.""" |
| | kind: NodeKind |
| | display_name: str |
| | inputs: list[PortSchema] |
| | outputs: list[PortSchema] |
| |
|
| |
|
| | @dataclass(slots=True) |
| | class NodeInstance: |
| | """Runtime node instance.""" |
| | node_id: str |
| | node_type: NodeType |
| | auto_process: bool = False |
| | x: float = 0 |
| | y: float = 0 |
| | inputs: dict[str, PortState] = field(default_factory=dict) |
| | outputs: dict[str, PortState] = field(default_factory=dict) |
| | on_process: Callable[["NodeInstance"], None] | None = None |
| |
|
| | def __post_init__(self) -> None: |
| | if not self.inputs: |
| | self.inputs = {p.name: PortState(p) for p in self.node_type.inputs} |
| | if not self.outputs: |
| | self.outputs = {p.name: PortState(p) for p in self.node_type.outputs} |
| |
|
| | def all_inputs(self) -> Iterable[PortState]: |
| | return self.inputs.values() |
| |
|
| | def all_outputs(self) -> Iterable[PortState]: |
| | return self.outputs.values() |
| |
|
| | def mark_dirty(self) -> None: |
| | for p in self.all_outputs(): |
| | p.state = DataPortState.DIRTY |
| |
|
| | async def process(self) -> None: |
| | if self.on_process: |
| | |
| | import inspect |
| | if inspect.iscoroutinefunction(self.on_process): |
| | await self.on_process(self) |
| | else: |
| | self.on_process(self) |
| | else: |
| | pass |
| |
|
| | def reset_node(self) -> None: |
| | pass |
| |
|