Files
projectm/src/libprojectM/PresetFactoryManager.cpp
Kai Blaschke ca9af04704 Fix texture loading if casing mismatches filename
Always use lower-case unqualified names to find and cache the actual textures.
2024-12-16 17:52:51 +01:00

145 lines
3.4 KiB
C++

#include "PresetFactoryManager.hpp"
#include <MilkdropPreset/Factory.hpp>
#include <Utils.hpp>
#include <algorithm>
#include <cassert>
#include <iostream>
#include <sstream>
namespace libprojectM {
PresetFactoryManager::~PresetFactoryManager()
{
ClearFactories();
}
void PresetFactoryManager::ClearFactories()
{
m_factoryMap.clear();
for (std::vector<PresetFactory*>::iterator pos = m_factoryList.begin();
pos != m_factoryList.end(); ++pos)
{
assert(*pos);
delete (*pos);
}
m_factoryList.clear();
}
void PresetFactoryManager::initialize()
{
ClearFactories();
auto* milkdropFactory = new MilkdropPreset::Factory();
registerFactory(milkdropFactory->supportedExtensions(), milkdropFactory);
}
// Current behavior if a conflict is occurs is to override the previous request
void PresetFactoryManager::registerFactory(const std::string& extensions, PresetFactory* factory)
{
std::stringstream ss(extensions);
std::string extension;
m_factoryList.push_back(factory);
while (ss >> extension)
{
if (m_factoryMap.count(extension))
{
std::cerr << "[PresetFactoryManager] Warning: extension \"" << extension << "\" already has a factory. New factory handler ignored." << std::endl;
}
else
{
m_factoryMap.insert(std::make_pair(extension, factory));
}
}
}
std::unique_ptr<Preset> PresetFactoryManager::CreatePresetFromFile(const std::string& filename)
{
try
{
const std::string extension = "." + ParseExtension(filename);
return factory(extension).LoadPresetFromFile(filename);
}
catch (const PresetFactoryException&)
{
throw;
}
catch (const std::exception& e)
{
throw PresetFactoryException(e.what());
}
catch (...)
{
throw PresetFactoryException("Uncaught preset factory exception");
}
}
std::unique_ptr<Preset> PresetFactoryManager::CreatePresetFromStream(const std::string& extension, std::istream& data)
{
try
{
return factory(extension).LoadPresetFromStream(data);
}
catch (const PresetFactoryException&)
{
throw;
}
catch (const std::exception& e)
{
throw PresetFactoryException(e.what());
}
catch (...)
{
throw PresetFactoryException("Uncaught preset factory exception");
}
}
PresetFactory& PresetFactoryManager::factory(const std::string& extension)
{
if (!extensionHandled(extension))
{
std::ostringstream os;
os << "No preset factory associated with \"" << extension << "\"." << std::endl;
throw PresetFactoryException(os.str());
}
return *m_factoryMap[extension];
}
bool PresetFactoryManager::extensionHandled(const std::string& extension) const
{
return m_factoryMap.count(extension);
}
std::vector<std::string> PresetFactoryManager::extensionsHandled() const
{
std::vector<std::string> retval;
for (auto const& element : m_factoryMap)
{
retval.push_back(element.first);
}
return retval;
}
//CPP17: std::filesystem::path::extension
auto PresetFactoryManager::ParseExtension(const std::string& filename) -> std::string
{
const auto start = filename.find_last_of('.');
if (start == std::string::npos || start >= (filename.length() - 1)) {
return "";
}
return Utils::ToLower(filename.substr(start + 1, filename.length()));
}
} // namespace libprojectM