Skip to content

structural

structural #

Nodes that control the organization and execution order of other procedures.

Structural procedures control the organization and execution order of other procedures: sequential execution, parallel execution, optional steps, and the append-an-element loop.

OptionalProcedure #

Bases: Procedure[Void]

Mark a procedure as optional, allowing it to be skipped or fail gracefully.

The wrapped procedure can fail without causing the overall workflow to fail, and its result is discarded. Useful for non-critical actions; build one with cg.do_optional(step) or the cg.optional() block.

Attributes:

Name Type Description
procedure Procedure[CGType]

The procedure to run optionally; its result is discarded.

Source code in capturegraph-lib/capturegraph/procedures/nodes/process/structural.py
@make_procedure
class OptionalProcedure(Procedure[Void]):
    """Mark a procedure as optional, allowing it to be skipped or fail gracefully.

    The wrapped procedure can fail without causing the overall workflow to fail,
    and its result is discarded. Useful for non-critical actions; build one with
    ``cg.do_optional(step)`` or the ``cg.optional()`` block.

    Attributes:
        procedure: The procedure to run optionally; its result is discarded.
    """

    procedure: Procedure[CGType]

PreloadProcedure #

Bases: Procedure[T]

Run procedure preloaded with default's result, and return its result.

The runtime evaluates default (typically a constant) and preloads it into procedure — the same preload a cache uses to re-fill a node from stored data — so the wrapped node starts complete and never blocks the capture. Wrapping a user-input node turns its question into an option: a control pre-answered with a sensible default the user may still adjust (RAW on a photo, a frame-rate preference on a video). node.preload(default) builds this.

Attributes:

Name Type Description
procedure Procedure[CGType]

The procedure to preload; its (possibly user-adjusted) result is returned.

default Procedure[CGType]

The default to preload, matching procedure's type by structure.

Source code in capturegraph-lib/capturegraph/procedures/nodes/process/structural.py
@make_procedure
class PreloadProcedure[T: CGType](Procedure[T]):
    """Run ``procedure`` preloaded with ``default``'s result, and return its result.

    The runtime evaluates ``default`` (typically a constant) and preloads it into
    ``procedure`` — the same preload a cache uses to re-fill a node from stored
    data — so the wrapped node starts complete and never blocks the capture.
    Wrapping a user-input node turns its question into an *option*: a control
    pre-answered with a sensible default the user may still adjust (RAW on a
    photo, a frame-rate preference on a video). ``node.preload(default)``
    builds this.

    Attributes:
        procedure: The procedure to preload; its (possibly user-adjusted)
            result is returned.
        default: The default to preload, matching ``procedure``'s type by
            structure.
    """

    procedure: Procedure[CGType]
    default: Procedure[CGType]

    def __post_init__(self) -> None:
        """Resolve ``_return_type`` to the procedure's type, validating the match."""
        super().__post_init__()
        procedure_type = self.procedure._return_type
        default_type = self.default._return_type
        if not structural_eq(procedure_type, default_type):
            raise TypeError(
                f"PreloadProcedure: cannot preload a "
                f"{getattr(procedure_type, '__name__', procedure_type)} procedure "
                f"with a {getattr(default_type, '__name__', default_type)} default"
            )
        object.__setattr__(self, "_return_type", procedure_type)

__post_init__() #

Resolve _return_type to the procedure's type, validating the match.

Source code in capturegraph-lib/capturegraph/procedures/nodes/process/structural.py
def __post_init__(self) -> None:
    """Resolve ``_return_type`` to the procedure's type, validating the match."""
    super().__post_init__()
    procedure_type = self.procedure._return_type
    default_type = self.default._return_type
    if not structural_eq(procedure_type, default_type):
        raise TypeError(
            f"PreloadProcedure: cannot preload a "
            f"{getattr(procedure_type, '__name__', procedure_type)} procedure "
            f"with a {getattr(default_type, '__name__', default_type)} default"
        )
    object.__setattr__(self, "_return_type", procedure_type)

ProcedureSequence #

Bases: Procedure[Void]

Execute a list of procedures in sequential order.

Each procedure runs to completion before the next. A step may return a value (e.g. a CacheProcedure returns the value it stored); the sequence runs it for effect and discards the result, returning Void.

Attributes:

Name Type Description
procedures Substeps

List of procedures to execute in order.

