diff --git a/include/cinder/Utilities.h b/include/cinder/Utilities.h index 586e86c7af..9dc92d1ad3 100644 --- a/include/cinder/Utilities.h +++ b/include/cinder/Utilities.h @@ -47,6 +47,11 @@ CI_API fs::path getDocumentsDirectory(); //! Removes all files beyond maxFileCount. CI_API void limitDirectoryFileCount( const fs::path& directoryPath, size_t maxFileCount, std::function sortFn = []( const fs::path& p1, const fs::path& p2 ) -> bool { return fs::last_write_time( p1 ) > fs::last_write_time( p2 ); } ); +//! Searches upwards from \a start (file or directory) for an ancestor directory where \a relativeSearch exists, up to \a maxDepth levels; returns absolute path if found, otherwise empty path. +CI_API fs::path findAncestorDir( const fs::path& start, const fs::path& relativeSearch, int maxDepth = 10 ); +//! Searches upwards from \a start (file or directory) for an ancestor file where \a relativeSearch exists, up to \a maxDepth levels; returns absolute path if found, otherwise empty path. +CI_API fs::path findAncestorFile( const fs::path& start, const fs::path& relativeSearch, int maxDepth = 10 ); + //! Launches a path in a web browser CI_API void launchWebBrowser( const Url &url ); diff --git a/src/cinder/Utilities.cpp b/src/cinder/Utilities.cpp index d4f2ee3886..1ef1e7da6f 100644 --- a/src/cinder/Utilities.cpp +++ b/src/cinder/Utilities.cpp @@ -78,6 +78,30 @@ void limitDirectoryFileCount( const fs::path& directoryPath, size_t maxFileCount } } +fs::path findAncestorFile( const fs::path& start, const fs::path& relativeSearch, int maxDepth ) +{ + size_t parentCt = 0; + for( fs::path curPath = start; curPath.has_parent_path() && parentCt <= maxDepth; curPath = curPath.parent_path(), ++parentCt ) { + const fs::path testDir = curPath / relativeSearch; + if( fs::exists( testDir ) && fs::is_regular_file( testDir ) ) + return testDir; + } + + return fs::path(); +} + +fs::path findAncestorDir( const fs::path& start, const fs::path& relativeSearch, int maxDepth ) +{ + size_t parentCt = 0; + for( fs::path curPath = start; curPath.has_parent_path() && parentCt <= maxDepth; curPath = curPath.parent_path(), ++parentCt ) { + const fs::path testDir = curPath / relativeSearch; + if( fs::exists( testDir ) && fs::is_directory( testDir ) ) + return testDir; + } + + return fs::path(); +} + void launchWebBrowser( const Url &url ) { app::Platform::get()->launchWebBrowser( url ); diff --git a/src/cinder/app/Platform.cpp b/src/cinder/app/Platform.cpp index 0a944cb39b..803d55224d 100644 --- a/src/cinder/app/Platform.cpp +++ b/src/cinder/app/Platform.cpp @@ -23,6 +23,7 @@ #include "cinder/app/Platform.h" #include "cinder/CinderAssert.h" +#include "cinder/Utilities.h" #if defined( CINDER_COCOA ) #include "cinder/app/cocoa/PlatformCocoa.h" @@ -145,20 +146,9 @@ const vector& Platform::getAssetDirectories() const void Platform::findAndAddDefaultAssetPath() { - // first search the local directory, then its parent, up to ASSET_SEARCH_DEPTH levels up - // check at least the app path, even if it has no parent directory - auto execPath = getExecutablePath(); - size_t parentCt = 0; - for( fs::path curPath = execPath; curPath.has_parent_path() || ( curPath == execPath ); curPath = curPath.parent_path(), ++parentCt ) { - if( parentCt >= ASSET_SEARCH_DEPTH ) - break; - - const fs::path curAssetDir = curPath / fs::path( "assets" ); - if( fs::exists( curAssetDir ) && fs::is_directory( curAssetDir ) ) { - addAssetDirectory( curAssetDir ); - break; - } - } + fs::path assetDir = findAncestorDir( getExecutablePath(), "assets", ASSET_SEARCH_DEPTH ); + if( ! assetDir.empty() ) + addAssetDirectory( assetDir ); } std::ostream& Platform::console()