From b6a47bbb286593103fc9460edae62a8253f6db5a Mon Sep 17 00:00:00 2001 From: c-mendoza Date: Wed, 6 Dec 2017 15:03:29 -0500 Subject: [PATCH] Added a DirectoryWatcher to magSlideShowSource --- src/Sources/magSlideShowSource.cpp | 94 ++++++---- src/Sources/magSlideShowSource.h | 267 +++++++++++++++-------------- 2 files changed, 193 insertions(+), 168 deletions(-) diff --git a/src/Sources/magSlideShowSource.cpp b/src/Sources/magSlideShowSource.cpp index 1856f6a..437047f 100644 --- a/src/Sources/magSlideShowSource.cpp +++ b/src/Sources/magSlideShowSource.cpp @@ -10,15 +10,20 @@ #include "SettingsLoader.h" #include "magSlideTransitionFactory.h" -magSlideShowSource::magSlideShowSource() -{ +magSlideShowSource::magSlideShowSource() { name = "Slide Show Source"; currentSlideIndex = 0; isPlaying = false; + directoryWatcher = 0; + doInit = false; } -bool magSlideShowSource::initialize(magSlideShowSource::Settings settings) -{ +magSlideShowSource::~magSlideShowSource() { + directoryWatcher->endWatch(); + delete directoryWatcher; +} + +bool magSlideShowSource::initialize(magSlideShowSource::Settings settings) { this->settings = settings; bool success = true; @@ -45,23 +50,44 @@ bool magSlideShowSource::initialize(magSlideShowSource::Settings settings) << settings.slidesFolderPath; return success; } + { + if (directoryWatcher == 0) + { + + using namespace ofx::piMapper; + directoryWatcher = new DirectoryWatcher(settings.slidesFolderPath, + SourceTypeHelper::GetSourceTypeHelperEnum( + SOURCE_TYPE_NAME_IMAGE)); + ofAddListener(directoryWatcher->directoryFileAddedEvent, this, &magSlideShowSource::fileAddedListener); + ofAddListener(directoryWatcher->directoryFileRemovedEvent, this, + &magSlideShowSource::fileRemovedListener); + directoryWatcher->beginWatch(); + } + } } else if (!settings.slideshowFilePath.empty()) { - // try to load slide show from xml success = false; } + return success; } -void magSlideShowSource::setup() -{ +void magSlideShowSource::setup() { ofx::piMapper::FboSource::setup(); } -void magSlideShowSource::update() -{ +void magSlideShowSource::update() { + + // Perform re-initialization if the DirectoryWatcher + // detects file changes: + if (doInit) + { + initialize(settings); + doInit = false; + } + if (!isPlaying) return; auto nowTime = ofGetElapsedTimeMillis(); @@ -96,8 +122,7 @@ void magSlideShowSource::update() } } -void magSlideShowSource::draw() -{ +void magSlideShowSource::draw() { ofBackground(0, 0); ofPushMatrix(); ofPushStyle(); @@ -115,8 +140,7 @@ void magSlideShowSource::draw() ofDisableAlphaBlending(); } -bool magSlideShowSource::createFromFolderContents(std::string path) -{ +bool magSlideShowSource::createFromFolderContents(std::string path) { ofDirectory dir = ofDirectory(path); slides.clear(); @@ -194,8 +218,7 @@ bool magSlideShowSource::createFromFolderContents(std::string path) } } -bool magSlideShowSource::loadFromXml() -{ +bool magSlideShowSource::loadFromXml() { auto *loader = ofx::piMapper::SettingsLoader::instance(); auto xml = ofxXmlSettings(); Settings settings; @@ -270,8 +293,7 @@ bool magSlideShowSource::loadFromXml() return true; } -void magSlideShowSource::addSlide(std::shared_ptr slide) -{ +void magSlideShowSource::addSlide(std::shared_ptr slide) { // ofLogVerbose("addSlide") << slide->getId(); slides.insert(slides.begin(), slide); auto rOption = slide->getResizeOption(); @@ -337,9 +359,9 @@ void magSlideShowSource::addSlide(std::shared_ptr slide) // bogusParamGroup, // slide->buildInDuration); slide->transition = tf->createTransition(settings.transitionName, - slide, - bogusParamGroup, - slide->buildOutDuration); + slide, + bogusParamGroup, + slide->buildOutDuration); } //// void method(const void * sender, ArgumentsType &args) ofAddListener(slide->slideStateChangedEvent, this, &magSlideShowSource::slideStateChanged); @@ -347,8 +369,7 @@ void magSlideShowSource::addSlide(std::shared_ptr slide) } -void magSlideShowSource::play() -{ +void magSlideShowSource::play() { if (!isPlaying) { runningTime = 0; @@ -359,13 +380,11 @@ void magSlideShowSource::play() } } -void magSlideShowSource::pause() -{ +void magSlideShowSource::pause() { isPlaying = false; } -void magSlideShowSource::playNextSlide() -{ +void magSlideShowSource::playNextSlide() { //TODO // I should check here to see if there are less than two slides. // If so, we should probably return @@ -450,27 +469,23 @@ void magSlideShowSource::playNextSlide() enqueueSlide(slides[currentSlideIndex], ofGetElapsedTimeMillis()); } -void magSlideShowSource::playPrevSlide() -{ +void magSlideShowSource::playPrevSlide() { currentSlideIndex -= (direction*2); playNextSlide(); } -void magSlideShowSource::playSlide(int slideIndex) -{ +void magSlideShowSource::playSlide(int slideIndex) { currentSlideIndex = slideIndex-direction; playNextSlide(); } -void magSlideShowSource::enqueueSlide(std::shared_ptr slide, u_int64_t startTime) -{ +void magSlideShowSource::enqueueSlide(std::shared_ptr slide, u_int64_t startTime) { // ofLogVerbose() << "Enqueuing slide " << currentSlideIndex << " slide id: " << slide->getId(); slide->start(startTime); activeSlides.insert(activeSlides.begin(), slide); } -void magSlideShowSource::slideStateChanged(const void *sender, ofEventArgs &args) -{ +void magSlideShowSource::slideStateChanged(const void *sender, ofEventArgs &args) { magSlide *slide = (magSlide *) sender; // ofLogVerbose("slideStateChanged") << "Slide id: " << slide->getId() << " Slide state: " @@ -488,11 +503,18 @@ void magSlideShowSource::slideStateChanged(const void *sender, ofEventArgs &args } -void magSlideShowSource::slideComplete(const void *sender, ofEventArgs &args) -{ +void magSlideShowSource::slideComplete(const void *sender, ofEventArgs &args) { magSlide *slide = (magSlide *) sender; // ofLogVerbose() << "Slide Complete. id: " << slide->getId(); slide->isComplete = true; } +void magSlideShowSource::fileAddedListener(const void *sender) { + doInit = true; +} + +void magSlideShowSource::fileRemovedListener(const void *sender) { + doInit = true; +} + diff --git a/src/Sources/magSlideShowSource.h b/src/Sources/magSlideShowSource.h index 5284b23..3f58a2f 100644 --- a/src/Sources/magSlideShowSource.h +++ b/src/Sources/magSlideShowSource.h @@ -9,152 +9,155 @@ #include "FboSource.h" #include "magSlide.h" +#include "DirectoryWatcher.h" class magSlide; -class magSlideShowSource : public ofx::piMapper::FboSource -{ -public: - magSlideShowSource(); - struct Settings; // forward declaration - bool initialize(magSlideShowSource::Settings settings); - void setup() override; - void update() override; - void draw() override; - - /** - * Removes all slides and then attempts to create a new slide show - * based on the contents of the ofDirectory specified. The files may - * be images or videos, which will be transformed into the appropriate slide type. - * Any other file type in the directory is ignored (including other directories). - * The slide order is alphabetical according to filename. - * - * @param dir The ofDirectory to use as a source for a slide show. - * @return true if at least one slide was created. false is returned - * otherwise. Check the console for the specific error. - */ - bool createFromFolderContents(std::string path); - - bool loadFromXml(); - void addSlide(std::shared_ptr slide); - void play(); - void pause(); - void playNextSlide(); - void playPrevSlide(); - void playSlide(int slideIndex); - - enum LoopType : int - { - NONE = 0, - NORMAL, - PING_PONG - }; - - struct Settings - { - /** - * The pixel width of the FBO. - */ - float width = 1280; - - /** - * The pixel height of the FBO. - */ - float height = 720; - /** - * An optional default slide duration, in seconds. - * If a slide specifies a duration this value is ignored. - */ - float slideDuration = 5; - - /** - * An optional default transition for the slide show. - */ - std::string transitionName = ""; - - /** - * An optional default transition duration. If no transition - * is specified, this value is ignored; - */ - float transitionDuration = 0; - - /** - * If specified, all applicable files in the folder will - * be used as slides in the slide show. They will be ordered - * alphabetically according to their file names. - * - * If path is relative, the root will likely be the Data folder. - */ - std::string slidesFolderPath = "sources/images"; - - /** - * If specified, - */ - std::string slideshowFilePath; - - - /** - * Loop type for the slide show. See @code LoopType for options. - * The default is @code LoopType:None. - */ - LoopType loopType = LoopType::NONE; - - /** - * The number of loops to perform, if the loopType is not NONE. - * If the value is 0 or less than 0, the slide show loops forever. - */ - int numLoops = 0; +class magSlideShowSource : public ofx::piMapper::FboSource { + public: + magSlideShowSource(); + struct Settings; // forward declaration + bool initialize(magSlideShowSource::Settings settings); + void setup() override; + void update() override; + void draw() override; /** - * The resizing option for the slide show. The default is FitProportionally. - * If a slide already has a resizing option applied, that option will be - * respected and this resizeOption will not be used. + * Removes all slides and then attempts to create a new slide show + * based on the contents of the ofDirectory specified. The files may + * be images or videos, which will be transformed into the appropriate slide type. + * Any other file type in the directory is ignored (including other directories). + * The slide order is alphabetical according to filename. + * + * @param dir The ofDirectory to use as a source for a slide show. + * @return true if at least one slide was created. false is returned + * otherwise. Check the console for the specific error. */ - magSlide::ResizeOptions resizeOption = magSlide::ResizeOptions::FitProportionally; - }; + bool createFromFolderContents(std::string path); + + bool loadFromXml(); + void addSlide(std::shared_ptr slide); + void play(); + void pause(); + void playNextSlide(); + void playPrevSlide(); + void playSlide(int slideIndex); + + enum LoopType : int { + NONE = 0, + NORMAL, + PING_PONG + }; + + struct Settings { + /** + * The pixel width of the FBO. + */ + float width = 1280; + + /** + * The pixel height of the FBO. + */ + float height = 720; + /** + * An optional default slide duration, in seconds. + * If a slide specifies a duration this value is ignored. + */ + float slideDuration = 5; + + /** + * An optional default transition for the slide show. + */ + std::string transitionName = ""; + + /** + * An optional default transition duration. If no transition + * is specified, this value is ignored; + */ + float transitionDuration = 0; + + /** + * If specified, all applicable files in the folder will + * be used as slides in the slide show. They will be ordered + * alphabetically according to their file names. + * + * If path is relative, the root will likely be the Data folder. + */ + std::string slidesFolderPath = "sources/images"; + + /** + * If specified, + */ + std::string slideshowFilePath; + + + /** + * Loop type for the slide show. See @code LoopType for options. + * The default is @code LoopType:None. + */ + LoopType loopType = LoopType::NONE; + + /** + * The number of loops to perform, if the loopType is not NONE. + * If the value is 0 or less than 0, the slide show loops forever. + */ + int numLoops = 0; + + /** + * The resizing option for the slide show. The default is FitProportionally. + * If a slide already has a resizing option applied, that option will be + * respected and this resizeOption will not be used. + */ + magSlide::ResizeOptions resizeOption = magSlide::ResizeOptions::FitProportionally; + }; + + //////////////////////////////////////////// + //// Event Listeners + //////////////////////////////////////////// + void slideStateChanged(const void *sender, ofEventArgs &args); + void slideComplete(const void *sender, ofEventArgs &args); + virtual ~magSlideShowSource(); - //////////////////////////////////////////// - //// Event Listeners - //////////////////////////////////////////// - void slideStateChanged(const void* sender, ofEventArgs &args); - void slideComplete(const void* sender, ofEventArgs &args); - - /** - * Fires when the slide show is done, which happens when - * the loop count is equal to Settings::numLoops, or when - * the last slide is played when @code LoopType::NONE is specified. - * Sender is this slide show. - */ - ofEvent slideshowCompleteEvent; + /** + * Fires when the slide show is done, which happens when + * the loop count is equal to Settings::numLoops, or when + * the last slide is played when @code LoopType::NONE is specified. + * Sender is this slide show. + */ + ofEvent slideshowCompleteEvent; - /** - * Fires when the slide show reaches the last slide - * and will perform a loop in the next call. - * Sender is this slide show. - */ - ofEvent slideshowWillLoopEvent; + /** + * Fires when the slide show reaches the last slide + * and will perform a loop in the next call. + * Sender is this slide show. + */ + ofEvent slideshowWillLoopEvent; -protected: - Settings settings; - std::vector> slides; + protected: + Settings settings; + std::vector> slides; -private: + private: // std::shared_ptr currentSlide; - std::vector> activeSlides; - void enqueueSlide(std::shared_ptr slide, u_int64_t startTime); - - u_int64_t lastTime; - u_int64_t deltaTime; - u_int64_t runningTime; - - bool isInitialized = false; - bool isPlaying = false; - int currentSlideIndex = 0; - int direction = 1; - int loopCount = 0; + std::vector> activeSlides; + void enqueueSlide(std::shared_ptr slide, u_int64_t startTime); + + u_int64_t lastTime; + u_int64_t deltaTime; + u_int64_t runningTime; + + bool isInitialized = false; + bool isPlaying = false; + int currentSlideIndex = 0; + int direction = 1; + int loopCount = 0; + ofx::piMapper::DirectoryWatcher* directoryWatcher; + void fileAddedListener(const void *sender); + void fileRemovedListener(const void *sender); + bool doInit; };