From e49720ecfa19d760fb5b6d9f9afad3dbbb43d814 Mon Sep 17 00:00:00 2001 From: Mischa Spiegelmock Date: Tue, 28 Jul 2020 22:01:56 +0300 Subject: [PATCH] Preset subdirs (#385) Scanning textures/presets dirs for textures and scanning preset dir for presets. Scanning is now done recursively, so presets and textures can be organized into subdirectories instead of needing to be flattened into a single directory. On POSIX systems makes use of [ftw](https://linux.die.net/man/3/ftw) which should be relatively efficient. Otherwise falls back to recursing with `dirent` (for windows). Probably should have made an autoconf check for `ftw` instead of doing `#ifdef WIN32`. * Scan subdirectories in presets directory * remove preset subdir config * Recursively scan for textures too, add c++-17 compatibility * Refactor directory scanning code so it's reused by texture loader and preset loader. Make cross-platform (maybe) * filescanner in makefile * extension filter for file loader * make extensions match up' * need string.h * Add FileScanner.cpp to win build (maybe) * scan all dirs * #ifndef #ifdef is def fun * bogus comment * bleh * bleh * itunes plugin with c++17 * EyeTunes needs to know about the FileScanner Co-authored-by: milkdropper.com Co-authored-by: milkdropper <59471060+milkdropper@users.noreply.github.com> --- Makefile.am | 6 - configure.ac | 10 - msvc/projectM.vcxproj | 3 +- .../EyeTune.Shared/EyeTune.Shared.vcxitems | 1 + src/libprojectM/Common.hpp | 2 +- src/libprojectM/FileScanner.cpp | 180 +++++++++++++++++ src/libprojectM/FileScanner.hpp | 60 ++++++ src/libprojectM/Makefile.am | 4 +- .../MilkdropPresetFactory/InitCond.cpp | 2 +- .../MilkdropPresetFactory/MilkdropPreset.cpp | 6 +- .../MilkdropPresetFactory/MilkdropPreset.hpp | 12 +- .../MilkdropPresetFactory.cpp | 3 +- .../MilkdropPresetFactory.hpp | 9 +- .../MilkdropPresetFactory/PerPixelEqn.cpp | 2 +- .../MilkdropPresetFactory/PerPixelEqn.hpp | 2 +- .../NativePresetFactory.hpp | 2 +- src/libprojectM/PresetFactoryManager.cpp | 12 +- src/libprojectM/PresetFactoryManager.hpp | 2 + src/libprojectM/PresetLoader.cpp | 187 +++++------------- src/libprojectM/PresetLoader.hpp | 53 ++--- src/libprojectM/Renderer/TextureManager.cpp | 103 +++------- src/libprojectM/Renderer/TextureManager.hpp | 2 +- src/libprojectM/Renderer/Waveform.cpp | 4 +- .../libprojectM.xcodeproj/project.pbxproj | 14 +- src/libprojectM/omptl/omptl_algorithm_ser.h | 4 +- .../iTunes Plugin.xcodeproj/project.pbxproj | 6 +- .../SDLprojectM.xcodeproj/project.pbxproj | 18 +- 27 files changed, 379 insertions(+), 330 deletions(-) create mode 100644 src/libprojectM/FileScanner.cpp create mode 100644 src/libprojectM/FileScanner.hpp diff --git a/Makefile.am b/Makefile.am index be8efb1ac..92cf4880e 100644 --- a/Makefile.am +++ b/Makefile.am @@ -11,7 +11,6 @@ CLEANFILES=dist # aka /usr/local/share/projectM pm_data_dir = $(pkgdatadir) pm_font_dir = $(pm_data_dir)/fonts -pm_presets_dir = $(pm_data_dir)/presets # files to install pm_data__DATA = src/libprojectM/config.inp @@ -19,13 +18,8 @@ pm_font__DATA = fonts/Vera.ttf fonts/VeraMono.ttf # find and install all preset files install-data-local: -if ENABLE_PRESET_SUBDIRS find "$(PRESETSDIR)" -type d -exec $(MKDIR_P) "$(DESTDIR)/$(pm_data_dir)/{}" \; find "$(PRESETSDIR)" -type f -exec $(INSTALL_DATA) "{}" "$(DESTDIR)/$(pm_data_dir)/{}" \; -else - test -z $(DESTDIR)$(pkgdatadir) || $(MKDIR_P) $(DESTDIR)$(pm_presets_dir) - find "$(PRESETSDIR)" -type f -print0 | LC_ALL=C sort -z | xargs -0 '-I{}' $(INSTALL_DATA) '{}' $(DESTDIR)$(pm_presets_dir) -endif # from https://stackoverflow.com/questions/30897170/ac-subst-does-not-expand-variable answer: https://stackoverflow.com/a/30960268 # ptomato https://stackoverflow.com/users/172999/ptomato diff --git a/configure.ac b/configure.ac index 341d26103..a83320508 100644 --- a/configure.ac +++ b/configure.ac @@ -32,7 +32,6 @@ AS_IF([test "x$enable_emscripten" = "xyes" || test "x$EMSCRIPTEN" = "xyes"], [ enable_threading=no enable_gles=yes enable_sdl=yes - enable_preset_subdirs=no ], [ dnl Running in a normal OS (not emscripten) AX_CHECK_GL @@ -127,13 +126,6 @@ AC_ARG_ENABLE([gles], AC_DEFINE([USE_GLES], [1], [Define USE_GLES]) ]) -AC_ARG_ENABLE([preset_subdirs], - AS_HELP_STRING([--enable-preset-subdirs], [Organize presets into subdirectories.]), - [], [enable_preset_subdirs=no]) - AS_IF([test "x$enable_preset_subdirs" = "xyes"], [ - AC_DEFINE([ENABLE_PRESET_SUBDIRS], [1], [Define ENABLE_PRESET_SUBDIRS]) -]) - dnl LLVM dnl unfortuately AX_LLVM macro seems to be out of date, so we're going to rely on the user to make sure LLVM is installed correctly AC_ARG_ENABLE([llvm], @@ -228,7 +220,6 @@ AM_CONDITIONAL([ENABLE_QT], [test "x$enable_qt" = "xyes"]) AM_CONDITIONAL([ENABLE_JACK], [test "x$enable_jack" = "xyes"]) AM_CONDITIONAL([ENABLE_PULSEAUDIO], [test "x$enable_pulseaudio" = "xyes"]) AM_CONDITIONAL([ENABLE_EMSCRIPTEN], [test "x$enable_emscripten" = "xyes"]) -AM_CONDITIONAL([ENABLE_PRESET_SUBDIRS], [test "x$enable_preset_subdirs" = "xyes"]) my_CFLAGS="-Wall -Wchar-subscripts -Wformat-security -Wpointer-arith -Wshadow -Wsign-compare -Wtype-limits" @@ -277,5 +268,4 @@ Jack: ${enable_jack} OpenGLES: ${enable_gles} Emscripten: ${enable_emscripten} llvm: ${enable_llvm} -Preset subdirs: ${enable_preset_subdirs} ]) diff --git a/msvc/projectM.vcxproj b/msvc/projectM.vcxproj index 8f1f0588b..4066f1e17 100644 --- a/msvc/projectM.vcxproj +++ b/msvc/projectM.vcxproj @@ -132,6 +132,7 @@ + CompileAsC @@ -166,4 +167,4 @@ - \ No newline at end of file + diff --git a/src/EyeTune/EyeTune.Shared/EyeTune.Shared.vcxitems b/src/EyeTune/EyeTune.Shared/EyeTune.Shared.vcxitems index 30992d65f..760e7d02c 100644 --- a/src/EyeTune/EyeTune.Shared/EyeTune.Shared.vcxitems +++ b/src/EyeTune/EyeTune.Shared/EyeTune.Shared.vcxitems @@ -36,6 +36,7 @@ + diff --git a/src/libprojectM/Common.hpp b/src/libprojectM/Common.hpp index 45e248a1a..fdca3951c 100755 --- a/src/libprojectM/Common.hpp +++ b/src/libprojectM/Common.hpp @@ -213,7 +213,7 @@ inline std::string parseExtension(const std::string & filename) { const std::size_t start = filename.find_last_of('.'); if (start == std::string::npos || start >= (filename.length()-1)) - return ""; + return {}; std::string ext = filename.substr(start+1, filename.length()); std::transform(ext.begin(), ext.end(), ext.begin(), tolower); return ext; diff --git a/src/libprojectM/FileScanner.cpp b/src/libprojectM/FileScanner.cpp new file mode 100644 index 000000000..92459ccba --- /dev/null +++ b/src/libprojectM/FileScanner.cpp @@ -0,0 +1,180 @@ +// +// FileScanner.cpp +// libprojectM +// +// + +#include "FileScanner.hpp" + +FileScanner::FileScanner() {} + +FileScanner::FileScanner(std::vector &rootDirs, std::vector &extensions) : _rootDirs(rootDirs), _extensions(extensions) {} + +void FileScanner::scan(ScanCallback cb) { +#ifdef WIN32 + for (auto dir : _rootDirs) + scanGeneric(cb, dir.c_str()); +#else + scanPosix(cb); +#endif +} + +void FileScanner::handleDirectoryError(std::string dir) { +#ifdef WIN32 + std::cerr << "[PresetLoader] warning: errno unsupported on win32 platforms. fix me" << std::endl; +#else + + std::cerr << dir << " scan error: "; + + switch ( errno ) + { + case ENOENT: + std::cerr << "ENOENT error. The path \"" << dir << "\" probably does not exist. \"man open\" for more info." << std::endl; + break; + case ENOMEM: + std::cerr << "out of memory!" << std::endl; + abort(); + case ENOTDIR: + std::cerr << "directory specified is not a directory! Trying to continue..." << std::endl; + break; + case ENFILE: + std::cerr << "Your system has reached its open file limit. Trying to continue..." << std::endl; + break; + case EMFILE: + std::cerr << "too many files in use by projectM! Bailing!" << std::endl; + break; + case EACCES: + std::cerr << "permissions issue reading the specified preset directory." << std::endl; + break; + default: + break; + } +#endif +} + +std::string FileScanner::extensionMatches(std::string &filename) { + // returns file name without extension + // TODO: optimize me + + std::string lowerCaseFileName(filename); + std::transform(lowerCaseFileName.begin(), lowerCaseFileName.end(), lowerCaseFileName.begin(), tolower); + + // Remove extension + for (auto ext : _extensions) + { + size_t found = lowerCaseFileName.find(ext); + if (found != std::string::npos) + { + std::string name = filename; + name.replace(int(found), ext.size(), ""); + return name; + } + } + + return {}; +} + + +// generic implementation using dirent +void FileScanner::scanGeneric(ScanCallback cb, const char *currentDir) { + DIR * m_dir; + + // Allocate a new a stream given the current directory name + if ((m_dir = opendir(currentDir)) == NULL) + { + return; // no files found in here + } + + struct dirent * dir_entry; + + while ((dir_entry = readdir(m_dir)) != NULL) + { + // Convert char * to friendly string + std::string filename(dir_entry->d_name); + + if (filename.length() > 0 && filename[0] == '.') + continue; + + std::string fullPath = std::string(currentDir) + PATH_SEPARATOR + filename; + + if (dir_entry->d_type == DT_DIR) { + // recurse into dir + scanGeneric(cb, fullPath.c_str()); + continue; + } else if (dir_entry->d_type != DT_REG && dir_entry->d_type != DT_LNK) { + // not regular file/link + continue; + } + + auto nameMatched = extensionMatches(filename); + if (! nameMatched.empty()) + cb(fullPath, nameMatched); + } + + if (m_dir) + { + closedir(m_dir); + m_dir = 0; + } +} + +#ifndef WIN32 +// more optimized posix "fts" directory traversal +int fts_compare(const FTSENT** one, const FTSENT** two) { + return (strcmp((*one)->fts_name, (*two)->fts_name)); +} +#endif + +void FileScanner::scanPosix(ScanCallback cb) { +#ifndef WIN32 + + // efficient directory traversal + FTS* fileSystem = NULL; + FTSENT *node = NULL; + + // list of directories to scan + auto rootDirCount = _rootDirs.size(); + char **dirList = (char **)malloc(sizeof(char*) * (rootDirCount + 1)); + for (unsigned long i = 0; i < rootDirCount; i++) { + dirList[i] = (char *) _rootDirs[i].c_str(); + } + dirList[rootDirCount] = NULL; + + // initialize file hierarchy traversal + fileSystem = fts_open(dirList, FTS_LOGICAL|FTS_NOCHDIR|FTS_NOSTAT, &fts_compare); + if (fileSystem == NULL) { + std::string s; + for (int i = 0; i < _rootDirs.size(); i++) + s += _rootDirs[i] + ' '; + handleDirectoryError(s); + + free(dirList); + return; + } + + std::string path, name, nameMatched; + + // traverse dirList + while( (node = fts_read(fileSystem)) != NULL) { + switch (node->fts_info) { + case FTS_F: + case FTS_SL: + case FTS_NSOK: + // found a file + path = std::string(node->fts_path); + name = std::string(node->fts_name); + + // check extension + nameMatched = extensionMatches(name); + if (! nameMatched.empty()) + cb(path, nameMatched); + break; + default: + break; + } + } + fts_close(fileSystem); + free(dirList); + +#endif +} diff --git a/src/libprojectM/FileScanner.hpp b/src/libprojectM/FileScanner.hpp new file mode 100644 index 000000000..6135ce751 --- /dev/null +++ b/src/libprojectM/FileScanner.hpp @@ -0,0 +1,60 @@ +// +// FileScanner.hpp +// libprojectM +// +// Cross-platform directory traversal with filtering by extension + +#ifndef FileScanner_hpp +#define FileScanner_hpp + +#include +#include +#include +#include +#include "Common.hpp" +#include + +#ifdef WIN32 +#include "dirent.h" +#else +#include +#endif + +#ifdef __unix__ +extern "C" +{ +#include +#include +} +#endif + +#ifdef __APPLE__ +extern "C" +{ +#include +#include +} +#endif + + +typedef std::function ScanCallback; + +class FileScanner { +public: + FileScanner(); + FileScanner(std::vector &rootDirs, std::vector &extensions); + + void scan(ScanCallback cb); + std::string extensionMatches(std::string &filename); + +private: + std::vector _rootDirs; + std::vector _extensions; + + void scanGeneric(ScanCallback cb, const char *dir); + void scanPosix(ScanCallback cb); + void handleDirectoryError(std::string dir); +}; + + +#endif /* FileScanner_hpp */ diff --git a/src/libprojectM/Makefile.am b/src/libprojectM/Makefile.am index a7799c8f0..5c084bc99 100644 --- a/src/libprojectM/Makefile.am +++ b/src/libprojectM/Makefile.am @@ -24,12 +24,12 @@ libprojectM_la_LIBADD = \ libprojectM_la_SOURCES = ConfigFile.cpp Preset.cpp PresetLoader.cpp timer.cpp \ KeyHandler.cpp PresetChooser.cpp TimeKeeper.cpp PCM.cpp PresetFactory.cpp \ fftsg.cpp wipemalloc.cpp PipelineMerger.cpp PresetFactoryManager.cpp projectM.cpp \ - TestRunner.cpp TestRunner.hpp \ + TestRunner.cpp TestRunner.hpp FileScanner.cpp FileScanner.hpp\ Common.hpp PipelineMerger.hpp PresetLoader.hpp\ HungarianMethod.hpp Preset.hpp RandomNumberGenerators.hpp\ IdleTextures.hpp PresetChooser.hpp TimeKeeper.hpp\ KeyHandler.hpp PresetFactory.hpp projectM.hpp\ - BackgroundWorker.h \ + BackgroundWorker.h \ PCM.hpp PresetFactoryManager.hpp\ projectM.hpp projectM-opengl.h \ ConfigFile.h \ diff --git a/src/libprojectM/MilkdropPresetFactory/InitCond.cpp b/src/libprojectM/MilkdropPresetFactory/InitCond.cpp index 051433ffe..1c0b3a727 100755 --- a/src/libprojectM/MilkdropPresetFactory/InitCond.cpp +++ b/src/libprojectM/MilkdropPresetFactory/InitCond.cpp @@ -71,7 +71,7 @@ void InitCond::evaluate(bool evalUser) /* WIP */ void InitCond::init_cond_to_string() { - int string_length; + unsigned long string_length; char string[MAX_TOKEN_SIZE]; /* Create a string "param_name=val" */ diff --git a/src/libprojectM/MilkdropPresetFactory/MilkdropPreset.cpp b/src/libprojectM/MilkdropPresetFactory/MilkdropPreset.cpp index 739183de5..e07636c7f 100755 --- a/src/libprojectM/MilkdropPresetFactory/MilkdropPreset.cpp +++ b/src/libprojectM/MilkdropPresetFactory/MilkdropPreset.cpp @@ -115,9 +115,7 @@ MilkdropPreset::~MilkdropPreset() int MilkdropPreset::add_per_pixel_eqn(char * name, Expr * gen_expr) { - PerPixelEqn * per_pixel_eqn = NULL; - int index; Param * param = NULL; assert(gen_expr); @@ -134,7 +132,7 @@ int MilkdropPreset::add_per_pixel_eqn(char * name, Expr * gen_expr) return PROJECTM_FAILURE; } - index = per_pixel_eqn_tree.size(); + auto index = per_pixel_eqn_tree.size(); /* Create the per pixel equation given the index, parameter, and general expression */ if ((per_pixel_eqn = new PerPixelEqn(index, param, gen_expr)) == NULL) @@ -143,8 +141,6 @@ int MilkdropPreset::add_per_pixel_eqn(char * name, Expr * gen_expr) return PROJECTM_FAILURE; } - - /* Insert the per pixel equation into the preset per pixel database */ std::pair::iterator, bool> inserteeOption = per_pixel_eqn_tree.insert (std::make_pair(per_pixel_eqn->index, per_pixel_eqn)); diff --git a/src/libprojectM/MilkdropPresetFactory/MilkdropPreset.hpp b/src/libprojectM/MilkdropPresetFactory/MilkdropPreset.hpp index c10fa43c3..c8fe7b795 100644 --- a/src/libprojectM/MilkdropPresetFactory/MilkdropPreset.hpp +++ b/src/libprojectM/MilkdropPresetFactory/MilkdropPreset.hpp @@ -61,16 +61,14 @@ public: /// Load a MilkdropPreset by filename with input and output buffers specified. /// \param absoluteFilePath the absolute file path of a MilkdropPreset to load from the file system - /// \param MilkdropPresetName a descriptive name for the MilkdropPreset. Usually just the file name - /// \param MilkdropPresetInputs a reference to read only projectM engine variables - /// \param MilkdropPresetOutputs initialized and filled with data parsed from a MilkdropPreset + /// \param milkdropPresetName a descriptive name for the MilkdropPreset. Usually just the file name + /// \param presetOutputs initialized and filled with data parsed from a MilkdropPreset MilkdropPreset(MilkdropPresetFactory *factory, const std::string & absoluteFilePath, const std::string & milkdropPresetName, PresetOutputs & presetOutputs); /// Load a MilkdropPreset from an input stream with input and output buffers specified. /// \param in an already initialized input stream to read the MilkdropPreset file from - /// \param MilkdropPresetName a descriptive name for the MilkdropPreset. Usually just the file name - /// \param MilkdropPresetInputs a reference to read only projectM engine variables - /// \param MilkdropPresetOutputs initialized and filled with data parsed from a MilkdropPreset + /// \param milkdropPresetName a descriptive name for the MilkdropPreset. Usually just the file name + /// \param presetOutputs initialized and filled with data parsed from a MilkdropPreset MilkdropPreset(MilkdropPresetFactory *factory, std::istream & in, const std::string & milkdropPresetName, PresetOutputs & presetOutputs); ~MilkdropPreset(); @@ -110,13 +108,11 @@ public: /// \returns A MilkdropPreset output instance with values computed from most recent evaluateFrame() PresetOutputs & presetOutputs() const { - return _presetOutputs; } const PresetInputs & presetInputs() const { - return _presetInputs; } diff --git a/src/libprojectM/MilkdropPresetFactory/MilkdropPresetFactory.cpp b/src/libprojectM/MilkdropPresetFactory/MilkdropPresetFactory.cpp index ad966948e..863a61e43 100644 --- a/src/libprojectM/MilkdropPresetFactory/MilkdropPresetFactory.cpp +++ b/src/libprojectM/MilkdropPresetFactory/MilkdropPresetFactory.cpp @@ -188,8 +188,7 @@ PresetOutputs* MilkdropPresetFactory::createPresetOutputs(int gx, int gy) presetOutputs->bSolarize = 0; presetOutputs->bInvert = 0; presetOutputs->bMotionVectorsOn = 1; - - presetOutputs->fWarpAnimSpeed = 0; + presetOutputs->fWarpAnimSpeed = 0; presetOutputs->fWarpScale = 0; presetOutputs->fShader = 0; diff --git a/src/libprojectM/MilkdropPresetFactory/MilkdropPresetFactory.hpp b/src/libprojectM/MilkdropPresetFactory/MilkdropPresetFactory.hpp index 76802b170..b63adec9e 100644 --- a/src/libprojectM/MilkdropPresetFactory/MilkdropPresetFactory.hpp +++ b/src/libprojectM/MilkdropPresetFactory/MilkdropPresetFactory.hpp @@ -21,18 +21,16 @@ class DLLEXPORT PresetInputs; class MilkdropPresetFactory : public PresetFactory { public: - MilkdropPresetFactory(int gx, int gy); virtual ~MilkdropPresetFactory(); + // called by ~MilkdropPreset + void releasePreset(Preset *preset); std::unique_ptr allocate(const std::string & url, const std::string & name = std::string(), const std::string & author = std::string()); - std::string supportedExtensions() const { return "milk prjm"; } - - // called by ~MilkdropPreset - void releasePreset(Preset *preset); + std::string supportedExtensions() const { return ".milk .prjm"; } private: static PresetOutputs* createPresetOutputs(int gx, int gy); @@ -40,7 +38,6 @@ private: int gx; int gy; PresetOutputs * _presetOutputsCache; - //PresetInputs _presetInputs; }; #endif diff --git a/src/libprojectM/MilkdropPresetFactory/PerPixelEqn.cpp b/src/libprojectM/MilkdropPresetFactory/PerPixelEqn.cpp index 47d44cf27..bb409371b 100755 --- a/src/libprojectM/MilkdropPresetFactory/PerPixelEqn.cpp +++ b/src/libprojectM/MilkdropPresetFactory/PerPixelEqn.cpp @@ -42,7 +42,7 @@ void PerPixelEqn::evaluate(int mesh_i, int mesh_j) assign_expr->eval( mesh_i, mesh_j ); } -PerPixelEqn::PerPixelEqn(int _index, Param * param, Expr * gen_expr):index(_index) +PerPixelEqn::PerPixelEqn(unsigned long _index, Param * param, Expr * gen_expr):index(_index) { assert(index >= 0); assert(param != 0); diff --git a/src/libprojectM/MilkdropPresetFactory/PerPixelEqn.hpp b/src/libprojectM/MilkdropPresetFactory/PerPixelEqn.hpp index 06e72dadc..3db2015cf 100755 --- a/src/libprojectM/MilkdropPresetFactory/PerPixelEqn.hpp +++ b/src/libprojectM/MilkdropPresetFactory/PerPixelEqn.hpp @@ -56,7 +56,7 @@ public: void evaluate(int mesh_i, int mesh_j); virtual ~PerPixelEqn(); - PerPixelEqn(int index, Param * param, Expr * gen_expr); + PerPixelEqn(unsigned long index, Param * param, Expr * gen_expr); Expr *assign_expr; }; diff --git a/src/libprojectM/NativePresetFactory/NativePresetFactory.hpp b/src/libprojectM/NativePresetFactory/NativePresetFactory.hpp index 591f9bec0..daba75bb0 100644 --- a/src/libprojectM/NativePresetFactory/NativePresetFactory.hpp +++ b/src/libprojectM/NativePresetFactory/NativePresetFactory.hpp @@ -29,7 +29,7 @@ public: virtual std::unique_ptr allocate(const std::string & url, const std::string & name = std::string(), const std::string & author = std::string()); - virtual std::string supportedExtensions() const { return "so dylib"; } + virtual std::string supportedExtensions() const { return ".so .dylib"; } private: PresetLibrary * loadLibrary(const std::string & url); diff --git a/src/libprojectM/PresetFactoryManager.cpp b/src/libprojectM/PresetFactoryManager.cpp index c8baa2967..aac38ccbd 100644 --- a/src/libprojectM/PresetFactoryManager.cpp +++ b/src/libprojectM/PresetFactoryManager.cpp @@ -81,7 +81,7 @@ void PresetFactoryManager::registerFactory(const std::string & extensions, Prese std::unique_ptr PresetFactoryManager::allocate(const std::string & url, const std::string & name) { try { - const std::string extension = parseExtension (url); + const std::string extension = "." + parseExtension(url); return factory(extension).allocate(url, name); } catch (const PresetFactoryException & e) { @@ -98,7 +98,7 @@ PresetFactory & PresetFactoryManager::factory(const std::string & extension) { if (!extensionHandled(extension)) { std::ostringstream os; - os << "No preset factory associated with \"" << extension << "\"." << std::endl; + os << "No preset factory associated with \"" << extension << "\"." << std::endl; throw PresetFactoryException(os.str()); } return *_factoryMap[extension]; @@ -107,3 +107,11 @@ PresetFactory & PresetFactoryManager::factory(const std::string & extension) { bool PresetFactoryManager::extensionHandled(const std::string & extension) const { return _factoryMap.count(extension); } + +std::vector PresetFactoryManager::extensionsHandled() const { + std::vector retval; + for (auto const& element : _factoryMap) { + retval.push_back(element.first); + } + return retval; +} diff --git a/src/libprojectM/PresetFactoryManager.hpp b/src/libprojectM/PresetFactoryManager.hpp index 7a9867acb..05f9e716f 100644 --- a/src/libprojectM/PresetFactoryManager.hpp +++ b/src/libprojectM/PresetFactoryManager.hpp @@ -49,6 +49,8 @@ class PresetFactoryManager { /// \returns true if a factory exists, false otherwise bool extensionHandled(const std::string & extension) const; std::unique_ptr allocate(const std::string & url, const std::string & name); + std::vector extensionsHandled() const; + private: int _gx, _gy; diff --git a/src/libprojectM/PresetLoader.cpp b/src/libprojectM/PresetLoader.cpp index a685d22cb..2b4ef100f 100644 --- a/src/libprojectM/PresetLoader.cpp +++ b/src/libprojectM/PresetLoader.cpp @@ -15,29 +15,19 @@ #include #include #include - -#ifdef __unix__ -extern "C" -{ -#include -} -#endif - -#ifdef __APPLE__ -extern "C" -{ -#include -} -#endif - +#include #include #include "fatal.h" - #include "Common.hpp" -PresetLoader::PresetLoader (int gx, int gy, std::string dirname = std::string()) :_dirname ( dirname ), _dir ( 0 ) +PresetLoader::PresetLoader (int gx, int gy, std::string dirname = std::string()) :_dirname ( dirname ) { - _presetFactoryManager.initialize(gx,gy); + _presetFactoryManager.initialize(gx,gy); + + std::vector dirs{_dirname}; + std::vector extensions = _presetFactoryManager.extensionsHandled(); + fileScanner = FileScanner(dirs, extensions); + // Do one scan if ( _dirname != std::string() ) rescan(); @@ -45,106 +35,59 @@ PresetLoader::PresetLoader (int gx, int gy, std::string dirname = std::string()) clear(); } -PresetLoader::~PresetLoader() -{ - if ( _dir ) - closedir ( _dir ); -} +PresetLoader::~PresetLoader() {} void PresetLoader::setScanDirectory ( std::string dirname ) { _dirname = dirname; } +void PresetLoader::addScannedPresetFile(const std::string &path, const std::string &name) { + auto ext = parseExtension(path); + if (ext.empty()) + return; + + ext = "." + ext; + + // Verify extension is projectm or milkdrop + if (!_presetFactoryManager.extensionHandled(ext)) + return; + +// std::cout << "Loading preset file " << path << std::endl; + + _entries.push_back(path); + _presetNames.push_back(name + ext); +} void PresetLoader::rescan() { // std::cerr << "Rescanning..." << std::endl; + + // Clear the directory entry collection + clear(); - // Clear the directory entry collection - clear(); - - // If directory already opened, close it first - if ( _dir ) - { - closedir ( _dir ); - _dir = 0; - } - - // Allocate a new a stream given the current directory name - if ( ( _dir = opendir ( _dirname.c_str() ) ) == NULL ) - { - handleDirectoryError(); - return; // no files loaded. _entries is empty - } - - struct dirent * dir_entry; - std::set alphaSortedFileSet; - std::set alphaSortedPresetNameSet; - - while ( ( dir_entry = readdir ( _dir ) ) != NULL ) - { - if (dir_entry->d_name[0] == 0) - continue; - - std::ostringstream out; - // Convert char * to friendly string - std::string filename ( dir_entry->d_name ); - - // Verify extension is projectm or milkdrop - if (!_presetFactoryManager.extensionHandled(parseExtension(filename))) - continue; - - if ( filename.length() > 0 && filename[0] == '.' ) - continue; - - // Create full path name - out << _dirname << PATH_SEPARATOR << filename; - - // Add to our directory entry collection - alphaSortedFileSet.insert ( out.str() ); - alphaSortedPresetNameSet.insert ( filename ); - - // the directory entry struct is freed elsewhere - } - - // Push all entries in order from the file set to the file entries member (which is an indexed vector) - for ( std::set::iterator pos = alphaSortedFileSet.begin(); - pos != alphaSortedFileSet.end();++pos ) - _entries.push_back ( *pos ); - - // Push all preset names in similar fashion - for ( std::set::iterator pos = alphaSortedPresetNameSet.begin(); - pos != alphaSortedPresetNameSet.end();++pos ) - _presetNames.push_back ( *pos ); - - // Give all presets equal rating of 3 - why 3? I don't know - _ratings = std::vector(TOTAL_RATING_TYPES, RatingList( _presetNames.size(), 3 )); - _ratingsSums = std::vector(TOTAL_RATING_TYPES, 3 * _presetNames.size()); - - - assert ( _entries.size() == _presetNames.size() ); - + // scan for presets + using namespace std::placeholders; + fileScanner.scan(std::bind(&PresetLoader::addScannedPresetFile, this, _1, _2)); + // Give all presets equal rating of 3 - why 3? I don't know + _ratings = std::vector(TOTAL_RATING_TYPES, RatingList( _presetNames.size(), 3 )); + _ratingsSums = std::vector(TOTAL_RATING_TYPES, 3 *_presetNames.size()); + assert ( _entries.size() == _presetNames.size() ); } - -std::unique_ptr PresetLoader::loadPreset ( unsigned int index ) const +std::unique_ptr PresetLoader::loadPreset ( PresetIndex index ) const { - // Check that index isn't insane assert ( index < _entries.size() ); return _presetFactoryManager.allocate ( _entries[index], _presetNames[index] ); - } - std::unique_ptr PresetLoader::loadPreset ( const std::string & url ) const { // std::cout << "Loading preset " << url << std::endl; - try { /// @bug probably should not use url for preset name return _presetFactoryManager.allocate @@ -157,40 +100,7 @@ std::unique_ptr PresetLoader::loadPreset ( const std::string & url ) co return std::unique_ptr(); } -void PresetLoader::handleDirectoryError() -{ - -#ifdef WIN32 - std::cerr << "[PresetLoader] warning: errno unsupported on win32 platforms. fix me" << std::endl; -#else - - switch ( errno ) - { - case ENOENT: - std::cerr << "[PresetLoader] ENOENT error. The path \"" << this->_dirname << "\" probably does not exist. \"man open\" for more info." << std::endl; - break; - case ENOMEM: - std::cerr << "[PresetLoader] out of memory! Are you running Windows?" << std::endl; - abort(); - case ENOTDIR: - std::cerr << "[PresetLoader] directory specified is not a preset directory! Trying to continue..." << std::endl; - break; - case ENFILE: - std::cerr << "[PresetLoader] Your system has reached its open file limit. Trying to continue..." << std::endl; - break; - case EMFILE: - std::cerr << "[PresetLoader] too many files in use by projectM! Bailing!" << std::endl; - break; - case EACCES: - std::cerr << "[PresetLoader] permissions issue reading the specified preset directory." << std::endl; - break; - default: - break; - } -#endif -} - -void PresetLoader::setRating(unsigned int index, int rating, const PresetRatingType ratingType) +void PresetLoader::setRating(PresetIndex index, int rating, const PresetRatingType ratingType) { const unsigned int ratingTypeIndex = static_cast(ratingType); assert (index < _ratings[ratingTypeIndex].size()); @@ -199,11 +109,9 @@ void PresetLoader::setRating(unsigned int index, int rating, const PresetRatingT _ratings[ratingTypeIndex][index] = rating; _ratingsSums[ratingType] += rating; - } - -unsigned int PresetLoader::addPresetURL ( const std::string & url, const std::string & presetName, const std::vector & ratings) +unsigned long PresetLoader::addPresetURL ( const std::string & url, const std::string & presetName, const std::vector & ratings) { _entries.push_back(url); _presetNames.push_back ( presetName ); @@ -220,9 +128,8 @@ unsigned int PresetLoader::addPresetURL ( const std::string & url, const std::st return _entries.size()-1; } -void PresetLoader::removePreset ( unsigned int index ) +void PresetLoader::removePreset ( PresetIndex index ) { - _entries.erase ( _entries.begin() + index ); _presetNames.erase ( _presetNames.begin() + index ); @@ -230,21 +137,19 @@ void PresetLoader::removePreset ( unsigned int index ) _ratingsSums[i] -= _ratings[i][index]; _ratings[i].erase ( _ratings[i].begin() + index ); } - - } -const std::string & PresetLoader::getPresetURL ( unsigned int index ) const +const std::string & PresetLoader::getPresetURL ( PresetIndex index ) const { return _entries[index]; } -const std::string & PresetLoader::getPresetName ( unsigned int index ) const +const std::string & PresetLoader::getPresetName ( PresetIndex index ) const { return _presetNames[index]; } -int PresetLoader::getPresetRating ( unsigned int index, const PresetRatingType ratingType ) const +int PresetLoader::getPresetRating ( PresetIndex index, const PresetRatingType ratingType ) const { return _ratings[ratingType][index]; } @@ -258,23 +163,19 @@ const std::vector & PresetLoader::getPresetRatingsSums() const { return _ratingsSums; } -void PresetLoader::setPresetName(unsigned int index, std::string name) { +void PresetLoader::setPresetName(PresetIndex index, std::string name) { _presetNames[index] = name; } -void PresetLoader::insertPresetURL ( unsigned int index, const std::string & url, const std::string & presetName, const RatingList & ratings) +void PresetLoader::insertPresetURL ( PresetIndex index, const std::string & url, const std::string & presetName, const RatingList & ratings) { _entries.insert ( _entries.begin() + index, url ); _presetNames.insert ( _presetNames.begin() + index, presetName ); - - for (unsigned int i = 0; i < _ratingsSums.size();i++) { _ratingsSums[i] += _ratings[i][index]; _ratings[i].insert ( _ratings[i].begin() + index, ratings[i] ); } assert ( _entries.size() == _presetNames.size() ); - - } diff --git a/src/libprojectM/PresetLoader.hpp b/src/libprojectM/PresetLoader.hpp index b6ca27829..df314387c 100644 --- a/src/libprojectM/PresetLoader.hpp +++ b/src/libprojectM/PresetLoader.hpp @@ -5,34 +5,18 @@ #include // for auto pointers #include -#ifdef WIN32 -#include "dirent.h" -#endif - -#ifdef __unix__ -#include -#endif - -#ifdef EMSCRIPTEN -#include -#endif - -#ifdef __APPLE__ -#include -#endif - #include #include #include "PresetFactoryManager.hpp" +#include "FileScanner.hpp" class Preset; class PresetFactory; +typedef std::size_t PresetIndex; class PresetLoader { public: - - /// Initializes the preset loader with the target directory specified PresetLoader(int gx, int gy, std::string dirname); @@ -40,21 +24,21 @@ class PresetLoader { /// Load a preset by specifying its unique identifier given when the preset url /// was added to this loader - std::unique_ptr loadPreset(unsigned int index) const; + std::unique_ptr loadPreset(PresetIndex index) const; std::unique_ptr loadPreset ( const std::string & url ) const; /// Add a preset to the loader's collection. /// \param url an url referencing the preset /// \param presetName a name for the preset - /// \param rating an integer representing the goodness of the preset + /// \param ratings an list representing the goodness ratings /// \returns The unique index assigned to the preset in the collection. Used with loadPreset - unsigned int addPresetURL ( const std::string & url, const std::string & presetName, const RatingList & ratings); + unsigned long addPresetURL(const std::string & url, const std::string & presetName, const RatingList & ratings); /// Add a preset to the loader's collection. /// \param index insertion index /// \param url an url referencing the preset /// \param presetName a name for the preset - /// \param rating an integer representing the goodness of the preset - void insertPresetURL (unsigned int index, const std::string & url, const std::string & presetName, const RatingList & ratings); + /// \param ratings an list representing the goodness ratings + void insertPresetURL (PresetIndex index, const std::string & url, const std::string & presetName, const RatingList & ratings); /// Clears all presets from the collection inline void clear() { @@ -72,19 +56,19 @@ class PresetLoader { /// Removes a preset from the loader /// \param index the unique identifier of the preset url to be removed - void removePreset(unsigned int index); + void removePreset(PresetIndex index); /// Sets the rating of a preset to a new value - void setRating(unsigned int index, int rating, const PresetRatingType ratingType); + void setRating(PresetIndex index, int rating, const PresetRatingType ratingType); /// Get a preset rating given an index - int getPresetRating ( unsigned int index, const PresetRatingType ratingType) const; + int getPresetRating ( PresetIndex index, const PresetRatingType ratingType) const; /// Get a preset url given an index - const std::string & getPresetURL ( unsigned int index) const; + const std::string & getPresetURL ( PresetIndex index) const; /// Get a preset name given an index - const std::string & getPresetName ( unsigned int index) const; + const std::string & getPresetName ( PresetIndex index) const; /// Returns the number of presets in the active directory inline std::size_t size() const { @@ -101,11 +85,12 @@ class PresetLoader { /// Rescans the active preset directory void rescan(); - void setPresetName(unsigned int index, std::string name); - private: - void handleDirectoryError(); + void setPresetName(PresetIndex index, std::string name); + + protected: + void addScannedPresetFile(const std::string &path, const std::string &name); + std::string _dirname; - DIR * _dir; std::vector _ratingsSums; mutable PresetFactoryManager _presetFactoryManager; @@ -115,8 +100,8 @@ class PresetLoader { // Indexed by ratingType, preset position. std::vector _ratings; - - + + FileScanner fileScanner; }; #endif diff --git a/src/libprojectM/Renderer/TextureManager.cpp b/src/libprojectM/Renderer/TextureManager.cpp index 9f4ab41f9..42bd1077f 100644 --- a/src/libprojectM/Renderer/TextureManager.cpp +++ b/src/libprojectM/Renderer/TextureManager.cpp @@ -1,29 +1,13 @@ #include #include #include - #include "projectM-opengl.h" - #include "SOIL2/SOIL2.h" - -#ifdef WIN32 -#include "dirent.h" -#endif - -#ifdef __unix__ -#include -#endif -#ifdef EMSCRIPTEN -#include -#endif - -#ifdef __APPLE__ -#include -#endif #include "TextureManager.hpp" #include "Common.hpp" #include "IdleTextures.hpp" #include "Texture.hpp" + /* OpenGL ES 2.0 cant handle converting textures fro GL_RGB to GL_RGBA via glTexImage2D http://docs.gl/es2/glTexImage2D @@ -44,8 +28,8 @@ So because of this, we switch to a PerlinNoiseWithAlpha class to generate the no TextureManager::TextureManager(const std::string _presetsURL, const int texsizeX, const int texsizeY, std::string datadir): - presetsURL(_presetsURL) -{ + presetsURL(_presetsURL) { + extensions.push_back(".jpg"); extensions.push_back(".dds"); extensions.push_back(".png"); @@ -53,6 +37,13 @@ TextureManager::TextureManager(const std::string _presetsURL, const int texsizeX extensions.push_back(".bmp"); extensions.push_back(".dib"); + std::vector dirsToScan{datadir + "/presets", datadir + "/textures", _presetsURL}; + FileScanner fileScanner = FileScanner(dirsToScan, extensions); + + // scan for textures + using namespace std::placeholders; + fileScanner.scan(std::bind(&TextureManager::loadTexture, this, _1, _2)); + Preload(); // if not data directory specified from user code // we use the built-in default directory (unix prefix based) @@ -63,10 +54,6 @@ TextureManager::TextureManager(const std::string _presetsURL, const int texsizeX datadir = DATADIR_PATH; #endif /** WIN32 */ - loadTextureDir(datadir + "/presets"); - loadTextureDir(datadir + "/textures"); - loadTextureDir(_presetsURL); - // Create main texture ans associated samplers mainTexture = new Texture("main", texsizeX, texsizeY, false); mainTexture->getSampler(GL_REPEAT, GL_LINEAR); @@ -233,12 +220,12 @@ TextureSamplerDesc TextureManager::getTexture(const std::string fullName, const // Remove extension std::string lowerCaseFileName(fullName); std::transform(lowerCaseFileName.begin(), lowerCaseFileName.end(), lowerCaseFileName.begin(), tolower); - for (size_t x = 0; x < extensions.size(); x++) + for (auto ext : extensions) { - size_t found = lowerCaseFileName.find(extensions[x]); + size_t found = lowerCaseFileName.find(ext); if (found != std::string::npos) { - fileName.replace(int(found), extensions[x].size(), ""); + fileName.replace(int(found), ext.size(), ""); break; } } @@ -272,25 +259,29 @@ TextureSamplerDesc TextureManager::tryLoadingTexture(const std::string name) ExtractTextureSettings(name, wrap_mode, filter_mode, unqualifiedName); - for (size_t x = 0; x < extensions.size(); x++) + for (auto ext : extensions) { - std::string filename = unqualifiedName + extensions[x]; + std::string filename = unqualifiedName + ext; std::string fullURL = presetsURL + PATH_SEPARATOR + filename; - texDesc = loadTexture(name, fullURL); + texDesc = loadTexture(fullURL, name); if (texDesc.first != NULL) { + std::cerr << "Located texture " << name << std::endl; break; } } + + std::cerr << "Failed to locate texture " << name << std::endl; return texDesc; } -TextureSamplerDesc TextureManager::loadTexture(const std::string name, const std::string fileName) +TextureSamplerDesc TextureManager::loadTexture(const std::string fileName, const std::string name) { int width, height; +// std::cout << "Loading texture " << name << " at " << fileName << std::endl; unsigned int tex = SOIL_load_OGL_texture( fileName.c_str(), @@ -313,64 +304,16 @@ TextureSamplerDesc TextureManager::loadTexture(const std::string name, const std Sampler * sampler = newTexture->getSampler(wrap_mode, filter_mode); if (textures.find(name) != textures.end()) { + // found duplicate.. this could be optimized delete textures[name]; } textures[name] = newTexture; +// std::cout << "Loaded texture " << name << std::endl; return TextureSamplerDesc(newTexture, sampler); } - -void TextureManager::loadTextureDir(const std::string &dirname) -{ - DIR * m_dir; - - // Allocate a new a stream given the current directory name - if ((m_dir = opendir(dirname.c_str())) == NULL) - { -// std::cout<<"No Textures Loaded from "<d_name); - - if (filename.length() > 0 && filename[0] == '.') - continue; - - std::string lowerCaseFileName(filename); - std::transform(lowerCaseFileName.begin(), lowerCaseFileName.end(), lowerCaseFileName.begin(), tolower); - - // Remove extension - for (size_t x = 0; x < extensions.size(); x++) - { - size_t found = lowerCaseFileName.find(extensions[x]); - if (found != std::string::npos) - { - std::string name = filename; - name.replace(int(found), extensions[x].size(), ""); - - // Create full path name - std::string fullname = dirname + PATH_SEPARATOR + filename; - loadTexture(name, fullname); - - break; - } - } - } - - if (m_dir) - { - closedir(m_dir); - m_dir = 0; - } -} - TextureSamplerDesc TextureManager::getRandomTextureName(std::string random_id) { GLint wrap_mode; diff --git a/src/libprojectM/Renderer/TextureManager.hpp b/src/libprojectM/Renderer/TextureManager.hpp index 10b68e676..55809433c 100644 --- a/src/libprojectM/Renderer/TextureManager.hpp +++ b/src/libprojectM/Renderer/TextureManager.hpp @@ -7,6 +7,7 @@ #include #include "projectM-opengl.h" #include "Texture.hpp" +#include "FileScanner.hpp" class TextureManager @@ -17,7 +18,6 @@ class TextureManager Texture * mainTexture; std::vector random_textures; - void loadTextureDir(const std::string & dirname); TextureSamplerDesc loadTexture(const std::string name, const std::string imageUrl); void ExtractTextureSettings(const std::string qualifiedName, GLint &_wrap_mode, GLint &_filter_mode, std::string & name); std::vector extensions; diff --git a/src/libprojectM/Renderer/Waveform.cpp b/src/libprojectM/Renderer/Waveform.cpp index 15154557b..219cef83b 100644 --- a/src/libprojectM/Renderer/Waveform.cpp +++ b/src/libprojectM/Renderer/Waveform.cpp @@ -57,8 +57,8 @@ void Waveform::Draw(RenderContext &context) std::transform(&value1[0], &value1[samples], &value1[0], bind2nd(std::multiplies(), mult)); std::transform(&value2[0], &value2[samples], &value2[0], bind2nd(std::multiplies(), mult)); #else - std::transform(&value1[0], &value1[samples], &value1[0], std::bind2nd(std::multiplies(), mult)); - std::transform(&value2[0], &value2[samples], &value2[0], std::bind2nd(std::multiplies(), mult)); + std::transform(&value1[0], &value1[samples], &value1[0], std::bind(std::multiplies(), std::placeholders::_1, mult)); + std::transform(&value2[0], &value2[samples], &value2[0], std::bind(std::multiplies(), std::placeholders::_1, mult)); #endif /** WIN32 */ WaveformContext waveContext(samples, context.beatDetect); diff --git a/src/libprojectM/libprojectM.xcodeproj/project.pbxproj b/src/libprojectM/libprojectM.xcodeproj/project.pbxproj index 19d44ad93..819d4440b 100644 --- a/src/libprojectM/libprojectM.xcodeproj/project.pbxproj +++ b/src/libprojectM/libprojectM.xcodeproj/project.pbxproj @@ -128,6 +128,10 @@ 1687174A20C33DF400947E7E /* Pipeline.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 1687173520C33DF400947E7E /* Pipeline.hpp */; }; 1687174B20C33DF400947E7E /* ShaderEngine.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 1687173620C33DF400947E7E /* ShaderEngine.hpp */; }; 1687174E20C33E1000947E7E /* RenderContext.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 1687174D20C33E1000947E7E /* RenderContext.hpp */; }; + 169BC64724CC4D16007B7829 /* FileScanner.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 169BC64524CC4D16007B7829 /* FileScanner.cpp */; }; + 169BC64824CC4D16007B7829 /* FileScanner.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 169BC64524CC4D16007B7829 /* FileScanner.cpp */; }; + 169BC64924CC4D16007B7829 /* FileScanner.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 169BC64624CC4D16007B7829 /* FileScanner.hpp */; }; + 169BC64A24CC4D16007B7829 /* FileScanner.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 169BC64624CC4D16007B7829 /* FileScanner.hpp */; }; 16A49E5E207A7CAE00E508EA /* ConfigFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 16178ABD207A68A500D3B0C8 /* ConfigFile.cpp */; }; 16A49E62207A7CAE00E508EA /* fftsg.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 16178AB5207A68A400D3B0C8 /* fftsg.cpp */; }; 16A49E69207A7CAE00E508EA /* PCM.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 16178AC1207A68A600D3B0C8 /* PCM.cpp */; }; @@ -264,6 +268,8 @@ 168C689320BB1FE0000AFC1B /* HLSLTree.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = HLSLTree.cpp; path = Renderer/hlslparser/src/HLSLTree.cpp; sourceTree = ""; }; 168C689420BB1FE0000AFC1B /* HLSLTokenizer.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = HLSLTokenizer.cpp; path = Renderer/hlslparser/src/HLSLTokenizer.cpp; sourceTree = ""; }; 168C689520BB1FE0000AFC1B /* CodeWriter.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = CodeWriter.cpp; path = Renderer/hlslparser/src/CodeWriter.cpp; sourceTree = ""; }; + 169BC64524CC4D16007B7829 /* FileScanner.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = FileScanner.cpp; sourceTree = ""; }; + 169BC64624CC4D16007B7829 /* FileScanner.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = FileScanner.hpp; sourceTree = ""; }; 16A49E57207A7C8C00E508EA /* libprojectM.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libprojectM.a; sourceTree = BUILT_PRODUCTS_DIR; }; /* End PBXFileReference section */ @@ -417,6 +423,8 @@ 16178AB8207A68A500D3B0C8 /* TimeKeeper.cpp */, 16178AB6207A68A400D3B0C8 /* timer.cpp */, 16178ABC207A68A500D3B0C8 /* wipemalloc.cpp */, + 169BC64524CC4D16007B7829 /* FileScanner.cpp */, + 169BC64624CC4D16007B7829 /* FileScanner.hpp */, ); name = libProjectM; sourceTree = ""; @@ -558,6 +566,7 @@ 1687174E20C33E1000947E7E /* RenderContext.hpp in Headers */, 1687174B20C33DF400947E7E /* ShaderEngine.hpp in Headers */, 1687173C20C33DF400947E7E /* RenderItemMatcher.hpp in Headers */, + 169BC64924CC4D16007B7829 /* FileScanner.hpp in Headers */, 1687174A20C33DF400947E7E /* Pipeline.hpp in Headers */, 1687174120C33DF400947E7E /* Renderer.hpp in Headers */, 1687173920C33DF400947E7E /* Renderable.hpp in Headers */, @@ -585,6 +594,7 @@ 1612CA0F207A878900862A3A /* resource.h in Headers */, 1612CA00207A878900862A3A /* cocoatoprojectM.h in Headers */, 1612CA07207A878900862A3A /* wipemalloc.h in Headers */, + 169BC64A24CC4D16007B7829 /* FileScanner.hpp in Headers */, 1612CA06207A878900862A3A /* sdltoprojectM.h in Headers */, 1612CA09207A878900862A3A /* fftsg.h in Headers */, 1612CA0E207A878900862A3A /* projectM-opengl.h in Headers */, @@ -756,6 +766,7 @@ 166854482105E4FC0042793A /* Filters.hpp in Sources */, 1668544B2105E4FC0042793A /* PerlinNoise.hpp in Sources */, 1668544C2105E4FC0042793A /* PerPixelMesh.hpp in Sources */, + 169BC64724CC4D16007B7829 /* FileScanner.cpp in Sources */, 1668544D2105E4FC0042793A /* Pipeline.hpp in Sources */, 1668544E2105E4FC0042793A /* PipelineContext.hpp in Sources */, 1668544F2105E4FC0042793A /* Renderable.hpp in Sources */, @@ -803,6 +814,7 @@ buildActionMask = 2147483647; files = ( 16A49E5E207A7CAE00E508EA /* ConfigFile.cpp in Sources */, + 169BC64824CC4D16007B7829 /* FileScanner.cpp in Sources */, 16A49E62207A7CAE00E508EA /* fftsg.cpp in Sources */, 16A49E69207A7CAE00E508EA /* PCM.cpp in Sources */, 1612C9EC207A860000862A3A /* KeyHandler.cpp in Sources */, @@ -911,7 +923,7 @@ GCC_C_LANGUAGE_STANDARD = gnu11; GCC_DYNAMIC_NO_PIC = NO; GCC_NO_COMMON_BLOCKS = YES; - GCC_OPTIMIZATION_LEVEL = 1; + GCC_OPTIMIZATION_LEVEL = 0; GCC_PREPROCESSOR_DEFINITIONS = ( "DEBUG=1", "GL_SILENCE_DEPRECATION=1", diff --git a/src/libprojectM/omptl/omptl_algorithm_ser.h b/src/libprojectM/omptl/omptl_algorithm_ser.h index 61c596690..c4897cf8f 100644 --- a/src/libprojectM/omptl/omptl_algorithm_ser.h +++ b/src/libprojectM/omptl/omptl_algorithm_ser.h @@ -463,14 +463,14 @@ template void random_shuffle(RandomAccessIterator first, RandomAccessIterator last, const unsigned P) { - return ::std::random_shuffle(first, last); + return random_shuffle(first, last); } template void random_shuffle(RandomAccessIterator first, RandomAccessIterator last, RandomNumberGenerator &rgen, const unsigned P) { - return ::std::random_shuffle(first, last, rgen); + return random_shuffle(first, last, rgen); } template diff --git a/src/projectM-iTunes/iTunes Plugin.xcodeproj/project.pbxproj b/src/projectM-iTunes/iTunes Plugin.xcodeproj/project.pbxproj index c50549674..de3714d9a 100644 --- a/src/projectM-iTunes/iTunes Plugin.xcodeproj/project.pbxproj +++ b/src/projectM-iTunes/iTunes Plugin.xcodeproj/project.pbxproj @@ -121,7 +121,7 @@ C37EBD3D19A0112900220265 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/MainMenu.xib; sourceTree = ""; }; C37EBD3F19A0112900220265 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; C37EBD4619A0112900220265 /* XCTest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = XCTest.framework; path = Library/Frameworks/XCTest.framework; sourceTree = DEVELOPER_DIR; }; - C37EBD5A19A0118600220265 /* iTunes Visualizer.pkg */ = {isa = PBXFileReference; lastKnownFileType = file; path = "iTunes Visualizer.pkg"; sourceTree = ""; }; + C37EBD5A19A0118600220265 /* iTunes Visualizer.pkg */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.installer-pkg"; path = "iTunes Visualizer.pkg"; sourceTree = ""; }; C37EBD5C19A0146F00220265 /* images */ = {isa = PBXFileReference; lastKnownFileType = folder; name = images; path = ../images; sourceTree = ""; }; C37EBD5E19A0164400220265 /* selectViz.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = selectViz.png; path = images/selectViz.png; sourceTree = ""; }; C37EBD6019A01BEE00220265 /* projectM Visualizer.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = "projectM Visualizer.entitlements"; sourceTree = ""; }; @@ -640,7 +640,7 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_CXX_LANGUAGE_STANDARD = "compiler-default"; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++17"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = NO; CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; @@ -697,7 +697,7 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_CXX_LANGUAGE_STANDARD = "compiler-default"; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++17"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = NO; CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; diff --git a/src/projectM-sdl/SDLprojectM.xcodeproj/project.pbxproj b/src/projectM-sdl/SDLprojectM.xcodeproj/project.pbxproj index 088ec74c3..be025a935 100644 --- a/src/projectM-sdl/SDLprojectM.xcodeproj/project.pbxproj +++ b/src/projectM-sdl/SDLprojectM.xcodeproj/project.pbxproj @@ -117,6 +117,7 @@ files = ( 168F715921124C0E001806E7 /* config.inp in Support files */, 168F715A21124C14001806E7 /* fonts in Support files */, + 169BC64224CC3FCA007B7829 /* presets in Support files */, ); name = "Support files"; runOnlyForDeploymentPostprocessing = 0; @@ -294,7 +295,6 @@ 168F714621120210001806E7 /* Frameworks */, 168F714721120210001806E7 /* Resources */, 168F7155211248DE001806E7 /* Executable */, - 168F715721124BBB001806E7 /* Copy Presets */, 168F715821124BFC001806E7 /* Support files */, 168F715B21124CD1001806E7 /* Frameworks */, 168F715D21124CF8001806E7 /* Generate Installer Package */, @@ -418,22 +418,6 @@ /* End PBXResourcesBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */ - 168F715721124BBB001806E7 /* Copy Presets */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - "$(SRCROOT)/../../presets", - ); - name = "Copy Presets"; - outputPaths = ( - "$(DERIVED_FILE_DIR)/presets", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/bash; - shellScript = "POUT=\"$BUILT_PRODUCTS_DIR\"/\"$CONTENTS_FOLDER_PATH/Resources/presets\"\nPIN=\"$SRCROOT\"/../../presets\n\nmkdir -p \"$POUT\"\nfor preset_dir in \"$PIN/\"*; do\n cp \"$preset_dir/\"* \"$POUT/\"\ndone\necho \"Copied presets to $POUT\"\n"; - }; 168F715D21124CF8001806E7 /* Generate Installer Package */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 12;