Aegisub/src/factory_manager.h
arch1t3cht 02567c2265 Rework the audio/video provider system
This became necessary now that more providers were added. Providers can
be proritized for certain file types (e.g. .vpy files will always be
opened with VapourSynth), and when the default provider fails on a file,
the user will be notified and be asked to pick an alternative provider.
2023-07-16 17:52:21 +02:00

73 lines
2.2 KiB
C++

// Copyright (c) 2014, Thomas Goyne <plorkyeran@aegisub.org>
//
// Permission to use, copy, modify, and distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
//
// Aegisub Project http://www.aegisub.org/
#include <string>
#include <vector>
#include <libaegisub/fs.h>
namespace {
template<typename Container>
std::vector<std::string> GetClasses(Container const& c) {
std::vector<std::string> list;
for (auto const& provider : c) {
if (!provider.hidden)
list.push_back(provider.name);
}
return list;
}
template<typename Container>
auto GetSorted(Container const& c, std::string const& preferred) -> std::vector<decltype(&*c.begin())> {
std::vector<decltype(&*c.begin())> sorted;
sorted.reserve(std::distance(c.begin(), c.end()));
size_t end_of_hidden = 0;
bool any_hidden = false;
for (auto const& provider : c) {
if (provider.hidden) {
sorted.push_back(&provider);
any_hidden = true;
}
else if (any_hidden && end_of_hidden == 0) {
end_of_hidden = sorted.size();
sorted.push_back(&provider);
}
else if (preferred == provider.name)
sorted.insert(sorted.begin() + end_of_hidden, &provider);
else
sorted.push_back(&provider);
}
return sorted;
}
template<typename Container>
auto RearrangeWithPriority(Container &c, agi::fs::path const& filename) {
size_t end_of_hidden = 0;
for (size_t i = 0; i < c.size(); i++) {
auto provider = c[i];
if (provider->hidden) {
end_of_hidden = i;
} else {
if (provider->wants_to_open(filename)) {
c.erase(c.begin() + i);
c.insert(c.begin() + end_of_hidden + 1, provider);
break;
}
}
}
}
}