#ifndef URDE_PROJECT_RESOURCE_FACTORY_HPP #define URDE_PROJECT_RESOURCE_FACTORY_HPP #include "Runtime/IFactory.hpp" #include "Runtime/CFactoryMgr.hpp" #include "DataSpec/DNACommon/NamedResourceCatalog.hpp" namespace URDE { class ProjectResourceFactory : public pshag::IFactory { std::unordered_map m_resPaths; std::unordered_map m_namedResources; pshag::CFactoryMgr m_factoryMgr; template void RecursiveAddDirObjects(const HECL::ProjectPath& path, const DataSpec::NamedResourceCatalog& catalog) { HECL::DirectoryEnumerator de = path.enumerateDir(); const int idLen = 5 + (IDType::BinarySize() * 2); for (const HECL::DirectoryEnumerator::Entry& ent : de) { if (ent.m_isDir) RecursiveAddDirObjects(HECL::ProjectPath(path, ent.m_name), catalog); if (ent.m_name.size() == idLen && ent.m_name[4] == _S('_')) { HECL::SystemUTF8View entu8(ent.m_name); u64 id = strtouq(entu8.c_str() + 5, nullptr, 16); if (id) { pshag::SObjectTag objTag = {HECL::FourCC(entu8.c_str()), id}; if (m_resPaths.find(objTag) == m_resPaths.end()) m_resPaths[objTag] = HECL::ProjectPath(path, ent.m_name); } } else { HECL::SystemUTF8View nameView(ent.m_name); auto it = std::find_if(catalog.namedResources.begin(), catalog.namedResources.end(), [&nameView](const typename DataSpec::NamedResourceCatalog::NamedResource& res) -> bool { return res.name == nameView.str(); }); if (it == catalog.namedResources.end()) continue; const typename DataSpec::NamedResourceCatalog::NamedResource& nr = *it; pshag::SObjectTag objTag = GetTag(nr); m_namedResources[nr.name.c_str()] = objTag; m_resPaths[objTag] = HECL::ProjectPath(path, ent.m_name); } } } template pshag::SObjectTag GetTag(const DataSpec::NamedResourceCatalog::NamedResource &nr, typename std::enable_if::value>::type* = 0) { return { nr.type, nr.uid.toUint32() }; } template pshag::SObjectTag GetTag(const typename DataSpec::NamedResourceCatalog::NamedResource& nr, typename std::enable_if::value>::type* = 0) { return { nr.type, nr.uid.toUint64() }; } public: ProjectResourceFactory(); void BuildObjectMap(const HECL::Database::Project::ProjectDataSpec& spec); std::unique_ptr Build(const pshag::SObjectTag&, const pshag::CVParamTransfer&); void BuildAsync(const pshag::SObjectTag&, const pshag::CVParamTransfer&, pshag::IObj**); void CancelBuild(const pshag::SObjectTag&); bool CanBuild(const pshag::SObjectTag&); const pshag::SObjectTag* GetResourceIdByName(const char*) const; }; } #endif // URDE_PROJECT_RESOURCE_FACTORY_HPP