From 936ebd475189fcfae4bd2e8056d68b2bd311033e Mon Sep 17 00:00:00 2001 From: carm Date: Tue, 13 Nov 2012 23:26:35 -0500 Subject: [PATCH] safe guard against expressions like x = 2*sin(bas)+5* --- .../MilkdropPresetFactory/Expr.cpp | 14 ++- .../MilkdropPresetFactory/Parser.cpp | 2 +- .../MilkdropPresetFactory/Parser.hpp | 2 +- src/libprojectM/PresetFactoryManager.cpp | 4 +- src/libprojectM/projectM.cpp | 94 +++++++------------ src/libprojectM/projectM.hpp | 6 +- 6 files changed, 57 insertions(+), 65 deletions(-) diff --git a/src/libprojectM/MilkdropPresetFactory/Expr.cpp b/src/libprojectM/MilkdropPresetFactory/Expr.cpp index 2f3efdf29..78502d56b 100755 --- a/src/libprojectM/MilkdropPresetFactory/Expr.cpp +++ b/src/libprojectM/MilkdropPresetFactory/Expr.cpp @@ -157,10 +157,20 @@ float TreeExpr::eval_tree_expr ( int mesh_i, int mesh_j ) /* Otherwise, this node is an infix operator. Evaluate accordingly */ - assert(left); + /* Safe guard in case the user gave a partially written expression */ + if (left == NULL) { + if (infix_op == Eval::infix_mult) + return 1; + else + return 0; + } + left_arg = left->eval_tree_expr ( mesh_i, mesh_j ); - assert(right); + /* Safe guard */ + if (right == NULL) + return left_arg; + right_arg = right->eval_tree_expr ( mesh_i, mesh_j ); diff --git a/src/libprojectM/MilkdropPresetFactory/Parser.cpp b/src/libprojectM/MilkdropPresetFactory/Parser.cpp index 16c3c82c5..fb14e6fe4 100755 --- a/src/libprojectM/MilkdropPresetFactory/Parser.cpp +++ b/src/libprojectM/MilkdropPresetFactory/Parser.cpp @@ -1070,7 +1070,7 @@ int Parser::insert_gen_rec(GenExpr * gen_expr, TreeExpr * root) if (root == NULL) { - //if (PARSE_DEBUG) printf("insert_gen_rec: root is null, returning failure\n"); + if (PARSE_DEBUG) printf("insert_gen_rec: root is null, returning failure\n"); return PROJECTM_FAILURE; } diff --git a/src/libprojectM/MilkdropPresetFactory/Parser.hpp b/src/libprojectM/MilkdropPresetFactory/Parser.hpp index 8c0e19d27..803541723 100755 --- a/src/libprojectM/MilkdropPresetFactory/Parser.hpp +++ b/src/libprojectM/MilkdropPresetFactory/Parser.hpp @@ -29,7 +29,7 @@ #ifndef _PARSER_H #define _PARSER_H //#define PARSE_DEBUG 2 -#define PARSE_DEBUG 0 +#define PARSE_DEBUG 2 #include diff --git a/src/libprojectM/PresetFactoryManager.cpp b/src/libprojectM/PresetFactoryManager.cpp index 5e748f138..9a349d2d8 100644 --- a/src/libprojectM/PresetFactoryManager.cpp +++ b/src/libprojectM/PresetFactoryManager.cpp @@ -84,12 +84,14 @@ std::auto_ptr PresetFactoryManager::allocate(const std::string & url, co const std::string extension = parseExtension (url); return factory(extension).allocate(url, name); + } catch (const PresetFactoryException & e) { + throw e; } catch (const std::exception & e) { throw PresetFactoryException(e.what()); } catch (...) { throw PresetFactoryException("uncaught preset factory exception"); } - + return std::auto_ptr(); } PresetFactory & PresetFactoryManager::factory(const std::string & extension) { diff --git a/src/libprojectM/projectM.cpp b/src/libprojectM/projectM.cpp index 26e84e07b..36f16dea6 100755 --- a/src/libprojectM/projectM.cpp +++ b/src/libprojectM/projectM.cpp @@ -693,27 +693,35 @@ static void *thread_callback(void *prjm) { return index; } - void projectM::selectPreset ( unsigned int index, bool hardCut) + void projectM::selectPreset(unsigned int index, bool hardCut) { if (m_presetChooser->empty()) return; - if (!hardCut) { - timeKeeper->StartSmoothing(); - } *m_presetPos = m_presetChooser->begin(index); + switchPreset(hardCut); + } + void projectM::switchPreset(const bool hardCut) { + std::string result; if (!hardCut) { - switchPreset(m_activePreset2); + result = switchPreset(m_activePreset2); } else { - switchPreset(m_activePreset); - timeKeeper->StartPreset(); + result = switchPreset(m_activePreset); + if (result.empty()) + timeKeeper->StartPreset(); } - presetSwitchedEvent(hardCut, **m_presetPos); + if (result.empty() && !hardCut) { + timeKeeper->StartSmoothing(); + } + if (result.empty()) + presetSwitchedEvent(hardCut, **m_presetPos); + else + presetSwitchFailedEvent(hardCut, **m_presetPos, result); } @@ -722,20 +730,9 @@ void projectM::selectRandom(const bool hardCut) { if (m_presetChooser->empty()) return; - if (!hardCut) { - timeKeeper->StartSmoothing(); - } - *m_presetPos = m_presetChooser->weightedRandom(hardCut); - if (!hardCut) { - switchPreset(m_activePreset2); - } else { - switchPreset(m_activePreset); - timeKeeper->StartPreset(); - } - - presetSwitchedEvent(hardCut, **m_presetPos); + switchPreset(hardCut); } @@ -744,27 +741,10 @@ void projectM::selectPrevious(const bool hardCut) { if (m_presetChooser->empty()) return; - if (!hardCut) { - timeKeeper->StartSmoothing(); - } m_presetChooser->previousPreset(*m_presetPos); - if (!hardCut) { - switchPreset(m_activePreset2); - } else { - switchPreset(m_activePreset); - timeKeeper->StartPreset(); - } - - presetSwitchedEvent(hardCut, **m_presetPos); - -// m_activePreset = m_presetPos->allocate(); -// renderer->SetPipeline(m_activePreset->pipeline()); -// renderer->setPresetName(m_activePreset->name()); - - //timeKeeper->StartPreset(); - + switchPreset(hardCut); } void projectM::selectNext(const bool hardCut) { @@ -772,36 +752,30 @@ void projectM::selectNext(const bool hardCut) { if (m_presetChooser->empty()) return; - if (!hardCut) { - timeKeeper->StartSmoothing(); - std::cout << "start smoothing" << std::endl; - } - m_presetChooser->nextPreset(*m_presetPos); - if (!hardCut) { - switchPreset(m_activePreset2); - } else { - switchPreset(m_activePreset); - timeKeeper->StartPreset(); - } - presetSwitchedEvent(hardCut, **m_presetPos); - - + switchPreset(hardCut); } /** - * - * @param targetPreset - */ -void projectM::switchPreset(std::auto_ptr & targetPreset) { +* Switches to the target preset. +* @param targetPreset +* @return a message indicating an error, empty otherwise. +*/ +std::string projectM::switchPreset(std::auto_ptr & targetPreset) { #ifdef SYNC_PRESET_SWITCHES pthread_mutex_lock(&preset_mutex); #endif - + try { targetPreset = m_presetPos->allocate(); - + } catch (const PresetFactoryException & e) { + #ifdef SYNC_PRESET_SWITCHES + pthread_mutex_unlock(&preset_mutex); + #endif + std::cerr << "problem allocating target preset: " << e.message() << std::endl; + return e.message(); + } // Set preset name here- event is not done because at the moment this function is oblivious to smooth/hard switches renderer->setPresetName(targetPreset->name()); renderer->SetPipeline(targetPreset->pipeline()); @@ -809,7 +783,9 @@ void projectM::switchPreset(std::auto_ptr & targetPreset) { #ifdef SYNC_PRESET_SWITCHES pthread_mutex_unlock(&preset_mutex); #endif - } + + return std::string(); + } void projectM::setPresetLock ( bool isLocked ) { diff --git a/src/libprojectM/projectM.hpp b/src/libprojectM/projectM.hpp index 5fa38d302..f01235a09 100755 --- a/src/libprojectM/projectM.hpp +++ b/src/libprojectM/projectM.hpp @@ -243,6 +243,8 @@ public: /// Occurs when active preset has switched. Switched to index is returned virtual void presetSwitchedEvent(bool isHardCut, unsigned int index) const {}; virtual void shuffleEnabledValueChanged(bool isEnabled) const {}; + virtual void presetSwitchFailedEvent(bool hardCut, unsigned int index, const std::string & message) const {}; + /// Occurs whenever preset rating has changed via changePresetRating() method virtual void presetRatingChanged(unsigned int index, int rating, PresetRatingType ratingType) const {}; @@ -320,7 +322,9 @@ private: Pipeline* currentPipe; -void switchPreset(std::auto_ptr & targetPreset); + std::string switchPreset(std::auto_ptr & targetPreset); + void switchPreset(const bool hardCut); + };