From a28a24ef834c1a9427a65008f19fcb558413f1e2 Mon Sep 17 00:00:00 2001 From: Bryan Walsh Date: Mon, 9 Apr 2018 19:37:26 -0400 Subject: [PATCH 01/16] install additional headers needed to compile against libprojectm --- Makefile.am | 3 +++ src/libprojectM/Makefile.am | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/Makefile.am b/Makefile.am index 062bb3ca1..87a8741ae 100644 --- a/Makefile.am +++ b/Makefile.am @@ -17,6 +17,9 @@ pm_font__DATA = fonts/Vera.ttf fonts/VeraMono.ttf pm_shaders__DATA = src/libprojectM/Renderer/blur.cg \ src/libprojectM/Renderer/projectM.cg +# system headers/libraries/data to install +include_HEADERS = config.h + # find and install all preset files install-data-local: test -z $(pkgdatadir) || $(MKDIR_P) $(pm_presets_dir) diff --git a/src/libprojectM/Makefile.am b/src/libprojectM/Makefile.am index 03ac1e53f..73d8353f6 100644 --- a/src/libprojectM/Makefile.am +++ b/src/libprojectM/Makefile.am @@ -12,7 +12,7 @@ AM_CPPFLAGS = \ $(FTGL_CFLAGS) $(CG_CFLAGS) # system headers/libraries/data to install -include_HEADERS = projectM.hpp +include_HEADERS = projectM.hpp Common.hpp dlldefs.h event.h fatal.h PCM.hpp lib_LTLIBRARIES = libprojectM.la # public, possibly-shared library # link flags From 0cf9fb0c9312d14176dfe6e53c5b780d83d5544f Mon Sep 17 00:00:00 2001 From: Bryan Walsh Date: Tue, 10 Apr 2018 18:54:12 -0400 Subject: [PATCH 02/16] do not install config.h. Remove config.h from Common.hpp --- Makefile.am | 3 --- src/libprojectM/Common.hpp | 2 +- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/Makefile.am b/Makefile.am index 87a8741ae..062bb3ca1 100644 --- a/Makefile.am +++ b/Makefile.am @@ -17,9 +17,6 @@ pm_font__DATA = fonts/Vera.ttf fonts/VeraMono.ttf pm_shaders__DATA = src/libprojectM/Renderer/blur.cg \ src/libprojectM/Renderer/projectM.cg -# system headers/libraries/data to install -include_HEADERS = config.h - # find and install all preset files install-data-local: test -z $(pkgdatadir) || $(MKDIR_P) $(pm_presets_dir) diff --git a/src/libprojectM/Common.hpp b/src/libprojectM/Common.hpp index 368d03fad..cd2ee0431 100755 --- a/src/libprojectM/Common.hpp +++ b/src/libprojectM/Common.hpp @@ -30,7 +30,7 @@ #include #include #include -#include "config.h" + #ifdef _MSC_sVER #define strcasecmp(s, t) _strcmpi(s, t) #endif From 4305ce94f40526de8cd92200c1abf5f369bc03b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20M=C3=BCller?= Date: Sat, 14 Apr 2018 21:45:07 +0200 Subject: [PATCH 03/16] Re-add pkg-config support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Give others - e.g qmmp the chance to find projectM Signed-off-by: Andreas Müller --- configure.ac | 1 + src/libprojectM/Makefile.am | 6 +++--- src/libprojectM/libprojectM.pc.in | 14 +++++++------- 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/configure.ac b/configure.ac index 96ce9dd75..eb582aa1a 100644 --- a/configure.ac +++ b/configure.ac @@ -19,6 +19,7 @@ AC_CONFIG_FILES([ src/libprojectM/Renderer/Makefile src/libprojectM/NativePresetFactory/Makefile src/libprojectM/MilkdropPresetFactory/Makefile + src/libprojectM/libprojectM.pc src/NativePresets/Makefile src/projectM-sdl/Makefile src/projectM-qt/Makefile diff --git a/src/libprojectM/Makefile.am b/src/libprojectM/Makefile.am index 73d8353f6..f102b9fb7 100644 --- a/src/libprojectM/Makefile.am +++ b/src/libprojectM/Makefile.am @@ -48,6 +48,6 @@ libprojectM_la_SOURCES = ConfigFile.cpp Preset.cpp PresetLoader.cpp timer.cpp \ omptl/omptl_algorithm pkgconfigdir = $(libdir)/pkgconfig -# pkgconfig_DATA = src/libprojectM.pc -# EXTRA_DIST += src/libprojectM.pc.in -# CLEANFILES += src/libprojectM.pc +pkgconfig_DATA = libprojectM.pc +EXTRA_DIST += libprojectM.pc.in +CLEANFILES += libprojectM.pc diff --git a/src/libprojectM/libprojectM.pc.in b/src/libprojectM/libprojectM.pc.in index 90de75231..84f6694e8 100644 --- a/src/libprojectM/libprojectM.pc.in +++ b/src/libprojectM/libprojectM.pc.in @@ -1,12 +1,12 @@ -prefix=@CMAKE_INSTALL_PREFIX@ -exec_prefix=@CMAKE_INSTALL_PREFIX@ -libdir=@LIB_INSTALL_DIR@ -includedir=@CMAKE_INSTALL_PREFIX@/include -pkgdatadir=@CMAKE_INSTALL_PREFIX@/@RESOURCE_PREFIX@ -sysconfdir=@CMAKE_INSTALL_PREFIX@/@RESOURCE_PREFIX@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ +pkgdatadir=@datadir@/@PACKAGE_NAME@ +sysconfdir=@datadir@/@PACKAGE_NAME@ Name: libprojectM -Version: @PROJECTM_VERSION@ +Version: @PACKAGE_VERSION@ Description: projectM - OpenGL Milkdrop Requires: Libs: -L${libdir} -lprojectM From 9c7d9dfdd4c8c9360850cd4712ca2d46afdac62a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20M=C3=BCller?= Date: Sun, 15 Apr 2018 00:20:41 +0200 Subject: [PATCH 04/16] Install headers to /usr/include/libprojectM MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit That is where the were before switching to autotools and where projects expect them. Signed-off-by: Andreas Müller --- src/Makefile.am | 4 ++++ src/libprojectM/Makefile.am | 2 -- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/Makefile.am b/src/Makefile.am index ea0af3a36..85478b4de 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -7,3 +7,7 @@ if ENABLE_QT endif SUBDIRS=libprojectM NativePresets ${PROJECTM_SDL_SUBDIR} ${PROJECTM_QT_SUBDIR} + +# system headers/libraries/data to install +# for compatibility reasons here as nobase_include +nobase_include_HEADERS = libprojectM/projectM.hpp libprojectM/Common.hpp libprojectM/dlldefs.h libprojectM/event.h libprojectM/fatal.h libprojectM/PCM.hpp diff --git a/src/libprojectM/Makefile.am b/src/libprojectM/Makefile.am index f102b9fb7..12d16cac4 100644 --- a/src/libprojectM/Makefile.am +++ b/src/libprojectM/Makefile.am @@ -11,8 +11,6 @@ AM_CPPFLAGS = \ -I$(top_srcdir)/src/libprojectM/Renderer \ $(FTGL_CFLAGS) $(CG_CFLAGS) -# system headers/libraries/data to install -include_HEADERS = projectM.hpp Common.hpp dlldefs.h event.h fatal.h PCM.hpp lib_LTLIBRARIES = libprojectM.la # public, possibly-shared library # link flags From 38fff2744e218537aef283eea6b57bf6b08432bd Mon Sep 17 00:00:00 2001 From: deltaoscarmike <37912794+deltaoscarmike@users.noreply.github.com> Date: Thu, 26 Apr 2018 22:34:23 +0200 Subject: [PATCH 05/16] Fix typo --- src/libprojectM/MilkdropPresetFactory/BuiltinParams.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libprojectM/MilkdropPresetFactory/BuiltinParams.cpp b/src/libprojectM/MilkdropPresetFactory/BuiltinParams.cpp index e33149b51..90f64346d 100644 --- a/src/libprojectM/MilkdropPresetFactory/BuiltinParams.cpp +++ b/src/libprojectM/MilkdropPresetFactory/BuiltinParams.cpp @@ -367,8 +367,8 @@ int BuiltinParams::load_all_builtin_param(const PresetInputs & presetInputs, Pre load_builtin_param_float("mv_x", (void*)&presetOutputs.mv.x_num, NULL,P_FLAG_NONE, 0.0, 64.0, 0.0, "nmotionvectorsx"); load_builtin_param_float("mv_y", (void*)&presetOutputs.mv.y_num, NULL,P_FLAG_NONE, 0.0, 48.0, 0.0, "nmotionvectorsy"); load_builtin_param_float("mv_l", (void*)&presetOutputs.mv.length, NULL,P_FLAG_NONE, 0.0, 5.0, 0.0, ""); - load_builtin_param_float("mv_dy", (void*)&presetOutputs.mv.x_offset, NULL, P_FLAG_NONE, 0.0, 1.0, -1.0, ""); - load_builtin_param_float("mv_dx", (void*)&presetOutputs.mv.y_offset, NULL,P_FLAG_NONE, 0.0, 1.0, -1.0, ""); + load_builtin_param_float("mv_dx", (void*)&presetOutputs.mv.x_offset, NULL, P_FLAG_NONE, 0.0, 1.0, -1.0, ""); + load_builtin_param_float("mv_dy", (void*)&presetOutputs.mv.y_offset, NULL,P_FLAG_NONE, 0.0, 1.0, -1.0, ""); load_builtin_param_float("mv_a", (void*)&presetOutputs.mv.a, NULL,P_FLAG_NONE, 0.0, 1.0, 0.0, ""); load_builtin_param_float("time", (void*)&presetInputs.time, NULL,P_FLAG_READONLY, 0.0, MAX_DOUBLE_SIZE, 0.0, ""); From 34d63573e476b3c08e8f9c74e3012e230ceb53f6 Mon Sep 17 00:00:00 2001 From: Mischa Spiegelmock Date: Fri, 27 Apr 2018 02:15:11 -0700 Subject: [PATCH 06/16] update tests to look for headers in libprojectM/... --- .travis.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 64107affd..8235a6e95 100644 --- a/.travis.yml +++ b/.travis.yml @@ -16,7 +16,9 @@ script: - test -e dist_install/share/projectM/shaders/blur.cg - test -d dist_install/share/projectM/presets - test -e dist_install/lib/libprojectM.la - - test -e dist_install/include/projectM.hpp + - test -e dist_install/include/libprojectM/projectM.hpp + - test -e dist_install/include/libprojectM/Common.hpp + - test -e dist_install/include/libprojectM/PCM.hpp # test on GCC and Clang matrix: From 133b0a74f17a3ac22a1b7bab2cb2b06402128492 Mon Sep 17 00:00:00 2001 From: Mischa Spiegelmock Date: Fri, 27 Apr 2018 02:53:07 -0700 Subject: [PATCH 07/16] remove bogus readme --- src/README | 30 ------------------------------ 1 file changed, 30 deletions(-) delete mode 100644 src/README diff --git a/src/README b/src/README deleted file mode 100644 index b95e1e781..000000000 --- a/src/README +++ /dev/null @@ -1,30 +0,0 @@ -PROJECTM README ------------------------------- -NOTE: The projectM wiki at http://projectm.wiki.sourceforge.net/ is the official source for build instructions. What lies below is just a terse review of how to build the source yourself. - -(1) How to configure the projectM build - -In the top level directory from where you extracted projectM, run - -ccmake . - -This will present you with a simple console based gui of options for projectM. First press "c" to run the configure script. Review the options and change what you think is necessary. Press 'g' to generate the make files and exit. - -(2) Compiling and installing - - -As usual, type - -make - -followed by - -make install - -If any problems go to the web page at - -http://projectm.sf.net - - - - From 39b74ef528cd6a20a7c493eba14f5d01853f590e Mon Sep 17 00:00:00 2001 From: Matthew Bellew Date: Tue, 8 May 2018 21:56:22 -0700 Subject: [PATCH 08/16] virtual Expr::eval() --- .../MilkdropPresetFactory/Eval.hpp | 2 +- .../MilkdropPresetFactory/Expr.cpp | 123 ++++++++---------- .../MilkdropPresetFactory/Expr.hpp | 45 ++++--- .../MilkdropPresetFactory/Parser.cpp | 22 ++-- 4 files changed, 98 insertions(+), 94 deletions(-) diff --git a/src/libprojectM/MilkdropPresetFactory/Eval.hpp b/src/libprojectM/MilkdropPresetFactory/Eval.hpp index 51bd22f7b..70da02546 100755 --- a/src/libprojectM/MilkdropPresetFactory/Eval.hpp +++ b/src/libprojectM/MilkdropPresetFactory/Eval.hpp @@ -84,7 +84,7 @@ public: static int init_infix_ops(); static int destroy_infix_ops(); void reset_engine_vars(); - + GenExpr * clone_gen_expr(GenExpr * gen_expr); TreeExpr * clone_tree_expr(TreeExpr * tree_expr); ValExpr * clone_val_expr(ValExpr * val_expr); diff --git a/src/libprojectM/MilkdropPresetFactory/Expr.cpp b/src/libprojectM/MilkdropPresetFactory/Expr.cpp index 14b5ad1e6..27467a799 100755 --- a/src/libprojectM/MilkdropPresetFactory/Expr.cpp +++ b/src/libprojectM/MilkdropPresetFactory/Expr.cpp @@ -27,34 +27,25 @@ #include #include "Eval.hpp" -float GenExpr::eval_gen_expr ( int mesh_i, int mesh_j ) +float GenExpr::eval ( int mesh_i, int mesh_j ) { - float l; - if (item == 0) return EVAL_ERROR; switch ( this->type ) { /* N.B. this code is responsible for 75% of all CPU time. making it faster will help a lot. */ case VAL_T: - return ( ( ValExpr* ) item )->eval_val_expr ( mesh_i, mesh_j ); case PREFUN_T: - l = ( ( PrefunExpr * ) item )->eval_prefun_expr ( mesh_i, mesh_j ); - //if (EVAL_DEBUG) DWRITE( "eval_gen_expr: prefix function return value: %f\n", l); - return l; case TREE_T: - return ( ( TreeExpr* ) ( item ) )->eval_tree_expr ( mesh_i, mesh_j ); + return item->eval( mesh_i, mesh_j ); default: return EVAL_ERROR; } - } /* Evaluates functions in prefix form */ -float PrefunExpr::eval_prefun_expr ( int mesh_i, int mesh_j ) +float PrefunExpr::eval ( int mesh_i, int mesh_j ) { - - assert ( func_ptr ); float arg_list_stk[10]; @@ -92,19 +83,23 @@ float PrefunExpr::eval_prefun_expr ( int mesh_i, int mesh_j ) } -/* Evaluates a value expression */ -float ValExpr::eval_val_expr ( int mesh_i, int mesh_j ) +// private subclasses of ValExpr -- ConstantExpr, ParameterExpr +class ConstantExpr : public ValExpr { +public: + ConstantExpr( int type, Term *term ) : ValExpr(type,term) {} + float eval(int mesh_i, int mesh_j ) { return term.constant; } +}; +class ParameterExpr : public ValExpr +{ +public: + ParameterExpr( int type, Term *term ) : ValExpr(type,term) {} + float eval(int mesh_i, int mesh_j ); +}; - /* Value is a constant, return the float value */ - if ( type == CONSTANT_TERM_T ) - { - return ( term.constant ); - } - - /* Value is variable, dereference it */ - if ( type == PARAM_TERM_T ) +/* Evaluates a value expression */ +float ParameterExpr::eval ( int mesh_i, int mesh_j ) { switch ( term.param->type ) { @@ -146,48 +141,44 @@ float ValExpr::eval_val_expr ( int mesh_i, int mesh_j ) return EVAL_ERROR; } } - /* Unknown type, return failure */ - return PROJECTM_FAILURE; + + +/* This could be optimized a lot more if we could return an Expr instead of a TreeExpr */ +TreeExpr * TreeExpr::create( InfixOp * _infix_op, Expr * _gen_expr, TreeExpr * _left, TreeExpr * _right ) +{ + float defautFloat = _infix_op == Eval::infix_mult ? 1.0f : 0.0f; + + if (_infix_op == NULL) + { + if (_gen_expr == NULL) + _gen_expr = GenExpr::const_to_expr(0.0f); + } + else + { + if (_left == NULL) + _left = new TreeExpr(NULL, GenExpr::const_to_expr(defautFloat), NULL, NULL); + if (_right == NULL) + _right = new TreeExpr(NULL, GenExpr::const_to_expr(defautFloat), NULL, NULL); + } + return new TreeExpr( _infix_op, _gen_expr, _left, _right); } /* Evaluates an expression tree */ -float TreeExpr::eval_tree_expr ( int mesh_i, int mesh_j ) +float TreeExpr::eval ( int mesh_i, int mesh_j ) { - float left_arg, right_arg; /* A leaf node, evaluate the general expression. If the expression is null as well, return zero */ if ( infix_op == NULL ) { - if ( gen_expr == NULL ) - return 0; - else - return gen_expr->eval_gen_expr ( mesh_i, mesh_j ); + return gen_expr->eval( mesh_i, mesh_j ); } /* Otherwise, this node is an infix operator. Evaluate accordingly */ - /* Safe guard in case the user gave a partially written expression */ - if (left == NULL) { - if (infix_op == Eval::infix_mult) - left_arg = 1; - else - left_arg = 0; - } - else - left_arg = left->eval_tree_expr ( mesh_i, mesh_j ); - - /* Safe guard in case the user gave a partially written expression */ - if (right == NULL) { - if (infix_op == Eval::infix_mult) - right_arg = 1; - else - right_arg = 0; - } - else - right_arg = right->eval_tree_expr ( mesh_i, mesh_j ); - + left_arg = left->eval ( mesh_i, mesh_j ); + right_arg = right->eval ( mesh_i, mesh_j ); switch ( infix_op->type ) { @@ -230,10 +221,10 @@ GenExpr * GenExpr::const_to_expr ( float val ) term.constant = val; - if ( ( val_expr = new ValExpr ( CONSTANT_TERM_T, &term ) ) == NULL ) + if ( ( val_expr = ValExpr::create( CONSTANT_TERM_T, &term ) ) == NULL ) return NULL; - gen_expr = new GenExpr ( VAL_T, ( void* ) val_expr ); + gen_expr = new GenExpr ( VAL_T, val_expr ); if ( gen_expr == NULL ) { @@ -269,10 +260,10 @@ GenExpr * GenExpr::param_to_expr ( Param * param ) term.param = param; - if ( ( val_expr = new ValExpr ( PARAM_TERM_T, &term ) ) == NULL ) + if ( ( val_expr = ValExpr::create( PARAM_TERM_T, &term ) ) == NULL ) return NULL; - if ( ( gen_expr = new GenExpr ( VAL_T, ( void* ) val_expr ) ) == NULL ) + if ( ( gen_expr = new GenExpr ( VAL_T, val_expr ) ) == NULL ) { delete val_expr; return NULL; @@ -296,7 +287,7 @@ GenExpr * GenExpr::prefun_to_expr ( float ( *func_ptr ) ( void * ), GenExpr ** e prefun_expr->func_ptr = ( float ( * ) ( void* ) ) func_ptr; prefun_expr->expr_list = expr_list; - gen_expr = new GenExpr ( PREFUN_T, ( void* ) prefun_expr ); + gen_expr = new GenExpr ( PREFUN_T, prefun_expr ); if ( gen_expr == NULL ) delete prefun_expr; @@ -305,7 +296,7 @@ GenExpr * GenExpr::prefun_to_expr ( float ( *func_ptr ) ( void * ), GenExpr ** e } /* Creates a new tree expression */ -TreeExpr::TreeExpr ( InfixOp * _infix_op, GenExpr * _gen_expr, TreeExpr * _left, TreeExpr * _right ) : +TreeExpr::TreeExpr ( InfixOp * _infix_op, Expr * _gen_expr, TreeExpr * _left, TreeExpr * _right ) : infix_op ( _infix_op ), gen_expr ( _gen_expr ), left ( _left ), right ( _right ) {} @@ -313,33 +304,31 @@ TreeExpr::TreeExpr ( InfixOp * _infix_op, GenExpr * _gen_expr, TreeExpr * _left, /* Creates a new value expression */ ValExpr::ValExpr ( int _type, Term * _term ) :type ( _type ) { - - - //val_expr->type = _type; term.constant = _term->constant; term.param = _term->param; +} - //return val_expr; +ValExpr *ValExpr::create ( int _type , Term * _term ) +{ + if (_type == CONSTANT_TERM_T) + return new ConstantExpr( _type, _term ); + else + return new ParameterExpr( _type, _term ); } /* Creates a new general expression */ -GenExpr::GenExpr ( int _type, void * _item ) :type ( _type ), item ( _item ) {} +GenExpr::GenExpr ( int _type, Expr * _item ) :type ( _type ), item ( _item ) {} /* Frees a general expression */ GenExpr::~GenExpr() { - switch ( type ) { case VAL_T: - delete ( ( ValExpr* ) item ); - break; case PREFUN_T: - delete ( ( PrefunExpr* ) item ); - break; case TREE_T: - delete ( ( TreeExpr* ) item ); + delete item; break; } } diff --git a/src/libprojectM/MilkdropPresetFactory/Expr.hpp b/src/libprojectM/MilkdropPresetFactory/Expr.hpp index b732531af..664c8512c 100755 --- a/src/libprojectM/MilkdropPresetFactory/Expr.hpp +++ b/src/libprojectM/MilkdropPresetFactory/Expr.hpp @@ -58,18 +58,27 @@ public: Term() { this->constant = 0; this->param = 0; } }; + +class Expr +{ +public: + virtual ~Expr() {}; + virtual bool isConstant(int mesh_i, int mesh_j) { return false; }; + virtual float eval(int mesh_i, int mesh_j) = 0; +}; /* General Expression Type */ -class GenExpr +class GenExpr : public Expr { public: int type; - void * item; + Expr * item; ~GenExpr(); - GenExpr( int type, void *item ); - float eval_gen_expr(int mesh_i, int mesh_j); + GenExpr( int type, Expr *item ); + float eval(int mesh_i, int mesh_j); + float eval_gen_expr(int mesh_i, int mesh_j) { return eval(mesh_i, mesh_j); } static GenExpr *const_to_expr( float val ); static GenExpr *param_to_expr( Param *param ); @@ -77,35 +86,41 @@ public: }; /* Value expression, contains a term union */ -class ValExpr +class ValExpr : public Expr { +protected: + ValExpr( int type, Term *term ); public: int type; Term term; + static ValExpr *create( int type, Term *term ); ~ValExpr(); - ValExpr( int type, Term *term ); - float eval_val_expr(int mesh_i, int mesh_j); + float eval_val_expr(int mesh_i, int mesh_j) { return eval(mesh_i, mesh_j); } }; /* A binary expression tree ordered by operator precedence */ -class TreeExpr +class TreeExpr : public Expr { +private: + TreeExpr( InfixOp *infix_op, Expr *gen_expr, + TreeExpr *left, TreeExpr *right ); public: + static TreeExpr *create( InfixOp *infix_op, Expr *gen_expr, + TreeExpr *left, TreeExpr *right ); InfixOp * infix_op; /* null if leaf */ - GenExpr * gen_expr; + Expr * gen_expr; TreeExpr *left, *right; ~TreeExpr(); - TreeExpr( InfixOp *infix_op, GenExpr *gen_expr, - TreeExpr *left, TreeExpr *right ); - float eval_tree_expr(int mesh_i, int mesh_j); + float eval(int mesh_i, int mesh_j); + float eval_tree_expr(int mesh_i, int mesh_j) { return eval(mesh_i, mesh_j); } }; /* A function expression in prefix form */ -class PrefunExpr +class PrefunExpr : public Expr { public: float (*func_ptr)(void*); @@ -115,8 +130,8 @@ public: ~PrefunExpr(); /* Evaluates functions in prefix form */ - float eval_prefun_expr(int mesh_i, int mesh_j); - + float eval(int mesh_i, int mesh_j); + float eval_prefun_expr(int mesh_i, int mesh_j) { return eval(mesh_i, mesh_j); } }; #endif /** _EXPR_H */ diff --git a/src/libprojectM/MilkdropPresetFactory/Parser.cpp b/src/libprojectM/MilkdropPresetFactory/Parser.cpp index bf7c0f985..692d200c0 100755 --- a/src/libprojectM/MilkdropPresetFactory/Parser.cpp +++ b/src/libprojectM/MilkdropPresetFactory/Parser.cpp @@ -999,7 +999,7 @@ TreeExpr * Parser::insert_infix_op(InfixOp * infix_op, TreeExpr **root) if (*root == NULL) { - new_root = new TreeExpr(infix_op, NULL, NULL, NULL); + new_root = TreeExpr::create(infix_op, NULL, NULL, NULL); *root = new_root; return new_root; } @@ -1009,7 +1009,7 @@ TreeExpr * Parser::insert_infix_op(InfixOp * infix_op, TreeExpr **root) if ((*root)->infix_op == NULL) { - new_root = new TreeExpr(infix_op, NULL, *root, NULL); + new_root = TreeExpr::create(infix_op, NULL, *root, NULL); (*root) = new_root; return new_root; } @@ -1020,7 +1020,7 @@ TreeExpr * Parser::insert_infix_op(InfixOp * infix_op, TreeExpr **root) if (infix_op->precedence >= (*root)->infix_op->precedence) { - new_root = new TreeExpr(infix_op, NULL, *root, NULL); + new_root = TreeExpr::create(infix_op, NULL, *root, NULL); (*root) = new_root; return new_root; } @@ -1053,7 +1053,7 @@ TreeExpr * Parser::insert_gen_expr(GenExpr * gen_expr, TreeExpr ** root) if (*root == NULL) { - new_root = new TreeExpr(NULL, gen_expr, NULL, NULL); + new_root = TreeExpr::create(NULL, gen_expr, NULL, NULL); *root = new_root; return new_root; } @@ -1085,7 +1085,7 @@ int Parser::insert_gen_rec(GenExpr * gen_expr, TreeExpr * root) if ((root->left == NULL) && (root->infix_op != NULL)) { - root->left = new TreeExpr(NULL, gen_expr, NULL, NULL); + root->left = TreeExpr::create(NULL, gen_expr, NULL, NULL); return PROJECTM_SUCCESS; } @@ -1095,7 +1095,7 @@ int Parser::insert_gen_rec(GenExpr * gen_expr, TreeExpr * root) if ((root->right == NULL) && (root->infix_op != NULL)) { - root->right = new TreeExpr(NULL, gen_expr, NULL, NULL); + root->right = TreeExpr::create(NULL, gen_expr, NULL, NULL); return PROJECTM_SUCCESS; } @@ -1131,14 +1131,14 @@ int Parser::insert_infix_rec(InfixOp * infix_op, TreeExpr * root) I don't think this will ever happen */ if (root->left == NULL) { - root->left = new TreeExpr(infix_op, NULL, root->left, NULL); + root->left = TreeExpr::create(infix_op, NULL, root->left, NULL); return PROJECTM_SUCCESS; } /* Right tree is empty, attach this operator to it */ if (root->right == NULL) { - root->right = new TreeExpr(infix_op, NULL, root->right, NULL); + root->right = TreeExpr::create(infix_op, NULL, root->right, NULL); return PROJECTM_SUCCESS; } @@ -1151,7 +1151,7 @@ int Parser::insert_infix_rec(InfixOp * infix_op, TreeExpr * root) if (root->right->infix_op == NULL) { - root->right = new TreeExpr(infix_op, NULL, root->right, NULL); + root->right = TreeExpr::create(infix_op, NULL, root->right, NULL); return PROJECTM_SUCCESS; } @@ -1162,7 +1162,7 @@ int Parser::insert_infix_rec(InfixOp * infix_op, TreeExpr * root) /* Otherwise, insert the operator here */ - root->right = new TreeExpr(infix_op, NULL, root->right, NULL); + root->right = TreeExpr::create(infix_op, NULL, root->right, NULL); return PROJECTM_SUCCESS; } @@ -1212,7 +1212,7 @@ GenExpr * Parser::parse_infix_op(std::istream & fs, token_t token, TreeExpr * t case tRPr: case tComma: if (PARSE_DEBUG) printf("parse_infix_op: terminal found (LINE %d)\n", line_count); - gen_expr = new GenExpr(TREE_T, (void*)tree_expr); + gen_expr = new GenExpr(TREE_T, tree_expr); assert(gen_expr); return gen_expr; default: From c8e0b93574abec5e21101d0f22304cf0d1e1b8d7 Mon Sep 17 00:00:00 2001 From: Matthew Bellew Date: Wed, 9 May 2018 08:43:05 -0700 Subject: [PATCH 09/16] kill GenExpr --- .../MilkdropPresetFactory/CustomWave.cpp | 2 +- .../MilkdropPresetFactory/CustomWave.hpp | 4 +- .../MilkdropPresetFactory/Eval.hpp | 16 +- .../MilkdropPresetFactory/Expr.cpp | 148 +++++------------- .../MilkdropPresetFactory/Expr.hpp | 16 +- .../MilkdropPresetFactory/MilkdropPreset.cpp | 2 +- .../MilkdropPresetFactory/MilkdropPreset.hpp | 2 +- .../MilkdropPresetFactory/Parser.cpp | 54 +++---- .../MilkdropPresetFactory/Parser.hpp | 14 +- .../MilkdropPresetFactory/PerFrameEqn.cpp | 6 +- .../MilkdropPresetFactory/PerFrameEqn.hpp | 6 +- .../MilkdropPresetFactory/PerPixelEqn.cpp | 8 +- .../MilkdropPresetFactory/PerPixelEqn.hpp | 6 +- .../MilkdropPresetFactory/PerPointEqn.cpp | 9 +- .../MilkdropPresetFactory/PerPointEqn.hpp | 6 +- 15 files changed, 114 insertions(+), 185 deletions(-) diff --git a/src/libprojectM/MilkdropPresetFactory/CustomWave.cpp b/src/libprojectM/MilkdropPresetFactory/CustomWave.cpp index 935cea745..c0cc8fbfd 100755 --- a/src/libprojectM/MilkdropPresetFactory/CustomWave.cpp +++ b/src/libprojectM/MilkdropPresetFactory/CustomWave.cpp @@ -450,7 +450,7 @@ CustomWave::~CustomWave() // Comments: index is not passed, so we assume monotonic increment by 1 is ok here -int CustomWave::add_per_point_eqn(char * name, GenExpr * gen_expr) +int CustomWave::add_per_point_eqn(char * name, Expr * gen_expr) { PerPointEqn * per_point_eqn; diff --git a/src/libprojectM/MilkdropPresetFactory/CustomWave.hpp b/src/libprojectM/MilkdropPresetFactory/CustomWave.hpp index a951fedeb..f1df5aafa 100755 --- a/src/libprojectM/MilkdropPresetFactory/CustomWave.hpp +++ b/src/libprojectM/MilkdropPresetFactory/CustomWave.hpp @@ -32,7 +32,7 @@ #define CUSTOM_WAVE_DEBUG 0 class CustomWave; -class GenExpr; +class Expr; class PerPointEqn; class Preset; @@ -115,7 +115,7 @@ public: int per_frame_eqn_string_index; int per_frame_init_eqn_string_index; - int add_per_point_eqn(char * name, GenExpr * gen_expr); + int add_per_point_eqn(char * name, Expr * gen_expr); void evalCustomWaveInitConditions(Preset *preset); diff --git a/src/libprojectM/MilkdropPresetFactory/Eval.hpp b/src/libprojectM/MilkdropPresetFactory/Eval.hpp index 70da02546..327145102 100755 --- a/src/libprojectM/MilkdropPresetFactory/Eval.hpp +++ b/src/libprojectM/MilkdropPresetFactory/Eval.hpp @@ -69,15 +69,15 @@ public: *infix_negative, *infix_positive; - float eval_gen_expr(GenExpr * gen_expr); - inline GenExpr * opt_gen_expr(GenExpr * gen_expr, int ** param_list); + float eval_gen_expr(Expr * gen_expr); + inline Expr * opt_gen_expr(Expr * gen_expr, int ** param_list); - GenExpr * const_to_expr(float val); - GenExpr * param_to_expr(Param * param); - GenExpr * prefun_to_expr(float (*func_ptr)(), GenExpr ** expr_list, int num_args); + Expr * const_to_expr(float val); + Expr * param_to_expr(Param * param); + Expr * prefun_to_expr(float (*func_ptr)(), Expr ** expr_list, int num_args); - static TreeExpr * new_tree_expr(InfixOp * infix_op, GenExpr * gen_expr, TreeExpr * left, TreeExpr * right); - static GenExpr * new_gen_expr(int type, void * item); + static TreeExpr * new_tree_expr(InfixOp * infix_op, Expr * gen_expr, TreeExpr * left, TreeExpr * right); + static Expr * new_gen_expr(int type, void * item); static ValExpr * new_val_expr(int type, Term *term); static InfixOp * new_infix_op(int type, int precedence); @@ -85,7 +85,7 @@ public: static int destroy_infix_ops(); void reset_engine_vars(); - GenExpr * clone_gen_expr(GenExpr * gen_expr); + Expr * clone_gen_expr(Expr * gen_expr); TreeExpr * clone_tree_expr(TreeExpr * tree_expr); ValExpr * clone_val_expr(ValExpr * val_expr); PrefunExpr * clone_prefun_expr(PrefunExpr * prefun_expr); diff --git a/src/libprojectM/MilkdropPresetFactory/Expr.cpp b/src/libprojectM/MilkdropPresetFactory/Expr.cpp index 27467a799..c1ed4c5ac 100755 --- a/src/libprojectM/MilkdropPresetFactory/Expr.cpp +++ b/src/libprojectM/MilkdropPresetFactory/Expr.cpp @@ -27,21 +27,6 @@ #include #include "Eval.hpp" -float GenExpr::eval ( int mesh_i, int mesh_j ) -{ - if (item == 0) - return EVAL_ERROR; - - switch ( this->type ) - { /* N.B. this code is responsible for 75% of all CPU time. making it faster will help a lot. */ - case VAL_T: - case PREFUN_T: - case TREE_T: - return item->eval( mesh_i, mesh_j ); - default: - return EVAL_ERROR; - } -} /* Evaluates functions in prefix form */ float PrefunExpr::eval ( int mesh_i, int mesh_j ) @@ -51,7 +36,7 @@ float PrefunExpr::eval ( int mesh_i, int mesh_j ) float * arg_list; float * argp; - GenExpr **expr_listp = expr_list; + Expr **expr_listp = expr_list; if (this->num_args > 10) { @@ -68,7 +53,7 @@ float PrefunExpr::eval ( int mesh_i, int mesh_j ) /* Evaluate each argument before calling the function itself */ for ( int i = 0; i < num_args; i++ ) { - *(argp++) = (*(expr_listp++))->eval_gen_expr ( mesh_i, mesh_j ); + *(argp++) = (*(expr_listp++))->eval ( mesh_i, mesh_j ); //printf("numargs %x", arg_list[i]); } /* Now we call the function, passing a list of @@ -100,47 +85,47 @@ public: /* Evaluates a value expression */ float ParameterExpr::eval ( int mesh_i, int mesh_j ) +{ + switch ( term.param->type ) { - switch ( term.param->type ) - { - case P_TYPE_BOOL: + case P_TYPE_BOOL: - return ( float ) ( * ( ( bool* ) ( term.param->engine_val ) ) ); - case P_TYPE_INT: + return ( float ) ( * ( ( bool* ) ( term.param->engine_val ) ) ); + case P_TYPE_INT: - return ( float ) ( * ( ( int* ) ( term.param->engine_val ) ) ); - case P_TYPE_DOUBLE: + return ( float ) ( * ( ( int* ) ( term.param->engine_val ) ) ); + case P_TYPE_DOUBLE: - if ( term.param->matrix_flag | ( term.param->flags & P_FLAG_ALWAYS_MATRIX ) ) + if ( term.param->matrix_flag | ( term.param->flags & P_FLAG_ALWAYS_MATRIX ) ) + { + + /* Sanity check the matrix is there... */ + assert ( term.param->matrix != NULL ); + + /// @slow boolean check could be expensive in this critical (and common) step of evaluation + if ( mesh_i >= 0 ) { - - /* Sanity check the matrix is there... */ - assert ( term.param->matrix != NULL ); - - /// @slow boolean check could be expensive in this critical (and common) step of evaluation - if ( mesh_i >= 0 ) + if ( mesh_j >= 0 ) { - if ( mesh_j >= 0 ) - { - return ( ( ( float** ) term.param->matrix ) [mesh_i][mesh_j] ); - } - else - { - return ( ( ( float* ) term.param->matrix ) [mesh_i] ); - } + return ( ( ( float** ) term.param->matrix ) [mesh_i][mesh_j] ); + } + else + { + return ( ( ( float* ) term.param->matrix ) [mesh_i] ); } - //assert(mesh_i >=0); } - //std::cout << term.param->name << ": " << (*((float*)term.param->engine_val)) << std::endl; - return * ( ( float* ) ( term.param->engine_val ) ); - default: - return EVAL_ERROR; - } + //assert(mesh_i >=0); + } + //std::cout << term.param->name << ": " << (*((float*)term.param->engine_val)) << std::endl; + return * ( ( float* ) ( term.param->engine_val ) ); + default: + return EVAL_ERROR; } +} /* This could be optimized a lot more if we could return an Expr instead of a TreeExpr */ @@ -151,14 +136,14 @@ TreeExpr * TreeExpr::create( InfixOp * _infix_op, Expr * _gen_expr, TreeExpr * _ if (_infix_op == NULL) { if (_gen_expr == NULL) - _gen_expr = GenExpr::const_to_expr(0.0f); + _gen_expr = Expr::const_to_expr(0.0f); } else { if (_left == NULL) - _left = new TreeExpr(NULL, GenExpr::const_to_expr(defautFloat), NULL, NULL); + _left = new TreeExpr(NULL, Expr::const_to_expr(defautFloat), NULL, NULL); if (_right == NULL) - _right = new TreeExpr(NULL, GenExpr::const_to_expr(defautFloat), NULL, NULL); + _right = new TreeExpr(NULL, Expr::const_to_expr(defautFloat), NULL, NULL); } return new TreeExpr( _infix_op, _gen_expr, _left, _right); } @@ -212,33 +197,16 @@ float TreeExpr::eval ( int mesh_i, int mesh_j ) } /* Converts a float value to a general expression */ -GenExpr * GenExpr::const_to_expr ( float val ) +Expr * Expr::const_to_expr ( float val ) { - - GenExpr * gen_expr; - ValExpr * val_expr; Term term; - term.constant = val; - - if ( ( val_expr = ValExpr::create( CONSTANT_TERM_T, &term ) ) == NULL ) - return NULL; - - gen_expr = new GenExpr ( VAL_T, val_expr ); - - if ( gen_expr == NULL ) - { - delete val_expr; - } - - return gen_expr; + return ValExpr::create( CONSTANT_TERM_T, &term ); } /* Converts a regular parameter to an expression */ -GenExpr * GenExpr::param_to_expr ( Param * param ) +Expr * Expr::param_to_expr ( Param * param ) { - - GenExpr * gen_expr = NULL; ValExpr * val_expr = NULL; Term term; @@ -260,39 +228,19 @@ GenExpr * GenExpr::param_to_expr ( Param * param ) term.param = param; - if ( ( val_expr = ValExpr::create( PARAM_TERM_T, &term ) ) == NULL ) - return NULL; - - if ( ( gen_expr = new GenExpr ( VAL_T, val_expr ) ) == NULL ) - { - delete val_expr; - return NULL; - } - return gen_expr; + return ValExpr::create( PARAM_TERM_T, &term ); } /* Converts a prefix function to an expression */ -GenExpr * GenExpr::prefun_to_expr ( float ( *func_ptr ) ( void * ), GenExpr ** expr_list, int num_args ) +Expr * Expr::prefun_to_expr ( float ( *func_ptr ) ( void * ), Expr ** expr_list, int num_args ) { - - GenExpr * gen_expr; PrefunExpr * prefun_expr; prefun_expr = new PrefunExpr(); - - if ( prefun_expr == NULL ) - return NULL; - prefun_expr->num_args = num_args; prefun_expr->func_ptr = ( float ( * ) ( void* ) ) func_ptr; prefun_expr->expr_list = expr_list; - - gen_expr = new GenExpr ( PREFUN_T, prefun_expr ); - - if ( gen_expr == NULL ) - delete prefun_expr; - - return gen_expr; + return prefun_expr; } /* Creates a new tree expression */ @@ -316,27 +264,9 @@ ValExpr *ValExpr::create ( int _type , Term * _term ) return new ParameterExpr( _type, _term ); } -/* Creates a new general expression */ - -GenExpr::GenExpr ( int _type, Expr * _item ) :type ( _type ), item ( _item ) {} - -/* Frees a general expression */ -GenExpr::~GenExpr() -{ - switch ( type ) - { - case VAL_T: - case PREFUN_T: - case TREE_T: - delete item; - break; - } -} - /* Frees a function in prefix notation */ PrefunExpr::~PrefunExpr() { - int i; /* Free every element in expression list */ diff --git a/src/libprojectM/MilkdropPresetFactory/Expr.hpp b/src/libprojectM/MilkdropPresetFactory/Expr.hpp index 664c8512c..2d0b289b6 100755 --- a/src/libprojectM/MilkdropPresetFactory/Expr.hpp +++ b/src/libprojectM/MilkdropPresetFactory/Expr.hpp @@ -65,10 +65,14 @@ public: virtual ~Expr() {}; virtual bool isConstant(int mesh_i, int mesh_j) { return false; }; virtual float eval(int mesh_i, int mesh_j) = 0; + + static Expr *const_to_expr( float val ); + static Expr *param_to_expr( Param *param ); + static Expr *prefun_to_expr( float (*func_ptr)(void *), Expr **expr_list, int num_args ); }; -/* General Expression Type */ -class GenExpr : public Expr +/* General Expression Type +class GenExpr : public GenExpr { public: int type; @@ -79,11 +83,7 @@ public: GenExpr( int type, Expr *item ); float eval(int mesh_i, int mesh_j); float eval_gen_expr(int mesh_i, int mesh_j) { return eval(mesh_i, mesh_j); } - - static GenExpr *const_to_expr( float val ); - static GenExpr *param_to_expr( Param *param ); - static GenExpr *prefun_to_expr( float (*func_ptr)(void *), GenExpr **expr_list, int num_args ); -}; + }; */ /* Value expression, contains a term union */ class ValExpr : public Expr @@ -125,7 +125,7 @@ class PrefunExpr : public Expr public: float (*func_ptr)(void*); int num_args; - GenExpr **expr_list; + Expr **expr_list; PrefunExpr(); ~PrefunExpr(); diff --git a/src/libprojectM/MilkdropPresetFactory/MilkdropPreset.cpp b/src/libprojectM/MilkdropPresetFactory/MilkdropPreset.cpp index 304ce7039..bd94f6f46 100755 --- a/src/libprojectM/MilkdropPresetFactory/MilkdropPreset.cpp +++ b/src/libprojectM/MilkdropPresetFactory/MilkdropPreset.cpp @@ -103,7 +103,7 @@ MilkdropPreset::~MilkdropPreset() /* Adds a per pixel equation according to its string name. This will be used only by the parser */ -int MilkdropPreset::add_per_pixel_eqn(char * name, GenExpr * gen_expr) +int MilkdropPreset::add_per_pixel_eqn(char * name, Expr * gen_expr) { PerPixelEqn * per_pixel_eqn = NULL; diff --git a/src/libprojectM/MilkdropPresetFactory/MilkdropPreset.hpp b/src/libprojectM/MilkdropPresetFactory/MilkdropPreset.hpp index 89fc7f89a..87cb0ee89 100644 --- a/src/libprojectM/MilkdropPresetFactory/MilkdropPreset.hpp +++ b/src/libprojectM/MilkdropPresetFactory/MilkdropPreset.hpp @@ -95,7 +95,7 @@ public: /// Used by parser /// @bug refactor - int add_per_pixel_eqn( char *name, GenExpr *gen_expr ); + int add_per_pixel_eqn( char *name, Expr *gen_expr ); /// Accessor method to retrieve the absolute file path of the loaded MilkdropPreset /// \returns a file path string diff --git a/src/libprojectM/MilkdropPresetFactory/Parser.cpp b/src/libprojectM/MilkdropPresetFactory/Parser.cpp index 692d200c0..c089add16 100755 --- a/src/libprojectM/MilkdropPresetFactory/Parser.cpp +++ b/src/libprojectM/MilkdropPresetFactory/Parser.cpp @@ -251,15 +251,15 @@ token_t Parser::parseToken(std::istream & fs, char * string) /* Parse input in the form of "exp, exp, exp, ...)" Returns a general expression list */ -GenExpr **Parser::parse_prefix_args(std::istream & fs, int num_args, MilkdropPreset * preset) +Expr **Parser::parse_prefix_args(std::istream & fs, int num_args, MilkdropPreset * preset) { int i, j; - GenExpr ** expr_list; /* List of arguments to function */ - GenExpr * gen_expr; + Expr ** expr_list; /* List of arguments to function */ + Expr * gen_expr; /* Malloc the expression list */ - expr_list = (GenExpr**)wipemalloc(sizeof(GenExpr*)*num_args); + expr_list = (Expr**)wipemalloc(sizeof(Expr*)*num_args); /* Malloc failed */ if (expr_list == NULL) @@ -331,7 +331,7 @@ int Parser::parse_per_pixel_eqn(std::istream & fs, MilkdropPreset * preset, cha char string[MAX_TOKEN_SIZE]; - GenExpr * gen_expr; + Expr * gen_expr; if (init_string != 0) @@ -717,17 +717,17 @@ int Parser::parse_line(std::istream & fs, MilkdropPreset * preset) /* Parses a general expression, this function is the meat of the parser */ -GenExpr * Parser::parse_gen_expr ( std::istream & fs, TreeExpr * tree_expr, MilkdropPreset * preset) +Expr * Parser::parse_gen_expr ( std::istream & fs, TreeExpr * tree_expr, MilkdropPreset * preset) { int i; char string[MAX_TOKEN_SIZE]; token_t token; - GenExpr * gen_expr; + Expr * gen_expr; float val; Param * param = NULL; Func * func; - GenExpr ** expr_list; + Expr ** expr_list; switch (token = parseToken(fs,string)) { @@ -759,7 +759,7 @@ GenExpr * Parser::parse_gen_expr ( std::istream & fs, TreeExpr * tree_expr, Mil } /* Convert function to expression */ - if ((gen_expr = GenExpr::prefun_to_expr((float (*)(void *))func->func_ptr, expr_list, func->getNumArgs())) == NULL) + if ((gen_expr = Expr::prefun_to_expr((float (*)(void *))func->func_ptr, expr_list, func->getNumArgs())) == NULL) { if (PARSE_DEBUG) printf("parse_prefix_args: failed to convert prefix function to general expression (LINE %d) \n", line_count); @@ -818,7 +818,7 @@ GenExpr * Parser::parse_gen_expr ( std::istream & fs, TreeExpr * tree_expr, Mil if (PARSE_DEBUG) printf("parse_gen_expr: plus used as prefix (LINE %d)\n", line_count); /* Treat prefix plus as implict 0 preceding operator */ - gen_expr = GenExpr::const_to_expr(0); + gen_expr = Expr::const_to_expr(0); return parse_infix_op(fs, tPositive, insert_gen_expr(gen_expr, &tree_expr), preset); } @@ -829,7 +829,7 @@ GenExpr * Parser::parse_gen_expr ( std::istream & fs, TreeExpr * tree_expr, Mil { /* Use the negative infix operator, but first add an implicit zero to the operator tree */ - gen_expr = GenExpr::const_to_expr(0); + gen_expr = Expr::const_to_expr(0); //return parse_gen_expr(fs, insert_gen_expr(gen_expr, &tree_expr), preset); return parse_infix_op(fs, tNegative, insert_gen_expr(gen_expr, &tree_expr), preset); } @@ -863,7 +863,7 @@ GenExpr * Parser::parse_gen_expr ( std::istream & fs, TreeExpr * tree_expr, Mil /* CASE 1: Check if string is a just a floating point number */ if (string_to_float(string, &val) != PROJECTM_PARSE_ERROR) { - if ((gen_expr = GenExpr::const_to_expr(val)) == NULL) + if ((gen_expr = Expr::const_to_expr(val)) == NULL) { if (tree_expr) delete tree_expr; @@ -898,7 +898,7 @@ GenExpr * Parser::parse_gen_expr ( std::istream & fs, TreeExpr * tree_expr, Mil /* Convert parameter to an expression */ - if ((gen_expr = GenExpr::param_to_expr(param)) == NULL) + if ((gen_expr = Expr::param_to_expr(param)) == NULL) { delete tree_expr; return NULL; @@ -932,7 +932,7 @@ GenExpr * Parser::parse_gen_expr ( std::istream & fs, TreeExpr * tree_expr, Mil } /* Convert parameter to an expression */ - if ((gen_expr = GenExpr::param_to_expr(param)) == NULL) + if ((gen_expr = Expr::param_to_expr(param)) == NULL) { delete tree_expr; return NULL; @@ -955,7 +955,7 @@ GenExpr * Parser::parse_gen_expr ( std::istream & fs, TreeExpr * tree_expr, Mil } /* Convert parameter to an expression */ - if ((gen_expr = GenExpr::param_to_expr(param)) == NULL) + if ((gen_expr = Expr::param_to_expr(param)) == NULL) { delete tree_expr; return NULL; @@ -1035,7 +1035,7 @@ TreeExpr * Parser::insert_infix_op(InfixOp * infix_op, TreeExpr **root) } -TreeExpr * Parser::insert_gen_expr(GenExpr * gen_expr, TreeExpr ** root) +TreeExpr * Parser::insert_gen_expr(Expr * gen_expr, TreeExpr ** root) { TreeExpr * new_root; @@ -1067,7 +1067,7 @@ TreeExpr * Parser::insert_gen_expr(GenExpr * gen_expr, TreeExpr ** root) } /* A recursive helper function to insert general expression elements into the operator tree */ -int Parser::insert_gen_rec(GenExpr * gen_expr, TreeExpr * root) +int Parser::insert_gen_rec(Expr * gen_expr, TreeExpr * root) { /* Trivial Case: root is null */ @@ -1168,10 +1168,10 @@ int Parser::insert_infix_rec(InfixOp * infix_op, TreeExpr * root) } /* Parses an infix operator */ -GenExpr * Parser::parse_infix_op(std::istream & fs, token_t token, TreeExpr * tree_expr, MilkdropPreset * preset) +Expr * Parser::parse_infix_op(std::istream & fs, token_t token, TreeExpr * tree_expr, MilkdropPreset * preset) { - GenExpr * gen_expr; + Expr * gen_expr; switch (token) { @@ -1212,7 +1212,7 @@ GenExpr * Parser::parse_infix_op(std::istream & fs, token_t token, TreeExpr * t case tRPr: case tComma: if (PARSE_DEBUG) printf("parse_infix_op: terminal found (LINE %d)\n", line_count); - gen_expr = new GenExpr(TREE_T, tree_expr); + gen_expr = tree_expr; assert(gen_expr); return gen_expr; default: @@ -1358,7 +1358,7 @@ PerFrameEqn * Parser::parse_per_frame_eqn(std::istream & fs, int index, Milkdro char string[MAX_TOKEN_SIZE]; Param * param; PerFrameEqn * per_frame_eqn; - GenExpr * gen_expr; + Expr * gen_expr; if (parseToken(fs, string) != tEq) @@ -1408,7 +1408,7 @@ PerFrameEqn * Parser::parse_implicit_per_frame_eqn(std::istream & fs, char * pa Param * param; PerFrameEqn * per_frame_eqn; - GenExpr * gen_expr; + Expr * gen_expr; if (fs.fail()) return NULL; @@ -1558,7 +1558,7 @@ InitCond * Parser::parse_per_frame_init_eqn(std::istream & fs, MilkdropPreset * Param * param = NULL; CValue init_val; InitCond * init_cond; - GenExpr * gen_expr; + Expr * gen_expr; float val; token_t token; @@ -1604,7 +1604,7 @@ InitCond * Parser::parse_per_frame_init_eqn(std::istream & fs, MilkdropPreset * } /* Compute initial condition value */ - val = gen_expr->eval_gen_expr(-1,-1); + val = gen_expr->eval(-1,-1); /* Free the general expression now that we are done with it */ delete gen_expr; @@ -2192,7 +2192,7 @@ int Parser::parse_wave_helper(std::istream & fs, MilkdropPreset * preset, int { Param * param; - GenExpr * gen_expr; + Expr * gen_expr; char string[MAX_TOKEN_SIZE]; PerFrameEqn * per_frame_eqn; CustomWave * custom_wave; @@ -2458,7 +2458,7 @@ int Parser::parse_shape_per_frame_eqn(std::istream & fs, CustomShape * custom_sh { Param * param; - GenExpr * gen_expr; + Expr * gen_expr; PerFrameEqn * per_frame_eqn; char string[MAX_TOKEN_SIZE]; @@ -2520,7 +2520,7 @@ int Parser::parse_wave_per_frame_eqn(std::istream & fs, CustomWave * custom_wav { Param * param; - GenExpr * gen_expr; + Expr * gen_expr; PerFrameEqn * per_frame_eqn; char string[MAX_TOKEN_SIZE]; diff --git a/src/libprojectM/MilkdropPresetFactory/Parser.hpp b/src/libprojectM/MilkdropPresetFactory/Parser.hpp index 6c28a551e..8809192bb 100755 --- a/src/libprojectM/MilkdropPresetFactory/Parser.hpp +++ b/src/libprojectM/MilkdropPresetFactory/Parser.hpp @@ -122,7 +122,7 @@ typedef enum { class CustomShape; class CustomWave; -class GenExpr; +class Expr; class InfixOp; class PerFrameEqn; class MilkdropPreset; @@ -155,17 +155,17 @@ public: static int parse_line( std::istream & fs, MilkdropPreset * preset ); static int get_string_prefix_len(char * string); - static TreeExpr * insert_gen_expr(GenExpr * gen_expr, TreeExpr ** root); + static TreeExpr * insert_gen_expr(Expr * gen_expr, TreeExpr ** root); static TreeExpr * insert_infix_op(InfixOp * infix_op, TreeExpr ** root); static token_t parseToken(std::istream & fs, char * string); - static GenExpr ** parse_prefix_args(std::istream & fs, int num_args, MilkdropPreset * preset); - static GenExpr * parse_infix_op(std::istream & fs, token_t token, TreeExpr * tree_expr, MilkdropPreset * preset); - static GenExpr * parse_sign_arg(std::istream & fs); + static Expr ** parse_prefix_args(std::istream & fs, int num_args, MilkdropPreset * preset); + static Expr * parse_infix_op(std::istream & fs, token_t token, TreeExpr * tree_expr, MilkdropPreset * preset); + static Expr * parse_sign_arg(std::istream & fs); static int parse_float(std::istream & fs, float * float_ptr); static int parse_int(std::istream & fs, int * int_ptr); - static int insert_gen_rec(GenExpr * gen_expr, TreeExpr * root); + static int insert_gen_rec(Expr * gen_expr, TreeExpr * root); static int insert_infix_rec(InfixOp * infix_op, TreeExpr * root); - static GenExpr * parse_gen_expr(std::istream & fs, TreeExpr * tree_expr, MilkdropPreset * preset); + static Expr * parse_gen_expr(std::istream & fs, TreeExpr * tree_expr, MilkdropPreset * preset); static PerFrameEqn * parse_implicit_per_frame_eqn(std::istream & fs, char * param_string, int index, MilkdropPreset * preset); static InitCond * parse_per_frame_init_eqn(std::istream & fs, MilkdropPreset * preset, std::map * database); static int parse_wavecode_prefix(char * token, int * id, char ** var_string); diff --git a/src/libprojectM/MilkdropPresetFactory/PerFrameEqn.cpp b/src/libprojectM/MilkdropPresetFactory/PerFrameEqn.cpp index 30e23422b..4d4efb856 100755 --- a/src/libprojectM/MilkdropPresetFactory/PerFrameEqn.cpp +++ b/src/libprojectM/MilkdropPresetFactory/PerFrameEqn.cpp @@ -43,10 +43,10 @@ void PerFrameEqn::evaluate() { fflush(stdout); } - //*((float*)per_frame_eqn->param->engine_val) = eval_gen_expr(per_frame_eqn->gen_expr); + //*((float*)per_frame_eqn->param->engine_val) = eval(per_frame_eqn->gen_expr); assert(gen_expr); assert(param); - param->set_param(gen_expr->eval_gen_expr(-1,-1)); + param->set_param(gen_expr->eval(-1,-1)); if (PER_FRAME_EQN_DEBUG) printf(" = %.4f\n", *((float*)param->engine_val)); @@ -63,5 +63,5 @@ PerFrameEqn::~PerFrameEqn() { } /* Create a new per frame equation */ -PerFrameEqn::PerFrameEqn(int _index, Param * _param, GenExpr * _gen_expr) : +PerFrameEqn::PerFrameEqn(int _index, Param * _param, Expr * _gen_expr) : index(_index), param(_param), gen_expr(_gen_expr) {} diff --git a/src/libprojectM/MilkdropPresetFactory/PerFrameEqn.hpp b/src/libprojectM/MilkdropPresetFactory/PerFrameEqn.hpp index 39640805d..4b703acb8 100755 --- a/src/libprojectM/MilkdropPresetFactory/PerFrameEqn.hpp +++ b/src/libprojectM/MilkdropPresetFactory/PerFrameEqn.hpp @@ -31,7 +31,7 @@ #define PER_FRAME_EQN_DEBUG 0 -class GenExpr; +class Expr; class Param; class PerFrameEqn; @@ -39,9 +39,9 @@ class PerFrameEqn { public: int index; /* a unique id for each per frame eqn (generated by order in preset files) */ Param *param; /* parameter to be assigned a value */ - GenExpr *gen_expr; /* expression that paremeter is equal to */ + Expr *gen_expr; /* expression that paremeter is equal to */ - PerFrameEqn(int index, Param * param, GenExpr * gen_expr); + PerFrameEqn(int index, Param * param, Expr * gen_expr); ~PerFrameEqn(); /// Evaluate the per frame equation diff --git a/src/libprojectM/MilkdropPresetFactory/PerPixelEqn.cpp b/src/libprojectM/MilkdropPresetFactory/PerPixelEqn.cpp index 3f7c7bdcc..b32324596 100755 --- a/src/libprojectM/MilkdropPresetFactory/PerPixelEqn.cpp +++ b/src/libprojectM/MilkdropPresetFactory/PerPixelEqn.cpp @@ -38,7 +38,7 @@ /* Evaluates a per pixel equation */ void PerPixelEqn::evaluate(int mesh_i, int mesh_j) { - GenExpr * eqn_ptr = 0; + Expr * eqn_ptr = 0; eqn_ptr = this->gen_expr; @@ -47,13 +47,13 @@ void PerPixelEqn::evaluate(int mesh_i, int mesh_j) { if (param_matrix == 0) { assert(param->engine_val); - (*(float*)param->engine_val) = eqn_ptr->eval_gen_expr(mesh_i, mesh_j); + (*(float*)param->engine_val) = eqn_ptr->eval(mesh_i, mesh_j); } else { assert(!(eqn_ptr == NULL || param_matrix == NULL)); - param_matrix[mesh_i][mesh_j] = eqn_ptr->eval_gen_expr(mesh_i, mesh_j); + param_matrix[mesh_i][mesh_j] = eqn_ptr->eval(mesh_i, mesh_j); /* Now that this parameter has been referenced with a per pixel equation, we let the evaluator know by setting @@ -64,7 +64,7 @@ void PerPixelEqn::evaluate(int mesh_i, int mesh_j) { } } -PerPixelEqn::PerPixelEqn(int _index, Param * _param, GenExpr * _gen_expr):index(_index), param(_param), gen_expr(_gen_expr) { +PerPixelEqn::PerPixelEqn(int _index, Param * _param, Expr * _gen_expr):index(_index), param(_param), gen_expr(_gen_expr) { assert(index >= 0); assert(param != 0); diff --git a/src/libprojectM/MilkdropPresetFactory/PerPixelEqn.hpp b/src/libprojectM/MilkdropPresetFactory/PerPixelEqn.hpp index 9410d7620..e991c7c1c 100755 --- a/src/libprojectM/MilkdropPresetFactory/PerPixelEqn.hpp +++ b/src/libprojectM/MilkdropPresetFactory/PerPixelEqn.hpp @@ -43,7 +43,7 @@ #define WARP_OP 9 #define NUM_OPS 10 /* obviously, this number is dependent on the number of existing per pixel operations */ -class GenExpr; +class Expr; class Param; class PerPixelEqn; class Preset; @@ -53,13 +53,13 @@ public: int index; /* used for splay tree ordering. */ int flags; /* primarily to specify if this variable is user-defined */ Param *param; - GenExpr *gen_expr; + Expr *gen_expr; void evalPerPixelEqns( Preset *preset ); void evaluate(int mesh_i, int mesh_j); virtual ~PerPixelEqn(); - PerPixelEqn(int index, Param * param, GenExpr * gen_expr); + PerPixelEqn(int index, Param * param, Expr * gen_expr); }; diff --git a/src/libprojectM/MilkdropPresetFactory/PerPointEqn.cpp b/src/libprojectM/MilkdropPresetFactory/PerPointEqn.cpp index e921916db..60bfb0ed5 100755 --- a/src/libprojectM/MilkdropPresetFactory/PerPointEqn.cpp +++ b/src/libprojectM/MilkdropPresetFactory/PerPointEqn.cpp @@ -42,7 +42,7 @@ void PerPointEqn::evaluate(int i) { float * param_matrix; - GenExpr * eqn_ptr; + Expr * eqn_ptr; // samples = CustomWave::interface_wave->samples; @@ -51,8 +51,7 @@ void PerPointEqn::evaluate(int i) if (param->matrix == NULL) { assert(param->matrix_flag == false); - (*(float*)param->engine_val) = eqn_ptr->eval_gen_expr(i,-1); - + (*(float*)param->engine_val) = eqn_ptr->eval(i,-1); return; } @@ -62,7 +61,7 @@ void PerPointEqn::evaluate(int i) param_matrix = (float*)param->matrix; // -1 is because per points only use one dimension - param_matrix[i] = eqn_ptr->eval_gen_expr(i, -1); + param_matrix[i] = eqn_ptr->eval(i, -1); /* Now that this parameter has been referenced with a per @@ -76,7 +75,7 @@ void PerPointEqn::evaluate(int i) } -PerPointEqn::PerPointEqn(int _index, Param * _param, GenExpr * _gen_expr, int _samples): +PerPointEqn::PerPointEqn(int _index, Param * _param, Expr * _gen_expr, int _samples): index(_index), samples(_samples), param(_param), diff --git a/src/libprojectM/MilkdropPresetFactory/PerPointEqn.hpp b/src/libprojectM/MilkdropPresetFactory/PerPointEqn.hpp index 90ba5ca1c..17838a492 100755 --- a/src/libprojectM/MilkdropPresetFactory/PerPointEqn.hpp +++ b/src/libprojectM/MilkdropPresetFactory/PerPointEqn.hpp @@ -30,7 +30,7 @@ #define _PER_POINT_EQN_H class CustomWave; -class GenExpr; +class Expr; class Param; class PerPointEqn; @@ -39,10 +39,10 @@ public: int index; int samples; // the number of samples to iterate over Param *param; - GenExpr * gen_expr; + Expr * gen_expr; ~PerPointEqn(); void evaluate(int i); - PerPointEqn( int index, Param *param, GenExpr *gen_expr, int samples); + PerPointEqn( int index, Param *param, Expr *gen_expr, int samples); }; From 54b253706624ad14d90d1ce247288020c892cd13 Mon Sep 17 00:00:00 2001 From: Matthew Bellew Date: Wed, 9 May 2018 22:39:02 -0700 Subject: [PATCH 10/16] optimize() --- .../MilkdropPresetFactory/Eval.hpp | 5 +- .../MilkdropPresetFactory/Expr.cpp | 218 ++++++++++++++---- .../MilkdropPresetFactory/Expr.hpp | 54 ++--- .../MilkdropPresetFactory/Parser.cpp | 31 ++- .../MilkdropPresetFactory/Parser.hpp | 2 + 5 files changed, 216 insertions(+), 94 deletions(-) diff --git a/src/libprojectM/MilkdropPresetFactory/Eval.hpp b/src/libprojectM/MilkdropPresetFactory/Eval.hpp index 327145102..7bf67287d 100755 --- a/src/libprojectM/MilkdropPresetFactory/Eval.hpp +++ b/src/libprojectM/MilkdropPresetFactory/Eval.hpp @@ -78,16 +78,13 @@ public: static TreeExpr * new_tree_expr(InfixOp * infix_op, Expr * gen_expr, TreeExpr * left, TreeExpr * right); static Expr * new_gen_expr(int type, void * item); - static ValExpr * new_val_expr(int type, Term *term); - + static InfixOp * new_infix_op(int type, int precedence); static int init_infix_ops(); static int destroy_infix_ops(); void reset_engine_vars(); - Expr * clone_gen_expr(Expr * gen_expr); TreeExpr * clone_tree_expr(TreeExpr * tree_expr); - ValExpr * clone_val_expr(ValExpr * val_expr); PrefunExpr * clone_prefun_expr(PrefunExpr * prefun_expr); }; diff --git a/src/libprojectM/MilkdropPresetFactory/Expr.cpp b/src/libprojectM/MilkdropPresetFactory/Expr.cpp index c1ed4c5ac..8c4dc5de7 100755 --- a/src/libprojectM/MilkdropPresetFactory/Expr.cpp +++ b/src/libprojectM/MilkdropPresetFactory/Expr.cpp @@ -68,19 +68,57 @@ float PrefunExpr::eval ( int mesh_i, int mesh_j ) } -// private subclasses of ValExpr -- ConstantExpr, ParameterExpr -class ConstantExpr : public ValExpr +class ConstantExpr : public Expr { + float constant; public: - ConstantExpr( int type, Term *term ) : ValExpr(type,term) {} - float eval(int mesh_i, int mesh_j ) { return term.constant; } + ConstantExpr( float constant ) : constant(constant) {} + ConstantExpr( int type, Term *term ) : constant(term->constant) {} + bool isConstant() + { + return true; + } + float eval(int mesh_i, int mesh_j ) + { + return constant; + } + std::ostream &to_string(std::ostream &out) + { + out << constant; return out; + } }; -class ParameterExpr : public ValExpr +class ParameterExpr : public Expr +{ +protected: + Term term; +public: + ParameterExpr( int type, Term *term ) : term(*term) {} + float eval(int mesh_i, int mesh_j ); + std::ostream& to_string(std::ostream& out) + { + out << term.param->name; + return out; + } +}; + +class BoolParameterExpr : public ParameterExpr { public: - ParameterExpr( int type, Term *term ) : ValExpr(type,term) {} - float eval(int mesh_i, int mesh_j ); + BoolParameterExpr( int type, Term *term ) : ParameterExpr(type,term) {} + float eval ( int mesh_i, int mesh_j ) { return ( float ) ( * ( ( bool* ) ( term.param->engine_val ) ) ); } +}; +class IntParameterExpr : public ParameterExpr +{ +public: + IntParameterExpr( int type, Term *term ) : ParameterExpr(type,term) {} + float eval ( int mesh_i, int mesh_j ) { return ( float ) ( * ( ( int* ) ( term.param->engine_val ) ) ); } +}; +class FloatParameterExpr : public ParameterExpr +{ +public: + FloatParameterExpr( int type, Term *term ) : ParameterExpr(type,term) {} + float eval ( int mesh_i, int mesh_j ) { return ( * ( ( float* ) ( term.param->engine_val ) ) ); } }; /* Evaluates a value expression */ @@ -88,18 +126,11 @@ float ParameterExpr::eval ( int mesh_i, int mesh_j ) { switch ( term.param->type ) { - case P_TYPE_BOOL: - - return ( float ) ( * ( ( bool* ) ( term.param->engine_val ) ) ); case P_TYPE_INT: - - return ( float ) ( * ( ( int* ) ( term.param->engine_val ) ) ); case P_TYPE_DOUBLE: - - if ( term.param->matrix_flag | ( term.param->flags & P_FLAG_ALWAYS_MATRIX ) ) { @@ -131,21 +162,94 @@ float ParameterExpr::eval ( int mesh_i, int mesh_j ) /* This could be optimized a lot more if we could return an Expr instead of a TreeExpr */ TreeExpr * TreeExpr::create( InfixOp * _infix_op, Expr * _gen_expr, TreeExpr * _left, TreeExpr * _right ) { - float defautFloat = _infix_op == Eval::infix_mult ? 1.0f : 0.0f; + // float defautFloat = _infix_op == Eval::infix_mult ? 1.0f : 0.0f; - if (_infix_op == NULL) + // if (_infix_op == NULL) + // { + // if (_gen_expr == NULL) + // _gen_expr = Expr::const_to_expr(0.0f); + // } + // else + // { + // if (_left == NULL) + // _left = new TreeExpr(NULL, Expr::const_to_expr(defautFloat), NULL, NULL); + // if (_right == NULL) + // _right = new TreeExpr(NULL, Expr::const_to_expr(defautFloat), NULL, NULL); + // } + return new TreeExpr( _infix_op, _gen_expr, _left, _right); +} + +std::ostream &TreeExpr::to_string(std::ostream &out) +{ + if (NULL == infix_op) { - if (_gen_expr == NULL) - _gen_expr = Expr::const_to_expr(0.0f); + out << gen_expr; } else { - if (_left == NULL) - _left = new TreeExpr(NULL, Expr::const_to_expr(defautFloat), NULL, NULL); - if (_right == NULL) - _right = new TreeExpr(NULL, Expr::const_to_expr(defautFloat), NULL, NULL); + out << "(" << left << " "; + switch ( infix_op->type ) + { + case INFIX_ADD: + out << "+"; break; + case INFIX_MINUS: + out << "-"; break; + case INFIX_MULT: + out << "+"; break; + case INFIX_MOD: + out << "%"; break; + case INFIX_OR: + out << "|"; break; + case INFIX_AND: + out << "&"; break; + case INFIX_DIV: + out << "/"; break; + default: + out << "infix_op_ERROR"; break; + } + out << " " << right << ")"; } - return new TreeExpr( _infix_op, _gen_expr, _left, _right); + return out; +} + +/* NOTE: Parser.cpp directly manipulates TreeExpr, so it is easier to optimizer AFTER parsing + * than while building up the tree initially + */ +Expr *TreeExpr::optimize() +{ + if (infix_op == NULL) + { + Expr *opt = gen_expr->optimize(); + if (opt != gen_expr) + delete gen_expr; + gen_expr = NULL; + return opt; + } + if (left == NULL) + { + left = new TreeExpr(NULL, Expr::const_to_expr(infix_op == Eval::infix_mult ? 1.0f : 0.0f), NULL, NULL); + } + else + { + Expr *l = left->optimize(); + if (l != left) + delete left; + left = l; + } + if (right == NULL) + { + right = new TreeExpr(NULL, Expr::const_to_expr(infix_op == Eval::infix_mult ? 1.0f : 0.0f), NULL, NULL); + } + else + { + Expr *r = right->optimize(); + if (r != right) + delete right; + right = r; + } + if (left->isConstant() && right->isConstant()) + return Expr::const_to_expr(eval(0.5, 0.5)); + return this; } /* Evaluates an expression tree */ @@ -201,13 +305,12 @@ Expr * Expr::const_to_expr ( float val ) { Term term; term.constant = val; - return ValExpr::create( CONSTANT_TERM_T, &term ); + return new ConstantExpr( CONSTANT_TERM_T, &term ); } /* Converts a regular parameter to an expression */ Expr * Expr::param_to_expr ( Param * param ) { - ValExpr * val_expr = NULL; Term term; if ( param == NULL ) @@ -226,9 +329,21 @@ Expr * Expr::param_to_expr ( Param * param ) making the parser handle the case where parameters are essentially per pixel equation substitutions */ - term.param = param; - return ValExpr::create( PARAM_TERM_T, &term ); + + switch ( param->type ) + { + case P_TYPE_BOOL: + return new BoolParameterExpr( PARAM_TERM_T, &term ); + case P_TYPE_INT: + return new IntParameterExpr( PARAM_TERM_T, &term ); + case P_TYPE_DOUBLE: + // TODO are these flags constant??? can I check them now? + if ( param->matrix_flag | ( param->flags & P_FLAG_ALWAYS_MATRIX ) ) + return new ParameterExpr( PARAM_TERM_T, &term ); + return new FloatParameterExpr( PARAM_TERM_T, &term ); + } + return NULL; } /* Converts a prefix function to an expression */ @@ -249,21 +364,6 @@ TreeExpr::TreeExpr ( InfixOp * _infix_op, Expr * _gen_expr, TreeExpr * _left, Tr left ( _left ), right ( _right ) {} -/* Creates a new value expression */ -ValExpr::ValExpr ( int _type, Term * _term ) :type ( _type ) -{ - term.constant = _term->constant; - term.param = _term->param; -} - -ValExpr *ValExpr::create ( int _type , Term * _term ) -{ - if (_type == CONSTANT_TERM_T) - return new ConstantExpr( _type, _term ); - else - return new ParameterExpr( _type, _term ); -} - /* Frees a function in prefix notation */ PrefunExpr::~PrefunExpr() { @@ -277,10 +377,6 @@ PrefunExpr::~PrefunExpr() free ( expr_list ); } -/* Frees values of type VARIABLE and CONSTANT */ -ValExpr::~ValExpr() -{} - /* Frees a tree expression */ TreeExpr::~TreeExpr() { @@ -311,7 +407,6 @@ TreeExpr::~TreeExpr() /* Initializes an infix operator */ InfixOp::InfixOp ( int type, int precedence ) { - this->type = type; this->precedence = precedence; } @@ -319,3 +414,32 @@ InfixOp::InfixOp ( int type, int precedence ) PrefunExpr::PrefunExpr() {} + +Expr *PrefunExpr::optimize() +{ + bool constant_args = true; + for (int i=0 ; i < num_args ; i++) + { + Expr *orig = expr_list[i]; + expr_list[i] = orig->optimize(); + if (orig != expr_list[i]) + delete orig; + constant_args &= expr_list[i]->isConstant(); + } + // TODO most functions can be pre-evaluated if inputs are constant, but not all + return this; +} + +std::ostream& PrefunExpr::to_string(std::ostream& out) +{ + char *comma = ""; + out << "("; + for (int i=0 ; i < num_args ; i++) + { + out << comma; + out << expr_list[i]; + comma = ","; + } + out << ")"; + return out; +} diff --git a/src/libprojectM/MilkdropPresetFactory/Expr.hpp b/src/libprojectM/MilkdropPresetFactory/Expr.hpp index 2d0b289b6..01d41bb49 100755 --- a/src/libprojectM/MilkdropPresetFactory/Expr.hpp +++ b/src/libprojectM/MilkdropPresetFactory/Expr.hpp @@ -31,6 +31,7 @@ #include "dlldefs.h" #include "CValue.hpp" +#include class Param; @@ -63,42 +64,27 @@ class Expr { public: virtual ~Expr() {}; - virtual bool isConstant(int mesh_i, int mesh_j) { return false; }; + virtual Expr *optimize() { return this; }; + virtual bool isConstant() { return false; }; virtual float eval(int mesh_i, int mesh_j) = 0; + virtual std::ostream& to_string(std::ostream &out) + { + std::cout << "nyi"; return out; + } static Expr *const_to_expr( float val ); static Expr *param_to_expr( Param *param ); static Expr *prefun_to_expr( float (*func_ptr)(void *), Expr **expr_list, int num_args ); }; -/* General Expression Type -class GenExpr : public GenExpr +inline std::ostream& operator<<(std::ostream& out, Expr *expr) { -public: - int type; - Expr * item; - - ~GenExpr(); - - GenExpr( int type, Expr *item ); - float eval(int mesh_i, int mesh_j); - float eval_gen_expr(int mesh_i, int mesh_j) { return eval(mesh_i, mesh_j); } - }; */ - -/* Value expression, contains a term union */ -class ValExpr : public Expr -{ -protected: - ValExpr( int type, Term *term ); -public: - int type; - Term term; - - static ValExpr *create( int type, Term *term ); - ~ValExpr(); - - float eval_val_expr(int mesh_i, int mesh_j) { return eval(mesh_i, mesh_j); } -}; + if (NULL == expr) + out << "NULL"; + else + expr->to_string(out); + return out; +} /* A binary expression tree ordered by operator precedence */ class TreeExpr : public Expr @@ -111,12 +97,17 @@ public: TreeExpr *left, TreeExpr *right ); InfixOp * infix_op; /* null if leaf */ Expr * gen_expr; - TreeExpr *left, *right; + // NOTE: before optimize() left and right will always be TreeExpr + Expr *left, *right; + // these are for type-safe access in Parser.cpp + TreeExpr *&leftTree() { return *(TreeExpr **)&left; }; + TreeExpr *&rightTree() { return *(TreeExpr **)&right; }; ~TreeExpr(); + Expr *optimize(); float eval(int mesh_i, int mesh_j); - float eval_tree_expr(int mesh_i, int mesh_j) { return eval(mesh_i, mesh_j); } + std::ostream& to_string(std::ostream &out); }; /* A function expression in prefix form */ @@ -130,8 +121,9 @@ public: ~PrefunExpr(); /* Evaluates functions in prefix form */ + Expr *optimize(); float eval(int mesh_i, int mesh_j); - float eval_prefun_expr(int mesh_i, int mesh_j) { return eval(mesh_i, mesh_j); } + std::ostream& to_string(std::ostream &out); }; #endif /** _EXPR_H */ diff --git a/src/libprojectM/MilkdropPresetFactory/Parser.cpp b/src/libprojectM/MilkdropPresetFactory/Parser.cpp index c089add16..3859d1ba6 100755 --- a/src/libprojectM/MilkdropPresetFactory/Parser.cpp +++ b/src/libprojectM/MilkdropPresetFactory/Parser.cpp @@ -715,11 +715,9 @@ int Parser::parse_line(std::istream & fs, MilkdropPreset * preset) } - /* Parses a general expression, this function is the meat of the parser */ -Expr * Parser::parse_gen_expr ( std::istream & fs, TreeExpr * tree_expr, MilkdropPreset * preset) +Expr * Parser::_parse_gen_expr ( std::istream & fs, TreeExpr * tree_expr, MilkdropPreset * preset) { - int i; char string[MAX_TOKEN_SIZE]; token_t token; @@ -981,6 +979,15 @@ Expr * Parser::parse_gen_expr ( std::istream & fs, TreeExpr * tree_expr, Milkdr } +Expr * Parser::parse_gen_expr ( std::istream & fs, TreeExpr * tree_expr, MilkdropPreset * preset) +{ + Expr *gen_expr = _parse_gen_expr( fs, tree_expr, preset ); + //std::cout << gen_expr << std::endl; + Expr *opt = gen_expr->optimize(); + //std::cout << opt << std::endl; + return opt; +} + /* Inserts expressions into tree according to operator precedence. If root is null, a new tree is created, with infix_op as only element */ @@ -1103,8 +1110,8 @@ int Parser::insert_gen_rec(Expr * gen_expr, TreeExpr * root) this succeeds then return. If it fails, try recursing down to the right */ - if (insert_gen_rec(gen_expr, root->left) == PROJECTM_FAILURE) - return insert_gen_rec(gen_expr, root->right); + if (insert_gen_rec(gen_expr, root->leftTree()) == PROJECTM_FAILURE) + return insert_gen_rec(gen_expr, root->rightTree()); /* Impossible for control flow to reach here, but in the world of C programming, who knows... */ @@ -1131,14 +1138,14 @@ int Parser::insert_infix_rec(InfixOp * infix_op, TreeExpr * root) I don't think this will ever happen */ if (root->left == NULL) { - root->left = TreeExpr::create(infix_op, NULL, root->left, NULL); + root->left = TreeExpr::create(infix_op, NULL, root->leftTree(), NULL); return PROJECTM_SUCCESS; } /* Right tree is empty, attach this operator to it */ if (root->right == NULL) { - root->right = TreeExpr::create(infix_op, NULL, root->right, NULL); + root->right = TreeExpr::create(infix_op, NULL, root->rightTree(), NULL); return PROJECTM_SUCCESS; } @@ -1149,20 +1156,20 @@ int Parser::insert_infix_rec(InfixOp * infix_op, TreeExpr * root) then insert the expression here, attaching the old right branch to the left of the new expression */ - if (root->right->infix_op == NULL) + if (root->rightTree()->infix_op == NULL) { - root->right = TreeExpr::create(infix_op, NULL, root->right, NULL); + root->right = TreeExpr::create(infix_op, NULL, root->rightTree(), NULL); return PROJECTM_SUCCESS; } /* Traverse deeper if the inserting operator precedence is less than the the root's right operator precedence */ - if (infix_op->precedence < root->right->infix_op->precedence) - return insert_infix_rec(infix_op, root->right); + if (infix_op->precedence < root->rightTree()->infix_op->precedence) + return insert_infix_rec(infix_op, root->rightTree()); /* Otherwise, insert the operator here */ - root->right = TreeExpr::create(infix_op, NULL, root->right, NULL); + root->right = TreeExpr::create(infix_op, NULL, root->rightTree(), NULL); return PROJECTM_SUCCESS; } diff --git a/src/libprojectM/MilkdropPresetFactory/Parser.hpp b/src/libprojectM/MilkdropPresetFactory/Parser.hpp index 8809192bb..b52fede6d 100755 --- a/src/libprojectM/MilkdropPresetFactory/Parser.hpp +++ b/src/libprojectM/MilkdropPresetFactory/Parser.hpp @@ -186,6 +186,8 @@ public: static int parse_shape_per_frame_eqn(std::istream & fs, CustomShape * custom_shape, MilkdropPreset * preset); static int parse_wave_per_frame_eqn(std::istream & fs, CustomWave * custom_wave, MilkdropPreset * preset); static bool wrapsToNextLine(const std::string & str); +private: + static Expr * _parse_gen_expr(std::istream & fs, TreeExpr * tree_expr, MilkdropPreset * preset); }; #endif /** !_PARSER_H */ From 397790b95e19c200a842b94430ea9c41be1ea324 Mon Sep 17 00:00:00 2001 From: Matthew Bellew Date: Thu, 10 May 2018 14:50:37 -0700 Subject: [PATCH 11/16] ExprClass and some warning cleanup --- .../MilkdropPresetFactory/Expr.cpp | 128 +++++++++++------- .../MilkdropPresetFactory/Expr.hpp | 8 ++ 2 files changed, 89 insertions(+), 47 deletions(-) diff --git a/src/libprojectM/MilkdropPresetFactory/Expr.cpp b/src/libprojectM/MilkdropPresetFactory/Expr.cpp index 8c4dc5de7..67f3f5585 100755 --- a/src/libprojectM/MilkdropPresetFactory/Expr.cpp +++ b/src/libprojectM/MilkdropPresetFactory/Expr.cpp @@ -72,8 +72,8 @@ class ConstantExpr : public Expr { float constant; public: - ConstantExpr( float constant ) : constant(constant) {} - ConstantExpr( int type, Term *term ) : constant(term->constant) {} + ConstantExpr( float value ) : Expr(CONSTANT), constant(value) {} + ConstantExpr( int type, Term *term ) : Expr(CONSTANT), constant(term->constant) {} bool isConstant() { return true; @@ -93,7 +93,7 @@ class ParameterExpr : public Expr protected: Term term; public: - ParameterExpr( int type, Term *term ) : term(*term) {} + ParameterExpr( int _type, Term *_term ) : Expr(PARAMETER), term(*_term) {} float eval(int mesh_i, int mesh_j ); std::ostream& to_string(std::ostream& out) { @@ -105,19 +105,19 @@ public: class BoolParameterExpr : public ParameterExpr { public: - BoolParameterExpr( int type, Term *term ) : ParameterExpr(type,term) {} + BoolParameterExpr( int _type, Term *_term ) : ParameterExpr(_type,_term) {} float eval ( int mesh_i, int mesh_j ) { return ( float ) ( * ( ( bool* ) ( term.param->engine_val ) ) ); } }; class IntParameterExpr : public ParameterExpr { public: - IntParameterExpr( int type, Term *term ) : ParameterExpr(type,term) {} + IntParameterExpr( int _type, Term *_term ) : ParameterExpr(_type,_term) {} float eval ( int mesh_i, int mesh_j ) { return ( float ) ( * ( ( int* ) ( term.param->engine_val ) ) ); } }; class FloatParameterExpr : public ParameterExpr { public: - FloatParameterExpr( int type, Term *term ) : ParameterExpr(type,term) {} + FloatParameterExpr( int _type, Term *_term ) : ParameterExpr(_type,_term) {} float eval ( int mesh_i, int mesh_j ) { return ( * ( ( float* ) ( term.param->engine_val ) ) ); } }; @@ -159,23 +159,31 @@ float ParameterExpr::eval ( int mesh_i, int mesh_j ) } +class MultAndAddExpr : public Expr +{ + Expr *a, *b, *c; +public: + MultAndAddExpr(Expr *_a, Expr *_b, Expr *_c) : Expr(OTHER), + a(_a), b(_b), c(_c) + { + } + float eval(int mesh_i, int mesh_j) + { + float a_value = a->eval(mesh_i,mesh_j); + float b_value = b->eval(mesh_i,mesh_j); + float c_value = c->eval(mesh_i,mesh_j); + return a_value * b_value + c_value; + } + std::ostream &to_string(std::ostream &out) + { + out << "(" << a << " * " << b << ") + " << c; + return out; + } +}; + /* This could be optimized a lot more if we could return an Expr instead of a TreeExpr */ TreeExpr * TreeExpr::create( InfixOp * _infix_op, Expr * _gen_expr, TreeExpr * _left, TreeExpr * _right ) { - // float defautFloat = _infix_op == Eval::infix_mult ? 1.0f : 0.0f; - - // if (_infix_op == NULL) - // { - // if (_gen_expr == NULL) - // _gen_expr = Expr::const_to_expr(0.0f); - // } - // else - // { - // if (_left == NULL) - // _left = new TreeExpr(NULL, Expr::const_to_expr(defautFloat), NULL, NULL); - // if (_right == NULL) - // _right = new TreeExpr(NULL, Expr::const_to_expr(defautFloat), NULL, NULL); - // } return new TreeExpr( _infix_op, _gen_expr, _left, _right); } @@ -225,30 +233,61 @@ Expr *TreeExpr::optimize() gen_expr = NULL; return opt; } - if (left == NULL) - { - left = new TreeExpr(NULL, Expr::const_to_expr(infix_op == Eval::infix_mult ? 1.0f : 0.0f), NULL, NULL); - } - else + if (left != NULL) { Expr *l = left->optimize(); if (l != left) delete left; left = l; } - if (right == NULL) - { - right = new TreeExpr(NULL, Expr::const_to_expr(infix_op == Eval::infix_mult ? 1.0f : 0.0f), NULL, NULL); - } - else + if (right != NULL) { Expr *r = right->optimize(); if (r != right) delete right; right = r; } + if (left == NULL) + { + Expr *opt = right; + right = NULL; + return opt; + } + if (right == NULL) + { + Expr *opt = left; + left = NULL; + return opt; + } if (left->isConstant() && right->isConstant()) - return Expr::const_to_expr(eval(0.5, 0.5)); + return Expr::const_to_expr(eval(-1, -1)); + + // this is gratuitious, but a*b+c is super common, so as proof-of-concept, let's make a special Expr + if (infix_op->type == INFIX_ADD && + ((left->clazz == TREE && ((TreeExpr *)left)->infix_op->type == INFIX_MULT) || + (right->clazz == TREE && ((TreeExpr *)right)->infix_op->type == INFIX_MULT))) + { + Expr *a, *b, *c; + if (left->clazz == TREE && ((TreeExpr *)left)->infix_op->type == INFIX_MULT) + { + a = ((TreeExpr *)left)->left; + b = ((TreeExpr *)left)->right; + c = right; + ((TreeExpr *)left)->left = NULL; + ((TreeExpr *)left)->right = NULL; + right = NULL; + } + else + { + a = ((TreeExpr *)right)->left; + b = ((TreeExpr *)right)->right; + c = left; + ((TreeExpr *)right)->left = NULL; + ((TreeExpr *)right)->right = NULL; + left = NULL; + } + return new MultAndAddExpr(a,b,c); + } return this; } @@ -257,14 +296,8 @@ float TreeExpr::eval ( int mesh_i, int mesh_j ) { float left_arg, right_arg; - /* A leaf node, evaluate the general expression. If the expression is null as well, return zero */ - if ( infix_op == NULL ) - { - return gen_expr->eval( mesh_i, mesh_j ); - } - - /* Otherwise, this node is an infix operator. Evaluate - accordingly */ + /* shouldn't be null if we've called optimize() */ + assert(NULL != infix_op); left_arg = left->eval ( mesh_i, mesh_j ); right_arg = right->eval ( mesh_i, mesh_j ); @@ -360,6 +393,7 @@ Expr * Expr::prefun_to_expr ( float ( *func_ptr ) ( void * ), Expr ** expr_list, /* Creates a new tree expression */ TreeExpr::TreeExpr ( InfixOp * _infix_op, Expr * _gen_expr, TreeExpr * _left, TreeExpr * _right ) : + Expr( TREE ), infix_op ( _infix_op ), gen_expr ( _gen_expr ), left ( _left ), right ( _right ) {} @@ -405,15 +439,15 @@ TreeExpr::~TreeExpr() } /* Initializes an infix operator */ -InfixOp::InfixOp ( int type, int precedence ) +InfixOp::InfixOp ( int _type, int _precedence ) { - this->type = type; - this->precedence = precedence; + this->type = _type; + this->precedence = _precedence; } - - -PrefunExpr::PrefunExpr() {} +PrefunExpr::PrefunExpr() : Expr(FUNCTION) +{ +} Expr *PrefunExpr::optimize() { @@ -432,13 +466,13 @@ Expr *PrefunExpr::optimize() std::ostream& PrefunExpr::to_string(std::ostream& out) { - char *comma = ""; + char comma = ' '; out << "("; for (int i=0 ; i < num_args ; i++) { out << comma; out << expr_list[i]; - comma = ","; + comma = ','; } out << ")"; return out; diff --git a/src/libprojectM/MilkdropPresetFactory/Expr.hpp b/src/libprojectM/MilkdropPresetFactory/Expr.hpp index 01d41bb49..2aa5c97c2 100755 --- a/src/libprojectM/MilkdropPresetFactory/Expr.hpp +++ b/src/libprojectM/MilkdropPresetFactory/Expr.hpp @@ -60,9 +60,17 @@ public: Term() { this->constant = 0; this->param = 0; } }; + +enum ExprClass +{ + TREE, CONSTANT, PARAMETER, FUNCTION, OTHER +}; + class Expr { public: + ExprClass clazz; + Expr(ExprClass c) : clazz(c) {}; virtual ~Expr() {}; virtual Expr *optimize() { return this; }; virtual bool isConstant() { return false; }; From 0d248236e794e2f2677af1e5df2efd557112966b Mon Sep 17 00:00:00 2001 From: Matthew Bellew Date: Thu, 10 May 2018 18:47:15 -0700 Subject: [PATCH 12/16] PrefunExprOne --- src/libprojectM/MilkdropPresetFactory/Expr.cpp | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/libprojectM/MilkdropPresetFactory/Expr.cpp b/src/libprojectM/MilkdropPresetFactory/Expr.cpp index 67f3f5585..2300f4e8f 100755 --- a/src/libprojectM/MilkdropPresetFactory/Expr.cpp +++ b/src/libprojectM/MilkdropPresetFactory/Expr.cpp @@ -68,6 +68,16 @@ float PrefunExpr::eval ( int mesh_i, int mesh_j ) } +class PrefunExprOne : public PrefunExpr +{ + float eval ( int mesh_i, int mesh_j ) + { + float val = expr_list[0]->eval ( mesh_i, mesh_j ); + return (func_ptr)(&val); + } +}; + + class ConstantExpr : public Expr { float constant; @@ -383,8 +393,10 @@ Expr * Expr::param_to_expr ( Param * param ) Expr * Expr::prefun_to_expr ( float ( *func_ptr ) ( void * ), Expr ** expr_list, int num_args ) { PrefunExpr * prefun_expr; - - prefun_expr = new PrefunExpr(); + if (num_args == 1) + prefun_expr = new PrefunExprOne(); + else + prefun_expr = new PrefunExpr(); prefun_expr->num_args = num_args; prefun_expr->func_ptr = ( float ( * ) ( void* ) ) func_ptr; prefun_expr->expr_list = expr_list; From 4ac64f4642bc223dcdc40e04783143abd1add5f9 Mon Sep 17 00:00:00 2001 From: Matthew Bellew Date: Thu, 10 May 2018 19:30:28 -0700 Subject: [PATCH 13/16] TreeExprMult --- .../MilkdropPresetFactory/Expr.cpp | 52 ++++++++++++++++--- .../MilkdropPresetFactory/Expr.hpp | 2 +- 2 files changed, 47 insertions(+), 7 deletions(-) diff --git a/src/libprojectM/MilkdropPresetFactory/Expr.cpp b/src/libprojectM/MilkdropPresetFactory/Expr.cpp index 2300f4e8f..cf58b1b95 100755 --- a/src/libprojectM/MilkdropPresetFactory/Expr.cpp +++ b/src/libprojectM/MilkdropPresetFactory/Expr.cpp @@ -191,12 +191,6 @@ public: } }; -/* This could be optimized a lot more if we could return an Expr instead of a TreeExpr */ -TreeExpr * TreeExpr::create( InfixOp * _infix_op, Expr * _gen_expr, TreeExpr * _left, TreeExpr * _right ) -{ - return new TreeExpr( _infix_op, _gen_expr, _left, _right); -} - std::ostream &TreeExpr::to_string(std::ostream &out) { if (NULL == infix_op) @@ -409,6 +403,52 @@ TreeExpr::TreeExpr ( InfixOp * _infix_op, Expr * _gen_expr, TreeExpr * _left, Tr infix_op ( _infix_op ), gen_expr ( _gen_expr ), left ( _left ), right ( _right ) {} +class TreeExprAdd : public TreeExpr +{ +public: + TreeExprAdd( InfixOp * _infix_op, Expr * _gen_expr, TreeExpr * _left, TreeExpr * _right ) : + TreeExpr( _infix_op, _gen_expr, _left, _right) {} + float eval( int mesh_i, int mesh_j) + { + return left->eval(mesh_i, mesh_j) + right->eval(mesh_i, mesh_j); + } +}; + +class TreeExprMinus : public TreeExpr +{ +public: + TreeExprMinus( InfixOp * _infix_op, Expr * _gen_expr, TreeExpr * _left, TreeExpr * _right ) : + TreeExpr( _infix_op, _gen_expr, _left, _right) {} + float eval( int mesh_i, int mesh_j) + { + return left->eval(mesh_i, mesh_j) - right->eval(mesh_i, mesh_j); + } +}; + +class TreeExprMult : public TreeExpr +{ +public: + TreeExprMult( InfixOp * _infix_op, Expr * _gen_expr, TreeExpr * _left, TreeExpr * _right ) : + TreeExpr( _infix_op, _gen_expr, _left, _right) {} + float eval( int mesh_i, int mesh_j) + { + return left->eval(mesh_i, mesh_j) * right->eval(mesh_i, mesh_j); + } +}; + +TreeExpr * TreeExpr::create( InfixOp * _infix_op, Expr * _gen_expr, TreeExpr * _left, TreeExpr * _right ) +{ + if ( NULL != _infix_op ) + { + if ( _infix_op->type == INFIX_ADD ) + return new TreeExprAdd( _infix_op, _gen_expr, _left, _right); + if ( _infix_op->type == INFIX_MINUS ) + return new TreeExprMinus( _infix_op, _gen_expr, _left, _right); + if ( _infix_op->type == INFIX_MULT ) + return new TreeExprMult( _infix_op, _gen_expr, _left, _right); + } + return new TreeExpr( _infix_op, _gen_expr, _left, _right ); +} /* Frees a function in prefix notation */ PrefunExpr::~PrefunExpr() diff --git a/src/libprojectM/MilkdropPresetFactory/Expr.hpp b/src/libprojectM/MilkdropPresetFactory/Expr.hpp index 2aa5c97c2..a1eb006d4 100755 --- a/src/libprojectM/MilkdropPresetFactory/Expr.hpp +++ b/src/libprojectM/MilkdropPresetFactory/Expr.hpp @@ -97,7 +97,7 @@ inline std::ostream& operator<<(std::ostream& out, Expr *expr) /* A binary expression tree ordered by operator precedence */ class TreeExpr : public Expr { -private: +protected: TreeExpr( InfixOp *infix_op, Expr *gen_expr, TreeExpr *left, TreeExpr *right ); public: From f3ab8e29427942de9f709af100449f6cdd123b30 Mon Sep 17 00:00:00 2001 From: Matthew Bellew Date: Thu, 10 May 2018 20:06:02 -0700 Subject: [PATCH 14/16] typo --- src/libprojectM/MilkdropPresetFactory/Expr.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libprojectM/MilkdropPresetFactory/Expr.cpp b/src/libprojectM/MilkdropPresetFactory/Expr.cpp index cf58b1b95..ef8a23f12 100755 --- a/src/libprojectM/MilkdropPresetFactory/Expr.cpp +++ b/src/libprojectM/MilkdropPresetFactory/Expr.cpp @@ -207,7 +207,7 @@ std::ostream &TreeExpr::to_string(std::ostream &out) case INFIX_MINUS: out << "-"; break; case INFIX_MULT: - out << "+"; break; + out << "*"; break; case INFIX_MOD: out << "%"; break; case INFIX_OR: From f9da4b3f0b79fac3dee0f69fa721fe4156b18024 Mon Sep 17 00:00:00 2001 From: Matthew Bellew Date: Thu, 10 May 2018 21:40:37 -0700 Subject: [PATCH 15/16] NULL check --- src/libprojectM/MilkdropPresetFactory/Parser.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/libprojectM/MilkdropPresetFactory/Parser.cpp b/src/libprojectM/MilkdropPresetFactory/Parser.cpp index 3859d1ba6..47df19ce6 100755 --- a/src/libprojectM/MilkdropPresetFactory/Parser.cpp +++ b/src/libprojectM/MilkdropPresetFactory/Parser.cpp @@ -982,9 +982,11 @@ Expr * Parser::_parse_gen_expr ( std::istream & fs, TreeExpr * tree_expr, Milkd Expr * Parser::parse_gen_expr ( std::istream & fs, TreeExpr * tree_expr, MilkdropPreset * preset) { Expr *gen_expr = _parse_gen_expr( fs, tree_expr, preset ); + if (NULL == gen_expr) + return NULL; //std::cout << gen_expr << std::endl; Expr *opt = gen_expr->optimize(); - //std::cout << opt << std::endl; + //std::cout << opt << std::endl << std::endl; return opt; } From 33110d0908d28ca8386237bbd148bd2ae8755a9a Mon Sep 17 00:00:00 2001 From: Matthew Bellew Date: Sun, 13 May 2018 23:22:37 -0700 Subject: [PATCH 16/16] fix segfault on app close --- src/projectM-sdl/projectM_SDL_main.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/projectM-sdl/projectM_SDL_main.cpp b/src/projectM-sdl/projectM_SDL_main.cpp index ad506eb47..46d89be45 100644 --- a/src/projectM-sdl/projectM_SDL_main.cpp +++ b/src/projectM-sdl/projectM_SDL_main.cpp @@ -107,6 +107,7 @@ int main(int argc, char *argv[]) { last_time = SDL_GetTicks(); } + app->endAudioCapture(); delete app; return PROJECTM_SUCCESS;