72 lines
2.8 KiB
C++
72 lines
2.8 KiB
C++
#include "core/view/fx_state.h"
|
|
|
|
#include <cstddef>
|
|
#include <utility>
|
|
|
|
namespace reasampler::view {
|
|
|
|
namespace {
|
|
|
|
// Slot keying, deliberately: the live chain IS the target set, so its positions
|
|
// are current by construction. Identity keying would drop an FX REAPER reports no
|
|
// GUID for, and reclaim has to reach those too.
|
|
std::vector<FxOfflineOp> offlineTargets(const std::string& trackGuid,
|
|
const std::vector<std::string>& liveFxGuids) {
|
|
std::vector<FxOfflineOp> ops;
|
|
ops.reserve(liveFxGuids.size());
|
|
for (std::size_t i = 0; i < liveFxGuids.size(); ++i)
|
|
ops.push_back(FxOfflineOp{trackGuid, FxKeying::Slot, liveFxGuids[i],
|
|
static_cast<int>(i), true});
|
|
return ops;
|
|
}
|
|
|
|
} // namespace
|
|
|
|
std::vector<FxOfflineOp> fxRestoreTargets(const ViewModeModel& model,
|
|
const std::string& trackGuid) {
|
|
std::vector<FxOfflineOp> ops;
|
|
if (!model.holdsSnapshotFx(trackGuid)) return ops;
|
|
|
|
const TrackSnapshot* snap = model.snapshot(trackGuid);
|
|
ops.reserve(snap->fxOffline.size());
|
|
for (std::size_t i = 0; i < snap->fxOffline.size(); ++i) {
|
|
const FxOfflineState& fx = snap->fxOffline[i];
|
|
ops.push_back(FxOfflineOp{trackGuid, snap->fxKeying, fx.fxGuid,
|
|
static_cast<int>(i), fx.offline != 0});
|
|
}
|
|
return ops;
|
|
}
|
|
|
|
std::vector<FxTrackWork> desiredFxState(const ViewModeModel& model,
|
|
const std::string& targetMode,
|
|
const std::set<std::string>& liveTrackGuids) {
|
|
std::vector<FxTrackWork> online;
|
|
std::vector<FxTrackWork> offline;
|
|
|
|
for (const auto& [guid, snap] : model.snapshots()) { // std::map ⇒ GUID order
|
|
if (liveTrackGuids.count(guid) == 0) continue; // dead track — nothing to write
|
|
|
|
if (!model.leafBelongsToMode(guid, targetMode)) {
|
|
offline.push_back(FxTrackWork{guid, FxWorkKind::Offline, {}});
|
|
continue;
|
|
}
|
|
// Active with the FX half already released: the chain is back online and
|
|
// the record is only waiting on its flags. Nothing owed either way.
|
|
if (!snap.fxHeld) continue;
|
|
online.push_back(FxTrackWork{guid, FxWorkKind::Online, fxRestoreTargets(model, guid)});
|
|
}
|
|
|
|
online.reserve(online.size() + offline.size());
|
|
for (FxTrackWork& w : offline) online.push_back(std::move(w));
|
|
return online;
|
|
}
|
|
|
|
FxRestoreResolution resolveFxWork(const FxTrackWork& work,
|
|
const std::vector<std::string>& liveFxGuids) {
|
|
if (work.kind == FxWorkKind::Offline)
|
|
return resolveFxRestore(offlineTargets(work.trackGuid, liveFxGuids), liveFxGuids);
|
|
return resolveFxRestore(work.targets, liveFxGuids);
|
|
}
|
|
|
|
} // namespace reasampler::view
|