Skip to content

Commit

Permalink
Resolve multi-sample missing monoliths also (#1379)
Browse files Browse the repository at this point in the history
* Resolve multi-sample missing monoliths also

and continue to clean up the code a bit

* Missing header
  • Loading branch information
baconpaul authored Sep 26, 2024
1 parent 007f382 commit 285fd01
Show file tree
Hide file tree
Showing 7 changed files with 136 additions and 34 deletions.
2 changes: 1 addition & 1 deletion src-ui/app/editor-impl/SCXTEditorResponseHandlers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -422,7 +422,7 @@ void SCXTEditor::onMissingResolutionWorkItemList(
{
for (const auto &wi : items)
{
SCLOG("Missing resolution work item");
SCLOG("Missing resolution " << (wi.isMultiUsed ? "multi-use " : "") << "work item");
SCLOG(" path : " << wi.path.u8string());
SCLOG(" id : " << wi.missingID.to_string());
}
Expand Down
118 changes: 116 additions & 2 deletions src/engine/missing_resolution.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,25 +26,139 @@
*/

#include "missing_resolution.h"
#include "messaging/messaging.h"

namespace scxt::engine
{
std::vector<MissingResolutionWorkItem> collectMissingResolutionWorkItems(const Engine &e)
{
std::vector<MissingResolutionWorkItem> res;

const auto &sm = e.getSampleManager();
auto it = sm->samplesBegin();
while (it != sm->samplesEnd())
{
const auto &[id, s] = *it;
if (s->isMissingPlaceholder)
{
res.push_back({id, s->mFileName});
res.push_back({id, s->mFileName, false});
}
it++;
}

std::sort(res.begin(), res.end(),
[](const auto &a, const auto &b) { return a.path.u8string() < b.path.u8string(); });

auto rit = 0;
auto rnext = 1;
while (rnext < res.size())
{
if (res[rit].missingID.sameMD5As(res[rnext].missingID) && res[rit].path == res[rnext].path)
{
res[rit].isMultiUsed = true;
res.erase(res.begin() + rnext);
}
else
{
rnext++;
rit++;
}
}

return res;
}

void resolveSingleFileMissingWorkItem(engine::Engine &e, const MissingResolutionWorkItem &mwi,
const fs::path &p)
{

auto smp = e.getSampleManager()->loadSampleByPath(p);
SCLOG("Resolving : " << p.u8string());
SCLOG(" Was : " << mwi.missingID.to_string());
SCLOG(" To : " << smp->to_string());
if (smp.has_value())
{
for (auto &p : *(e.getPatch()))
{
for (auto &g : *p)
{
for (auto &z : *g)
{
int vidx{0};
for (auto &v : z->variantData.variants)
{
if (v.active && v.sampleID == mwi.missingID)
{
SCLOG(" Zone : " << z->getName());
v.sampleID = *smp;
z->attachToSampleAtVariation(
*(e.getSampleManager()), *smp, vidx,
engine::Zone::SampleInformationRead::ENDPOINTS);
}
vidx++;
}
}
}
}
}
}

void resolveMultiFileMissingWorkItem(engine::Engine &e, const MissingResolutionWorkItem &mwi,
const fs::path &p)
{
bool isSF2{false}, isMultiSample{false};
if (extensionMatches(p, ".sf2"))
{
isSF2 = true;
}

if (!isSF2 && !isMultiSample)
{
SCLOG("Cant deteremine multi style for " << p.u8string());
e.getMessageController()->reportErrorToClient(
"Unable to resolve missing with multifile",
"Can't determine the multifile type for path '" + p.u8string() + "''");
return;
}

for (auto &pt : *(e.getPatch()))
{
for (auto &g : *pt)
{
for (auto &z : *g)
{
int vidx{0};
for (auto &v : z->variantData.variants)
{
if (v.active && v.sampleID.sameMD5As(mwi.missingID))
{
std::optional<SampleID> nid;
if (isSF2)
{
nid = e.getSampleManager()->loadSampleFromSF2(
p, nullptr, v.sampleID.multiAddress[0], v.sampleID.multiAddress[1],
v.sampleID.multiAddress[2]);
}
if (isMultiSample)
{
nid = e.getSampleManager()->loadSampleFromMultiSample(
p, v.sampleID.multiAddress[2], mwi.missingID);
}
if (nid.has_value())
{
SCLOG("Re-attaching to multi in " << z->getName());
SCLOG(" Was : " << v.sampleID.to_string());
SCLOG(" To : " << nid->to_string());
v.sampleID = *nid;
z->attachToSampleAtVariation(
*(e.getSampleManager()), *nid, vidx,
engine::Zone::SampleInformationRead::ENDPOINTS);
}
}
vidx++;
}
}
}
}
}

} // namespace scxt::engine
6 changes: 6 additions & 0 deletions src/engine/missing_resolution.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,16 @@ struct MissingResolutionWorkItem
{
SampleID missingID;
fs::path path;
bool isMultiUsed{false};
};

std::vector<MissingResolutionWorkItem> collectMissingResolutionWorkItems(const Engine &e);

void resolveSingleFileMissingWorkItem(engine::Engine &e, const MissingResolutionWorkItem &mwi,
const fs::path &p);

void resolveMultiFileMissingWorkItem(engine::Engine &e, const MissingResolutionWorkItem &mwi,
const fs::path &p);
} // namespace scxt::engine

#endif // MISSING_RESOLUTION_H
6 changes: 2 additions & 4 deletions src/json/missing_resolution_traits.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,13 +40,11 @@
namespace scxt::json
{
SC_STREAMDEF(scxt::engine::MissingResolutionWorkItem, SC_FROM({
v = {
{"i", from.missingID},
{"p", from.path.u8string()},
};
v = {{"i", from.missingID}, {"p", from.path.u8string()}, {"m", from.isMultiUsed}};
}),
SC_TO({
findIf(v, "i", to.missingID);
findOrSet(v, "m", false, to.isMultiUsed);
std::string fp;
findIf(v, "p", fp);
to.path = fs::path(fs::u8path(fp));
Expand Down
34 changes: 7 additions & 27 deletions src/messaging/client/missing_resolution_messages.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,34 +47,14 @@ inline void doResolveSample(const resolveSamplePayload_t &payload, engine::Engin
{
auto mwi = std::get<0>(payload);
auto p = fs::path(fs::u8path(std::get<1>(payload)));
auto smp = e.getSampleManager()->loadSampleByPath(p);
SCLOG("Resolving : " << p.u8string());
SCLOG(" Was : " << mwi.missingID.to_string());
SCLOG(" To : " << smp->to_string());
if (smp.has_value())

if (mwi.isMultiUsed)
{
engine::resolveMultiFileMissingWorkItem(e, mwi, p);
}
else
{
for (auto &p : *(e.getPatch()))
{
for (auto &g : *p)
{
for (auto &z : *g)
{
int vidx{0};
for (auto &v : z->variantData.variants)
{
if (v.active && v.sampleID == mwi.missingID)
{
SCLOG(" Zone : " << z->getName());
v.sampleID = *smp;
z->attachToSampleAtVariation(
*(e.getSampleManager()), *smp, vidx,
engine::Zone::SampleInformationRead::ENDPOINTS);
}
vidx++;
}
}
}
}
engine::resolveSingleFileMissingWorkItem(e, mwi, p);
}
e.getSampleManager()->purgeUnreferencedSamples();
e.sendFullRefreshToClient();
Expand Down
2 changes: 2 additions & 0 deletions src/sample/sample_manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@ void SampleManager::restoreFromSampleAddressesAndIDs(const sampleAddressesAndIds
nid = loadSampleFromMultiSample(addr.path, addr.region, id);
}
break;
// add something here? don't forget to add it in the multi resolver too in
// resolveSingleFileMissingWorkItem
}

if (nid.has_value())
Expand Down
2 changes: 2 additions & 0 deletions src/utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,8 @@ struct SampleID

bool isValid() const { return md5[0] != 'x' && md5[1] != '\0'; }

bool sameMD5As(const SampleID &other) const { return strncmp(md5, other.md5, md5len) == 0; }

void setAsInvalid()
{
memset(md5, 0, sizeof(md5));
Expand Down

0 comments on commit 285fd01

Please sign in to comment.