// See view_solo.h. Compiled into the reaper_reasampler module; includes // reaper_plugin_functions.h without REAPERAPI_IMPLEMENT (main.cpp owns that). #include "shell/view/view_solo.h" #include #define REAPERAPI_MINIMAL #define REAPERAPI_WANT_GetMediaTrackInfo_Value #define REAPERAPI_WANT_SetMediaTrackInfo_Value #include "reaper_plugin_functions.h" namespace reasampler { namespace { // SDK: int, 0=not soloed, 1=soloed, 2=soloed in place, 5=safe soloed, // 6=safe soloed in place. Documented under SetMediaTrackInfo_Value with no // read-only marker (unlike B_RECMON_IN_EFFECT in the same list), so it is settable. constexpr const char* kSoloParm = "I_SOLO"; } // namespace std::vector readTrackSolos(const TrackHandles& handles) { std::vector live; live.reserve(handles.size()); for (const auto& [guid, tr] : handles) { if (!tr) continue; live.push_back(view::TrackSolo{ guid, static_cast(GetMediaTrackInfo_Value(tr, kSoloParm))}); } return live; } void applySoloOps(const TrackHandles& handles, const std::vector& ops) { if (ops.empty()) return; // the common case: nothing soloed, no project write std::map byGuid; for (const view::SoloOp& op : ops) byGuid[op.guid] = op.value; for (const auto& [guid, tr] : handles) { if (!tr) continue; auto it = byGuid.find(guid); if (it == byGuid.end()) continue; SetMediaTrackInfo_Value(tr, kSoloParm, static_cast(it->second)); } } void clearTrackSolos(const TrackHandles& handles, const std::map& soloed) { std::vector ops; ops.reserve(soloed.size()); for (const auto& entry : soloed) ops.push_back(view::SoloOp{entry.first, 0}); applySoloOps(handles, ops); } void restoreTrackSolos(const TrackHandles& handles, const std::map& cached, const std::set& liveGuids, const std::set& visibleGuids) { applySoloOps(handles, view::planSoloRestore(cached, liveGuids, visibleGuids)); } } // namespace reasampler