docs: 1.0 documentation restructure
Split root CLAUDE.md into 19 per-directory files scoped to their source area. Roll v0 history into docs/ARCHIVE.md; retire CONTEXT.md, CONTEXT-ARCHIVE.md, PLAN.md, COMPLETED.md. Move plan docs under docs/. Rescue 9 live deferrals into docs/TODO.md.
This commit is contained in:
@@ -0,0 +1,104 @@
|
||||
# src/core/view — pure Design View mode model
|
||||
|
||||
## Scope
|
||||
|
||||
Pure, REAPER-free Design View model: mode/track membership, folder-derived
|
||||
visibility, snapshot-based park/restore planning, new-content (GUID) detection,
|
||||
and the managed/manual lane-identity convention that underlies per-item mode
|
||||
separation (fixed lanes). Does **not** include: the actual DAW-side flag
|
||||
application (hide, CPU-park, per-FX offline, restore via `B_SHOWINTCP` /
|
||||
`B_SHOWINMIXER` / `B_MAINSEND` / `I_FXEN`) or the never-touch-master/mute/solo
|
||||
enforcement — those live in `shell/view`.
|
||||
|
||||
## Invariants
|
||||
|
||||
Design View — additive phase spec (settled decisions; Two-canvas sub-phase,
|
||||
settled 2026-07-23):
|
||||
|
||||
- **Membership.** Default = Arrange; every untagged leaf belongs to it. Leaves
|
||||
opt in to Design (or any mode). No track appears in two modes at once except
|
||||
via an explicit show-both toggle or parent/folder derivation.
|
||||
- **Parents are derived, never tagged.** A parent/folder track is visible in
|
||||
mode M if either any descendant leaf is visible in M, or the parent belongs to
|
||||
M by its own membership; an untagged parent is an Arrange member by default. A
|
||||
parent is never parked in any mode it is visible in. Master track is always
|
||||
visible and never touched.
|
||||
- **N-mode model, two-mode UI.** The data model carries arbitrarily many modes;
|
||||
the UI ships Arrange + Design. A mode is (stable id, display name, ordinal).
|
||||
- **Persistence.** Membership index + last-active mode + per-track flag
|
||||
snapshots ride in the existing `"reasampler"` project ext-state namespace and
|
||||
travel with the `.rpp`.
|
||||
- **Non-destructive restore (enforced in the pure layer).** For every flag the
|
||||
tool drives, snapshot the prior value before parking; on toggle-back, restore
|
||||
from the snapshot, never to a hardcoded default. Round-trip (snapshot → park →
|
||||
restore) returns every driven flag to its captured value — this is the
|
||||
phase's trust anchor, the analog of the capture null test.
|
||||
- **GUID-keyed, reorder-safe.** Membership keys on track GUID (`GetTrackGUID`),
|
||||
never track index; tolerates unknown/stale GUIDs (pruned on reconcile via
|
||||
`ViewModeModel::reconcile(liveGuids)`).
|
||||
- **Relative/portable state only** in the persisted view section (GUID strings,
|
||||
mode ids — no absolute paths, no index positions).
|
||||
- **Show-both semantics.** A per-track "pin visible across modes" flag that
|
||||
re-enables processing whenever shown. A show-both leaf appears in every
|
||||
mode's visible set and is never parked — its driven flags stay at
|
||||
snapshot/restored values. Stored on the membership record; persists;
|
||||
togglable per selection.
|
||||
- **Non-goals / guardrails:** No literal second canvas — a second window or
|
||||
duplicated project stays rejected; subproject/second-project-file approaches
|
||||
and overloading item `D_POSITION` with mode semantics (timebase-offset
|
||||
regions) are rejected paths (the latter collides with the capture null test).
|
||||
Every leaf is managed: an untagged leaf is an Arrange member and, when the
|
||||
active mode is not Arrange, is fully parked and snapshot-restored exactly
|
||||
like a tagged leaf; show-both is the only way to opt a leaf out of parking.
|
||||
Restore from snapshot, never to a default: no hardcoded "on" restores.
|
||||
|
||||
**Two-canvas sub-phase (Phase D2/E) — settled and landed parts only:**
|
||||
|
||||
- **Mechanism: fixed item lanes.** Map mode → lane; toggle drives per-lane
|
||||
play/show so only the active mode's lane is present. Items keep their real
|
||||
position and real track — nothing is moved in time or deleted.
|
||||
- **Membership: adoption rule for new items; active mode for new tracks.** New
|
||||
tracks are tagged to the active mode at creation. New items follow an
|
||||
adoption rule: if the item's track has pre-existing managed-eligible content
|
||||
spanning exactly one mode, the item adopts that mode; the active-mode
|
||||
fallback applies only when the track is empty or already spans multiple
|
||||
modes. Items in manual lanes are excluded from the prior-mode computation and
|
||||
are not auto-tagged at all. Membership is exclusive per item except via
|
||||
show-both.
|
||||
- **Managed vs. manual lanes — indexed and distinct.** The tool maintains a
|
||||
lane-ownership index — per (track GUID, lane): managed (which mode owns it)
|
||||
vs. manual (user-minted, outside the mode system). Mode operations touch only
|
||||
managed lanes; manual lanes are never shown, hidden, silenced, or re-laned by
|
||||
a toggle, and their `C_LANEPLAYS` stays exactly as the user set it. The
|
||||
ownership index rides in `"reasampler"` `view_state` alongside the membership
|
||||
index, GUID-keyed and portable. **New invariant — mode operations touch only
|
||||
managed lanes:** "the 'which lanes may this toggle touch' decision is a pure
|
||||
query over the ownership index; only reading REAPER's live lane state is
|
||||
shell."
|
||||
- **REAPER floor: v7** for this sub-phase (fixed lanes shipped in v7); no
|
||||
version-gate branch — below v7 the sub-phase is simply unavailable.
|
||||
- Precision invariants (null test, bit-identical repeats, non-destructive,
|
||||
exact bounds, relative-paths-only) are entirely unaffected by this
|
||||
sub-phase — no capture path changes; lane assignment and `C_LANEPLAYS` are
|
||||
reversible flags, never a destructive operation.
|
||||
|
||||
## Modules
|
||||
|
||||
- `view_mode_model` — Design View mode system: mode registry, GUID-keyed membership, folder-tree-aware visibility derivation, snapshot-based park/restore planner, JSON round-trip.
|
||||
- `view_tree` — pure `I_FOLDERDEPTH`→FolderTree helper for the Design View shell.
|
||||
- `mode_switch` — REAPER-free segment layout + hit-test for the bank_panel's Design View mode switch.
|
||||
- `guid_diff` — the pure, REAPER-free core of the D2 Wave-2 new-content detection: `newGuids(previous, current)` computes the GUIDs present in `current` but absent from `previous` (empty GUIDs ignored); `GuidBaseline` tracks the live GUID set across polls for one project, implementing the first-poll-after-open guard (the first `observe()` after construction/`reset()` records a baseline and reports nothing new, so pre-existing content is never mass-tagged) and re-arms via `reset()` on a detected project switch so detection never diffs across two unrelated projects.
|
||||
- `lane_keys` — the pure, REAPER-free convention mapping a fixed lane's durable REAPER name (`P_LANENAME:n`) to the opaque lane-key `view_mode_model` keys by, plus the managed/manual heuristic both the toggle-apply path and the new-content/auto-tag exemption path share: `kManagedLanePrefix` ("reasampler:") stamps every lane the tool mints; `isManagedLaneName`/`managedLaneKey`/`laneNameForMode`/`modeIdFromLaneName` round-trip a lane name ↔ its owning mode id; `isOnManualLane` is the single predicate governing which lanes a toggle may drive and which items are exempt from auto-tag.
|
||||
|
||||
## Gotchas
|
||||
|
||||
- REAPER exposes no durable per-lane GUID — the only lane identity is the
|
||||
ordinal `I_FIXEDLANE`, which REAPER renumbers on reorder/delete. Lane
|
||||
identity must ride on the durable `P_LANENAME` (`lane_keys`), never the raw
|
||||
ordinal, or a reorder will silently corrupt managed/manual ownership.
|
||||
- `kManagedLanePrefix` ("reasampler:") is stable-forever like an action-id
|
||||
string — changing it strands the ownership of every already-minted lane in
|
||||
every already-saved project.
|
||||
- `guid_diff::GuidBaseline` must have `reset()` called on every detected
|
||||
project switch, or the next `observe()` will diff across two unrelated
|
||||
projects and mass-tag (or miss) content.
|
||||
Reference in New Issue
Block a user