diff --git a/include/fggl/assets/loader.hpp b/include/fggl/assets/loader.hpp index beedcc2711aa337dc82b417ca8da18a25bd57d1c..6c104bd64c5ffe7d8a22a3a4777cec4812db250f 100644 --- a/include/fggl/assets/loader.hpp +++ b/include/fggl/assets/loader.hpp @@ -80,39 +80,23 @@ namespace fggl::assets { return; } - // FIXME use the fancy dependency resolution algorithm from the module system - std::vector<AssetID> loadOrder; - std::stack<AssetID> openSet; - openSet.push(asset); - while ( !openSet.empty() ) { - auto current = openSet.top(); - openSet.pop(); - - if ( !m_checkin->exists(current) ) { - debug::warning("attempted to load chain with unknown assert, {} - abort!", current); - return; - } - - // this WILL (probably) break if an asset ends up in the chain twice - loadOrder.push_back( current ); - const auto& record = m_checkin->find(current); - for ( const auto& dep : record.m_requires ) { - openSet.push( dep ); - } - } + std::queue<AssetID> loadOrder; + m_checkin->loadOrder(asset, loadOrder); processChain(loadOrder, userPtr); } - void processChain( std::vector<AssetID>& loadOrder, void* userPtr = nullptr ) { + void processChain( std::queue<AssetID>& loadOrder, void* userPtr = nullptr ) { if ( loadOrder.empty() ) { return; } debug::info("Starting chain load"); - for ( auto it = loadOrder.rbegin(); it < loadOrder.rend(); ++it ) { - debug::info(" CHAIN -> loading {}", *it ); - load( *it, userPtr ); + while( !loadOrder.empty() ) { + auto it = loadOrder.front(); + debug::info(" CHAIN -> loading {}", it ); + load( it, userPtr ); + loadOrder.pop(); } debug::info("Ended chain loader"); } diff --git a/include/fggl/assets/packed/adapter.hpp b/include/fggl/assets/packed/adapter.hpp index d2299850391801620a421fd26b26602587ce2dc9..a5cbab2871b75fac516edaebe46c0c381edd9b37 100644 --- a/include/fggl/assets/packed/adapter.hpp +++ b/include/fggl/assets/packed/adapter.hpp @@ -25,6 +25,7 @@ #include "fggl/assets/packed/direct.hpp" #include "fggl/data/storage.hpp" +#include "fggl/ds/graph.hpp" namespace fggl::assets { @@ -95,6 +96,10 @@ namespace fggl::assets { return file.m_path; } + void loadOrder( AssetID id, std::queue<AssetID>& order) { + m_requires.getOrderPartialRev(id, order); + } + void discover( const char* packName, bool useCache = false, bool updateCache = true) { if ( m_packs.contains(packName) ) { return; @@ -167,6 +172,7 @@ namespace fggl::assets { data::Storage* m_storage; RawCheckin* m_checkin; std::map<AssetID, ResourceRecord> m_files; + ds::DirectedGraph<AssetID> m_requires; struct PackInfo { std::filesystem::path rootDir; @@ -204,6 +210,8 @@ namespace fggl::assets { // store the resulting data m_files[rr.assetID] = rr; packFiles.push_back( rr.assetID ); + m_requires.addEdges( rr.assetID, rr.m_requires ); + debug::trace("discovered {} ({}) from pack '{}'", rr.assetID, relPath.c_str(), packName.c_str() ); break; } @@ -256,6 +264,7 @@ namespace fggl::assets { }; m_files[ rr.assetID ] = rr; m_packs[ packRoot.filename() ].assets.push_back( rr.assetID ); + m_requires.addEdges( rr.assetID, depList ); debug::trace("discovered {} ({}) from pack {}", rr.assetID.get(), fullPath.c_str(), packRoot.filename().c_str() ); } diff --git a/include/fggl/ds/graph.hpp b/include/fggl/ds/graph.hpp index f88ff5c61adf292b1e43beffc2b9c64adbdb747d..8675c08564ca7afafff015bdf702f1bb5e77edc6 100644 --- a/include/fggl/ds/graph.hpp +++ b/include/fggl/ds/graph.hpp @@ -40,7 +40,7 @@ namespace fggl::ds { * @param start the entry which depends something else * @param end the thing it depends on */ - inline void addEdge(T start, const T end) { + inline void addEdge(const T start, const T end) { m_edges[start].push_back(end); m_edges[end]; } @@ -48,7 +48,7 @@ namespace fggl::ds { /** * Add a single vertex to the graph. */ - inline void addVertex(T vertex) { + inline void addVertex(const T vertex) { m_edges[vertex]; } @@ -61,7 +61,7 @@ namespace fggl::ds { * @param name the entry having dependencies added * @param dependencies the things it depends on */ - void addEdges(const T &name, const std::vector<T> &dependencies) { + void addEdges(const T name, const std::vector<T> &dependencies) { auto existing = m_edges.find(name); if (existing == m_edges.end()) { m_edges[name] = dependencies; @@ -99,6 +99,12 @@ namespace fggl::ds { return true; } + bool getOrderPartial(T first, std::stack<T> &stack) { + std::set<T> visited{}; + sortUtil(first, visited, stack); + return true; + } + bool getOrderRev(std::queue<T> &stack) { std::set<T> visited{}; @@ -111,6 +117,12 @@ namespace fggl::ds { return true; } + bool getOrderPartialRev(T first, std::queue<T>& queue) { + std::set<T> visited{}; + sortUtilRev(first, visited, queue); + return true; + } + private: std::map<T, std::vector<T>> m_edges;