State Management

This page documents the core state primitives: objectstate.object_state.ObjectState and objectstate.object_state.ObjectStateRegistry. The API is generic—no OpenHCS references—and reflects the current implementation in objectstate/object_state.py.

ObjectState

Purpose

A UI-friendly model extracted from a backing object (dataclass, callable, etc.) that authoritatively stores working parameters and resolved values across a window’s lifecycle.

Core attributes

  • object_instance: the backing object (updated on save via to_object())

  • parameters: flat dict of user-editable values (dotted paths for nested dataclasses)

  • _live_resolved: last resolved values using the current ancestor stack

  • _saved_resolved: resolved values at the last explicit save (baseline)

  • _saved_parameters: immutable snapshot of raw parameters at save time

  • _live_provenance: dict tracking which scope provided each inherited field value

  • scope_id: unique key for registry lookup

Saved vs Live

  • _saved_resolved represents “on disk” (after last save).

  • _live_resolved represents “on screen” (after every edit and ancestor change).

  • mark_saved() updates saved baselines from current live values.

  • restore_saved() resets working values back to the saved snapshot.

  • dirty_fields tracks where _live_resolved differs from _saved_resolved (resolved / inherited view).

  • is_raw_dirty is a fast check for unsaved edits in raw parameters (parameters vs _saved_parameters).

Reading resolved values

ObjectState keeps both a live resolved snapshot and a saved resolved snapshot. Use the appropriate accessor depending on whether you want to include unsaved edits:

  • get_resolved_value(name): returns the live resolved value from _live_resolved (includes unsaved edits)

  • get_saved_resolved_value(name): returns the saved resolved value from _saved_resolved (excludes unsaved edits)

Key methods

  • mark_saved(): set current state as the new baseline

  • restore_saved(): revert parameters/resolved values to saved baseline

  • dirty_fields: resolved diffs (live vs saved) as a set of dotted field names

  • is_raw_dirty: true if raw parameters differ from saved parameters

  • to_object(): materialize a concrete object from the current parameters

Lifecycle

ObjectStates are created when an object is added, persist independently of UI windows, and are removed when unregistered from the registry.

ObjectStateRegistry

Purpose

Singleton registry of all ObjectStates, keyed by scope_id. Supports lookup, ancestry traversal, and history management.

Registration

  • register(state) / unregister(scope_id)

  • get_by_scope(scope_id)

  • get_ancestor_objects(scope_id) / get_ancestor_objects_with_scopes(scope_id)

Saved vs Live pattern (registry-wide)

The registry coordinates saved/live baselines across all ObjectStates so that application code can distinguish “proposed” vs “committed” values while showing immediate UI feedback.

Notes

  • Registry methods are classmethods; the registry is effectively a singleton.

  • History/undo is covered separately in Undo / Redo.

  • Provenance tracking for inherited fields is covered in Provenance Tracking.