Source code in capturegraph-lib/capturegraph/procedures/nodes/process/structural.py
@make_procedure
class ProcedureSequence(Procedure[Void]):
    """Execute a list of procedures in sequential order.

    Each procedure runs to completion before the next. A step may return a value
    (e.g. a ``CacheProcedure`` returns the value it stored); the sequence runs it
    for effect and discards the result, returning ``Void``.

    Attributes:
        procedures: List of procedures to execute in order.
    """

    procedures: Substeps

ProcedureSet #

Bases: Procedure[Void]

Execute a list of procedures concurrently (in parallel).

All procedures in the set start together and can complete in any order; their results are discarded and the set returns Void.

Attributes:

Name Type Description
procedures Substeps

List of procedures to execute concurrently.

Source code in capturegraph-lib/capturegraph/procedures/nodes/process/structural.py
@make_procedure
class ProcedureSet(Procedure[Void]):
    """Execute a list of procedures concurrently (in parallel).

    All procedures in the set start together and can complete in any order;
    their results are discarded and the set returns ``Void``.

    Attributes:
        procedures: List of procedures to execute concurrently.
    """

    procedures: Substeps

ProcedureWhile #

Bases: Procedure[Void]

Repeatedly run a body, appending one array element per iteration.

Do-while semantics: body runs at least once, then condition is evaluated; while it is true (and max_iterations is not reached) the body runs again, each iteration appending a fresh element to array_path (via a PathAppend node inside the body). The with cg.while_repeat(condition, array_path): block authors this node, yielding the appended element to cache into; construct it directly only for a hand-built graph.

On the device, the body and condition are duplicated per iteration (template instantiation), so each iteration gets independent state and its own array element. Loop-invariant inputs (array_path, max_iterations) are referenced without duplication. The serializer computes which nodes loop and records their ids in the template_nodes setting automatically.

Attributes:

Name Type Description
body Procedure[Void]

The loop body to run each iteration (typically a ProcedureSequence).

condition Input[Bool]

Boolean procedure evaluated after each iteration; loop continues while true.

array_path Procedure[Path]

The Path to the Array each iteration appends into.

max_iterations Input[Number]

Maximum iteration count (a Number value or a procedure producing one), evaluated once.

Source code in capturegraph-lib/capturegraph/procedures/nodes/process/structural.py
@make_procedure
class ProcedureWhile(Procedure[Void]):
    """Repeatedly run a body, appending one array element per iteration.

    Do-while semantics: ``body`` runs at least once, then ``condition`` is
    evaluated; while it is true (and ``max_iterations`` is not reached) the body
    runs again, each iteration appending a fresh element to ``array_path`` (via a
    ``PathAppend`` node inside the body). The ``with cg.while_repeat(condition,
    array_path):`` block authors this node, yielding the appended element to cache
    into; construct it directly only for a hand-built graph.

    On the device, the body and condition are duplicated per iteration (template
    instantiation), so each iteration gets independent state and its own array
    element. Loop-invariant inputs (``array_path``, ``max_iterations``) are
    referenced without duplication. The serializer computes which nodes loop and
    records their ids in the ``template_nodes`` setting automatically.

    Attributes:
        body: The loop body to run each iteration (typically a ProcedureSequence).
        condition: Boolean procedure evaluated after each iteration; loop
            continues while true.
        array_path: The ``Path`` to the ``Array`` each iteration appends into.
        max_iterations: Maximum iteration count (a ``Number`` value or a procedure
            producing one), evaluated once.
    """

    body: Procedure[Void]
    condition: Input[Bool]
    array_path: Procedure[Path]
    max_iterations: Input[Number]

RequiredProcedure #

Bases: Procedure[Void]

Run a procedure for effect and discard its result.

Wraps any procedure into a Void step: it runs procedure to completion, drops whatever it returns, and is the required counterpart of [OptionalProcedure][]. cg.do(step) builds this, and |= / &= wrap each cache in one so a stored value is never left dangling.

Attributes:

Name Type Description
procedure Procedure[CGType]

The procedure to run; its result is discarded.

Source code in capturegraph-lib/capturegraph/procedures/nodes/process/structural.py
@make_procedure
class RequiredProcedure(Procedure[Void]):
    """Run a procedure for effect and discard its result.

    Wraps any procedure into a ``Void`` step: it runs ``procedure`` to completion,
    drops whatever it returns, and is the required counterpart of
    [OptionalProcedure][]. ``cg.do(step)`` builds this, and ``|=`` / ``&=``
    wrap each cache in one so a stored value is never left dangling.

    Attributes:
        procedure: The procedure to run; its result is discarded.
    """

    procedure: Procedure[CGType]