diff --git a/src/projectM-engine/Preset.cpp b/src/projectM-engine/Preset.cpp index 8cb724ffa..67b3a8c41 100755 --- a/src/projectM-engine/Preset.cpp +++ b/src/projectM-engine/Preset.cpp @@ -35,31 +35,17 @@ - -Preset::Preset(const std::string & filename): +Preset::Preset(const std::string & filename, const PresetInputs & presetInputs, PresetOutputs & presetOutputs): file_path(filename), - customWaves(0), - customShapes(0) {} - -Preset::Preset(const PresetInputs * presetInputs, PresetOutputs * presetOutputs, const std::string & filename): - file_path(filename), - builtinParams(*presetInputs, *presetOutputs), - customWaves(&presetOutputs->customWaves), - customShapes(&presetOutputs->customShapes) + builtinParams(presetInputs, presetOutputs), + customWaves(&presetOutputs.customWaves), + customShapes(&presetOutputs.customShapes) { initialize(filename); } -/// @bug is memory properly deallocated? verify -void Preset::setIO(const PresetInputs * presetInputs, PresetOutputs * presetOutputs) { - builtinParams = BuiltinParams(*presetInputs, *presetOutputs); - customWaves = &presetOutputs->customWaves; - customShapes = &presetOutputs->customShapes; - initialize(file_path); -} - Preset::~Preset() { #if defined(PRESET_DEBUG) && defined(DEBUG) diff --git a/src/projectM-engine/Preset.hpp b/src/projectM-engine/Preset.hpp index 5129b2493..b8f007408 100644 --- a/src/projectM-engine/Preset.hpp +++ b/src/projectM-engine/Preset.hpp @@ -61,18 +61,11 @@ protected: public: /** Load a preset by filename with input and output buffers specified. - * Most common way to allocate new preset */ - Preset(const PresetInputs * presetInputs, PresetOutputs * presetOutputs, const std::string & filename); - - /** Initializes a preset object and stores the filename associated with it. The preset is NOT properly initialize - * until a call to member function setIO is made */ - Preset(const std::string & filename); + * This is the only poper way to allocate a new preset. */ + Preset(const std::string & filename, const PresetInputs & presetInputs, PresetOutputs & presetOutputs); ~Preset(); - /** Set or reset the input and output associations for this preset. */ - void setIO(const PresetInputs * presetInputs, PresetOutputs * presetOutputs); - /** Evaluates the preset for a frame given the current values of preset inputs / outputs */ void evaluateFrame(); diff --git a/src/projectM-engine/PresetSwitcher.cpp b/src/projectM-engine/PresetChooser.cpp similarity index 100% rename from src/projectM-engine/PresetSwitcher.cpp rename to src/projectM-engine/PresetChooser.cpp diff --git a/src/projectM-engine/PresetChooser.hpp b/src/projectM-engine/PresetChooser.hpp new file mode 100644 index 000000000..f7fea55af --- /dev/null +++ b/src/projectM-engine/PresetChooser.hpp @@ -0,0 +1,108 @@ +/** PresetChooser.hpp: + * This class is a WIP that provides methods to load presets, switch presets, and + * merge them. The user of this class decides when / how to switch by calling functions + * of this class at the appropriate times in the renderer. + * DECISION: Merging / etc. goes in PresetFilters.hpp! Loading goes in here, switching goes in here + */ + +/// More specifically, we need to +/// (1) load presets from a path(s) +/// (2) set which preset is the "active" presets +/// (3) merge two presets together - probably doesn't belong in this class +/// how about another class called PresetFilters? + + +/// @idea Weighted random based on user stats + +#ifndef PRESET_CHOOSER_HPP +#define PRESET_CHOOSER_HPP +#include "Preset.hpp" +#include "projectM.h" + +class PresetChooser { + +public: + + // Used for aribtrary randomness + typedef PresetIterator iterator; + + /** Initializes a chooser with an established preset loader. Note that the loader must be + * refreshed via events or otherwise *outside* this class's scope **/ + PresetChooser(const PresetLoader & presetLoader); + + class PresetIterator { + + PresetIterator():m_chooser(0) {} + + void operator++() { + assert(m_currentIndex < (m_presetLoader.getNumPresets()-1)); + m_currentIndex++; + } + + void operator--() { + assert(m_currentIndex > 0); + m_currentIndex--; + } + + std::size_t operator*() { + return m_currentIndex; + } + + std::auto_ptr allocate(const PresetInputs & presetInputs, PresetOutputs & presetOutputs) { + return m_presetChooser.directoryIndex(m_currentIndex, presetInputs, presetOutputs); + } + + private: + std::size_t m_currentIndex; + inline void setChooser(const PresetChooser & chooser) { + + m_presetChooser = &chooser; + } + const PresetChooser * m_presetChooser; + }; + + /** Choose a preset via the passed in index. Must be between 0 and num valid presets in directory **/ + std::auto_ptr directoryIndex(std::size_int index, const PresetInputs & presetInputs, + PresetOutputs & presetOutputs) const; + + class UniformRandomFunctor { + + public: + UniformRandomFunctor(std::size_t collectionSize):m_collectionSize(collectionSize) {} + + std::size_t operator() (std::size_t index) { + return (1.0 / (float)m_collectionSize); + } + + private: + std::size_t m_collectionSize; + + }; + + + /** Samples from the preset collection **/ + template + std::auto_ptr weightedRandom(const PresetInputs & presetInputs, PresetOutputs & presetOutputs, WeightFunctor & weightFunctor) const { + + + // Choose a random index from the preset directory + float cutoff = ((float)(random())) / RAND_MAX; + float mass = 0; + + for(iterator pos = this->begin();pos != this->end() ; ++pos) { + mass += weightFunctor(*pos); + if (mass >= cutoff) + return pos.allocate(presetInputs,presetOutputs); + } + + } + + }; + + + +/* destroyPresetLoader: closes the preset + loading library. This should be done when + PresetChooser does cleanup */ +}; +#endif diff --git a/src/projectM-engine/PresetLoader.cpp b/src/projectM-engine/PresetLoader.cpp index 0426d5de0..0a8eda823 100644 --- a/src/projectM-engine/PresetLoader.cpp +++ b/src/projectM-engine/PresetLoader.cpp @@ -16,6 +16,7 @@ extern "C" { #include #include } +#include PresetLoader::PresetLoader(std::string dirname) :m_dirname(dirname) { @@ -37,13 +38,13 @@ m_entries.clear(); closedir(m_dir); } -// Allocate a new a stream given the current diectory name +// Allocate a new a stream given the current directory name if ((m_dir = opendir(m_dirname.c_str())) == NULL) { handleDirectoryError(); } -std::string fullPath; -std::ostringstream out(fullPath); + +std::ostringstream out; struct dirent * dir_entry; while ((dir_entry = readdir(m_dir)) != NULL) { @@ -68,6 +69,17 @@ while ((dir_entry = readdir(m_dir)) != NULL) { } +std::auto_ptr PresetLoader::loadPreset(unsigned int index, const PresetInputs & presetInputs, PresetOutputs & presetOutputs) { + + // Check that index isn't insane + assert(index >= 0); + assert(index < m_entries.size()); + + // Return a new auto pointer to a present + return std::auto_ptr(new Preset(m_entries[index], presetInputs, presetOutputs)); +} + + void PresetLoader::handleDirectoryError() { switch (errno) { @@ -88,4 +100,4 @@ void PresetLoader::handleDirectoryError() { default: break; } -} \ No newline at end of file +} diff --git a/src/projectM-engine/PresetLoader.hpp b/src/projectM-engine/PresetLoader.hpp index 503629519..374ae006a 100644 --- a/src/projectM-engine/PresetLoader.hpp +++ b/src/projectM-engine/PresetLoader.hpp @@ -1,9 +1,9 @@ #ifndef __PRESET_LOADER_HPP #define __PRESET_LOADER_HPP -#include -#include "Preset.hpp" - +#include // used for path / filename stuff +#include "Preset.hpp" // used to allocate presets via loadDir +#include // for auto pointers class PresetLoader { public: @@ -19,7 +19,7 @@ class PresetLoader { #endif #ifdef WIN32 - static const char PATH_SEPARATOR = '\'; + static const char PATH_SEPARATOR = '\\'; #endif @@ -28,11 +28,11 @@ class PresetLoader { /** Destructor will remove all alllocated presets */ ~PresetLoader(); - - /** Load a preset by indexing the collection of presets from a directory */ - /** Autopointers: when you take it, I leave it */ -// auto_ptr loadPreset(unsigned int index, const PresetInputs & presetInputs, PresetOutputs & presetOutputs); -// auto_ptr loadPreset(std::string filename); + + /** Load a preset by specifying a filename of the directory (that is, NOT full path) */ + /** Autopointers: when you take it, I leave it */ + std::auto_ptr loadPreset(unsigned int index, const PresetInputs & presetInputs, + PresetOutputs & presetOutputs); /** Returns the number of presets in the active directory */ inline std::size_t getNumPresets() { @@ -45,11 +45,12 @@ class PresetLoader { /** Rescans the active preset directory */ void rescan(); - private: void handleDirectoryError(); std::string m_dirname; DIR * m_dir; + + // vector chosen for speed, but not great for reverse index lookups std::vector m_entries; }; diff --git a/src/projectM-engine/PresetSwitcher.hpp b/src/projectM-engine/PresetSwitcher.hpp deleted file mode 100644 index a0c4045d1..000000000 --- a/src/projectM-engine/PresetSwitcher.hpp +++ /dev/null @@ -1,47 +0,0 @@ -/** PresetSwitcher.hpp: - * This class is a WIP that provides methods to load presets, switch presets, and - * merge them. The user of this class decides when / how to switch by calling functions - * of this class at the appropriate times in the renderer. - * DECISION: Merging / etc. goes in PresetFilters.hpp! Loading goes in here, switching goes in here - */ - -/// More specifically, we need to -/// (1) load presets from a path(s) -/// (2) set which preset is the "active" presets -/// (3) merge two presets together - probably doesn't belong in this class -/// how about another class called PresetFilters? - - -/// @idea Weighted random based on user stats - -#ifndef PRESET_SWITCHER_HPP -#define PRESET_SWITCHER_HPP -#include "Preset.hpp" -#include "projectM.h" - -typedef enum { - ALPHA_NEXT, - ALPHA_PREVIOUS, - RANDOM_NEXT, - RESTART_ACTIVE, -} switch_mode_t; - - -class PresetSwitcher { - -public: - - /** Preset switching */ - int loadPresetDir( char *dir ); - int closePresetDir(); - int switchPreset( switch_mode_t switch_mode, int cut_type); - int loadPresetByFile( char *filename ); - int initPresetLoader(); - int destroyPresetLoader(); - static int is_valid_extension(const struct dirent* ent); - -/* destroyPresetLoader: closes the preset - loading library. This should be done when - PresetSwitcher does cleanup */ -}; -#endif diff --git a/src/projectM-engine/projectM.h b/src/projectM-engine/projectM.h index 41303c3df..034eece12 100755 --- a/src/projectM-engine/projectM.h +++ b/src/projectM-engine/projectM.h @@ -144,9 +144,8 @@ public: #else long startTime; #endif /** !WIN32 */ - + /** Render target texture ID */ - char disp[80]; @@ -157,14 +156,10 @@ public: int fvh; int wvw; //windowed dimensions int wvh; - + int fullscreen; - + int avgtime; //# frames per preset - - - - /** Timing information */ int mspf;