feat(view): mint managed lanes to separate cross-mode content per stance (D2 W3-A)

Pure planLaneMinting decides which tracks hold >1 mode's content and which managed
lane each item lands on; view.cpp applies it (I_FREEMODE/I_NUMFIXEDLANES/P_LANENAME/
I_FIXEDLANE) under one undo block, driven off the auto-tag detection tick. Manual lanes
and their items are never touched. Load-time reconcile rebuilds ownership from durable
lane names before reapplying active-mode visibility.
This commit is contained in:
2026-07-23 20:08:38 -04:00
parent fed70c0a80
commit b182146f9a
11 changed files with 673 additions and 4 deletions
+7
View File
@@ -31,6 +31,13 @@ std::string laneNameForMode(const std::string& modeId) {
return std::string(kManagedLanePrefix) + modeId;
}
std::optional<std::string> modeIdFromLaneName(const std::string& laneName) {
if (!hasManagedPrefix(laneName)) return std::nullopt; // manual/unnamed ⇒ no mode
const std::size_t n = std::strlen(kManagedLanePrefix);
if (laneName.size() == n) return std::nullopt; // prefix only, no mode suffix (illegal)
return laneName.substr(n);
}
bool isOnManualLane(bool isFixedLaneTrack, const std::string& laneName) {
// On a normal (non-fixed-lane) track there is no concept of a manual lane; the
// item follows the normal auto-tag rule.