Source code for pySimBlocks.gui.models.block_instance

# ******************************************************************************
#                                  pySimBlocks
#                     Copyright (c) 2026 Université de Lille & INRIA
# ******************************************************************************
#  This program is free software: you can redistribute it and/or modify it
#  under the terms of the GNU Lesser General Public License as published by
#  the Free Software Foundation, either version 3 of the License, or (at your
#  option) any later version.
#
#  This program is distributed in the hope that it will be useful, but WITHOUT
#  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
#  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
#  for more details.
#
#  You should have received a copy of the GNU Lesser General Public License
#  along with this program.  If not, see <https://www.gnu.org/licenses/>.
# ******************************************************************************
#  Authors: see Authors.txt
# ******************************************************************************

import uuid
from typing import TYPE_CHECKING, Any, Dict, List

from pySimBlocks.gui.models.port_instance import PortInstance

try: # Python 3.11+
    from typing import Self
except ImportError: # Python <3.11
    from typing_extensions import Self


if TYPE_CHECKING:
    from pySimBlocks.gui.blocks.block_meta import BlockMeta


[docs] class BlockInstance: """Represent a mutable GUI-side instance of a block. Attributes: uid: Unique identifier for this instance. meta: Immutable block metadata definition. name: Editable block instance name. parameters: Current parameter values for the instance. ports: Resolved input and output ports for the instance. """ # -------------------------------------------------------------------------- # Class Methods # --------------------------------------------------------------------------
[docs] @classmethod def copy(cls, block: Self) -> Self: """Create a shallow copy of a block instance. Args: block: Block instance to copy. Returns: Copied block instance with duplicated parameters. """ cpy = BlockInstance(block.meta) cpy.name = block.name cpy.parameters = block.parameters.copy() return cpy
def __init__(self, meta: 'BlockMeta'): """Initialize a block instance from metadata. Args: meta: Block metadata definition. Raises: None. """ self.uid: str = uuid.uuid4().hex self.meta = meta self.name: str = meta.name self.parameters: Dict[str, Any] = self._init_parameters() self.ports: List[PortInstance] = [] # --- Public methods ---
[docs] def update_params(self, params: dict[str, Any]): """Update existing parameter values from a mapping. Args: params: Parameter values keyed by parameter name. """ for k, v in params.items(): if k in self.parameters: self.parameters[k] = v
[docs] def resolve_ports(self) -> None: """Rebuild ports while preserving existing instances when possible.""" new_ports = self.meta.build_ports(self) if not self.ports: self.ports = new_ports return old_inputs = [p for p in self.ports if p.direction == "input"] old_outputs = [p for p in self.ports if p.direction == "output"] updated_ports = [] for np in new_ports: if np.direction == "input": if old_inputs: p = old_inputs.pop(0) p.name = np.name p.display_as = np.display_as updated_ports.append(p) else: updated_ports.append(np) else: if old_outputs: p = old_outputs.pop(0) p.name = np.name p.display_as = np.display_as updated_ports.append(p) else: updated_ports.append(np) self.ports = updated_ports
[docs] def active_parameters(self) -> dict[str, Any]: """Return only the parameters active under the current configuration. Returns: Active parameters keyed by parameter name. """ return { k: v for k, v in self.parameters.items() if self.meta.is_parameter_active(k, self.parameters) }
# --- Private methods --- def _init_parameters(self) -> dict[str, Any]: """Initialize parameter values from metadata defaults.""" params = {} for p in self.meta.parameters: params[p.name] = p.default if p.autofill else None return params