Fixed a few memory management issues with presets.

Mainly two problems:
- MilkdropPresetFactory deleted a private reference-typed member in MilkdropPreset. Changed this into a plain pointer which is now checked and properly cleaned up.
- In the library interface class, projectM, the active preset pointers were not deleted before the factors, which lead to a use-after-free when the presets tried to dereference the factory pointer.
This commit is contained in:
Kai Blaschke
2021-06-09 22:36:30 +02:00
parent 147c4e0e89
commit 3f3ea5d0c4
9 changed files with 175 additions and 153 deletions

View File

@ -13,10 +13,10 @@ BuiltinParams::BuiltinParams()
{
}
BuiltinParams::BuiltinParams(PresetInputs& presetInputs, PresetOutputs& presetOutputs)
BuiltinParams::BuiltinParams(PresetInputs& presetInputs, PresetOutputs* presetOutputs)
{
presetInputs.Initialize(presetOutputs.gx, presetOutputs.gy);
presetInputs.Initialize(presetOutputs->gx, presetOutputs->gy);
int ret;
if ((ret = init_builtin_param_db(presetInputs, presetOutputs)) != PROJECTM_SUCCESS)
@ -267,7 +267,7 @@ int BuiltinParams::insert_builtin_param(Param* param)
/* Initialize the builtin parameter database.
Should only be necessary once */
int BuiltinParams::init_builtin_param_db(const PresetInputs& presetInputs, PresetOutputs& presetOutputs)
int BuiltinParams::init_builtin_param_db(const PresetInputs& presetInputs, PresetOutputs* presetOutputs)
{
if (BUILTIN_PARAMS_DEBUG)
@ -297,120 +297,121 @@ int BuiltinParams::init_builtin_param_db(const PresetInputs& presetInputs, Prese
/* Loads all builtin parameters, limits are also defined here */
int BuiltinParams::load_all_builtin_param(const PresetInputs& presetInputs, PresetOutputs& presetOutputs)
int BuiltinParams::load_all_builtin_param(const PresetInputs& presetInputs, PresetOutputs* presetOutputs)
{
load_builtin_param_float("frating", (void*) &presetOutputs.fRating, NULL, P_FLAG_NONE, 0.0, 5.0, 0.0, "");
load_builtin_param_float("frating", (void*) &presetOutputs->fRating, NULL, P_FLAG_NONE, 0.0, 5.0, 0.0, "");
// 0 will turn off all waviness in our waves... 1 seems better
load_builtin_param_float("fwavescale", (void*) &presetOutputs.wave.scale, NULL, P_FLAG_NONE, 1.0, MAX_DOUBLE_SIZE,
load_builtin_param_float("fwavescale", (void*) &presetOutputs->wave.scale, NULL, P_FLAG_NONE, 1.0, MAX_DOUBLE_SIZE,
-MAX_DOUBLE_SIZE, "");
load_builtin_param_float("gamma", (void*) &presetOutputs.fGammaAdj, NULL, P_FLAG_NONE, 0.0, MAX_DOUBLE_SIZE, 0,
load_builtin_param_float("gamma", (void*) &presetOutputs->fGammaAdj, NULL, P_FLAG_NONE, 0.0, MAX_DOUBLE_SIZE, 0,
"fGammaAdj");
load_builtin_param_float("echo_zoom", (void*) &presetOutputs.videoEcho.zoom, NULL, P_FLAG_NONE, 0.0,
load_builtin_param_float("echo_zoom", (void*) &presetOutputs->videoEcho.zoom, NULL, P_FLAG_NONE, 0.0,
MAX_DOUBLE_SIZE, 0, "fVideoEchoZoom");
load_builtin_param_float("echo_alpha", (void*) &presetOutputs.videoEcho.a, NULL, P_FLAG_NONE, 0.0, MAX_DOUBLE_SIZE,
load_builtin_param_float("echo_alpha", (void*) &presetOutputs->videoEcho.a, NULL, P_FLAG_NONE, 0.0, MAX_DOUBLE_SIZE,
0, "fvideoechoalpha");
load_builtin_param_float("wave_a", (void*) &presetOutputs.wave.a, NULL, P_FLAG_NONE, 1.0, 1.0, 0, "fwavealpha");
load_builtin_param_float("fwavesmoothing", (void*) &presetOutputs.wave.smoothing, NULL, P_FLAG_NONE, 0.0, 1.0, -1.0,
"");
load_builtin_param_float("fmodwavealphastart", (void*) &presetOutputs.wave.modOpacityStart, NULL, P_FLAG_NONE, 0.0,
1.0, -1.0, "");
load_builtin_param_float("fmodwavealphaend", (void*) &presetOutputs.wave.modOpacityEnd, NULL, P_FLAG_NONE, 0.0, 1.0,
load_builtin_param_float("wave_a", (void*) &presetOutputs->wave.a, NULL, P_FLAG_NONE, 1.0, 1.0, 0, "fwavealpha");
load_builtin_param_float("fwavesmoothing", (void*) &presetOutputs->wave.smoothing, NULL, P_FLAG_NONE, 0.0, 1.0,
-1.0, "");
load_builtin_param_float("fWarpAnimSpeed", (void*) &presetOutputs.fWarpAnimSpeed, NULL, P_FLAG_NONE, 1.0, 1.0, -1.0,
"");
load_builtin_param_float("fWarpScale", (void*) &presetOutputs.fWarpScale, NULL, P_FLAG_NONE, 1.0, 1.0, -1.0, "");
load_builtin_param_float("fmodwavealphastart", (void*) &presetOutputs->wave.modOpacityStart, NULL, P_FLAG_NONE, 0.0,
1.0, -1.0, "");
load_builtin_param_float("fmodwavealphaend", (void*) &presetOutputs->wave.modOpacityEnd, NULL, P_FLAG_NONE, 0.0,
1.0, -1.0, "");
load_builtin_param_float("fWarpAnimSpeed", (void*) &presetOutputs->fWarpAnimSpeed, NULL, P_FLAG_NONE, 1.0, 1.0,
-1.0, "");
load_builtin_param_float("fWarpScale", (void*) &presetOutputs->fWarpScale, NULL, P_FLAG_NONE, 1.0, 1.0, -1.0, "");
load_builtin_param_float("fshader", (void*) &presetOutputs.fShader, NULL, P_FLAG_NONE, 0.0, 1.0, -1.0, "");
load_builtin_param_float("fshader", (void*) &presetOutputs->fShader, NULL, P_FLAG_NONE, 0.0, 1.0, -1.0, "");
// 0.98 seems close to milkdrop2 default
load_builtin_param_float("decay", (void*) &presetOutputs.screenDecay, NULL, P_FLAG_NONE, 0.98, 1.0, 0, "fdecay");
load_builtin_param_float("decay", (void*) &presetOutputs->screenDecay, NULL, P_FLAG_NONE, 0.98, 1.0, 0, "fdecay");
load_builtin_param_int("echo_orient", (void*) &presetOutputs.videoEcho.orientation, P_FLAG_NONE, 0, 3, 0,
load_builtin_param_int("echo_orient", (void*) &presetOutputs->videoEcho.orientation, P_FLAG_NONE, 0, 3, 0,
"nVideoEchoOrientation");
load_builtin_param_int("wave_mode", (void*) &presetOutputs.wave.mode, P_FLAG_NONE, 0, 7, 0, "nwavemode");
load_builtin_param_int("wave_mode", (void*) &presetOutputs->wave.mode, P_FLAG_NONE, 0, 7, 0, "nwavemode");
load_builtin_param_bool("wave_additive", (void*) &presetOutputs.wave.additive, P_FLAG_NONE, false,
load_builtin_param_bool("wave_additive", (void*) &presetOutputs->wave.additive, P_FLAG_NONE, false,
"bAdditiveWaves");
load_builtin_param_bool("bmodwavealphabyvolume", (void*) &presetOutputs.wave.modulateAlphaByVolume, P_FLAG_NONE,
load_builtin_param_bool("bmodwavealphabyvolume", (void*) &presetOutputs->wave.modulateAlphaByVolume, P_FLAG_NONE,
false, "");
load_builtin_param_bool("wave_brighten", (void*) &presetOutputs.wave.maximizeColors, P_FLAG_NONE, false,
load_builtin_param_bool("wave_brighten", (void*) &presetOutputs->wave.maximizeColors, P_FLAG_NONE, false,
"bMaximizeWaveColor");
load_builtin_param_bool("wrap", (void*) &presetOutputs.textureWrap, P_FLAG_NONE, true, "btexwrap");
load_builtin_param_bool("darken_center", (void*) &presetOutputs.bDarkenCenter, P_FLAG_NONE, false, "bdarkencenter");
load_builtin_param_bool("bredbluestereo", (void*) &presetOutputs.bRedBlueStereo, P_FLAG_NONE, false, "");
load_builtin_param_bool("brighten", (void*) &presetOutputs.bBrighten, P_FLAG_NONE, false, "bbrighten");
load_builtin_param_bool("darken", (void*) &presetOutputs.bDarken, P_FLAG_NONE, false, "bdarken");
load_builtin_param_bool("solarize", (void*) &presetOutputs.bSolarize, P_FLAG_NONE, false, "bsolarize");
load_builtin_param_bool("invert", (void*) &presetOutputs.bInvert, P_FLAG_NONE, false, "binvert");
load_builtin_param_bool("bmotionvectorson", (void*) &presetOutputs.bMotionVectorsOn, P_FLAG_NONE, false, "");
load_builtin_param_bool("wave_dots", (void*) &presetOutputs.wave.dots, P_FLAG_NONE, false, "bwavedots");
load_builtin_param_bool("wave_thick", (void*) &presetOutputs.wave.thick, P_FLAG_NONE, false, "bwavethick");
load_builtin_param_bool("wrap", (void*) &presetOutputs->textureWrap, P_FLAG_NONE, true, "btexwrap");
load_builtin_param_bool("darken_center", (void*) &presetOutputs->bDarkenCenter, P_FLAG_NONE, false,
"bdarkencenter");
load_builtin_param_bool("bredbluestereo", (void*) &presetOutputs->bRedBlueStereo, P_FLAG_NONE, false, "");
load_builtin_param_bool("brighten", (void*) &presetOutputs->bBrighten, P_FLAG_NONE, false, "bbrighten");
load_builtin_param_bool("darken", (void*) &presetOutputs->bDarken, P_FLAG_NONE, false, "bdarken");
load_builtin_param_bool("solarize", (void*) &presetOutputs->bSolarize, P_FLAG_NONE, false, "bsolarize");
load_builtin_param_bool("invert", (void*) &presetOutputs->bInvert, P_FLAG_NONE, false, "binvert");
load_builtin_param_bool("bmotionvectorson", (void*) &presetOutputs->bMotionVectorsOn, P_FLAG_NONE, false, "");
load_builtin_param_bool("wave_dots", (void*) &presetOutputs->wave.dots, P_FLAG_NONE, false, "bwavedots");
load_builtin_param_bool("wave_thick", (void*) &presetOutputs->wave.thick, P_FLAG_NONE, false, "bwavethick");
// warp is turned on by default in milkdrop2
load_builtin_param_float("warp", (void*) &presetOutputs.warp, presetOutputs.warp_mesh,
load_builtin_param_float("warp", (void*) &presetOutputs->warp, presetOutputs->warp_mesh,
P_FLAG_PER_PIXEL | P_FLAG_NONE, 1.0, MAX_DOUBLE_SIZE, MIN_DOUBLE_SIZE, "");
// zoom=1 is the 'do nothing' value, 0 causes Inf values in PresetOutputs::PerPixelMath()
load_builtin_param_float("zoom", (void*) &presetOutputs.zoom, presetOutputs.zoom_mesh,
load_builtin_param_float("zoom", (void*) &presetOutputs->zoom, presetOutputs->zoom_mesh,
P_FLAG_PER_PIXEL | P_FLAG_NONE, 1.0, MAX_DOUBLE_SIZE, MIN_DOUBLE_SIZE, "");
load_builtin_param_float("rot", (void*) &presetOutputs.rot, presetOutputs.rot_mesh, P_FLAG_PER_PIXEL | P_FLAG_NONE,
0.0, MAX_DOUBLE_SIZE, MIN_DOUBLE_SIZE, "");
load_builtin_param_float("rot", (void*) &presetOutputs->rot, presetOutputs->rot_mesh,
P_FLAG_PER_PIXEL | P_FLAG_NONE, 0.0, MAX_DOUBLE_SIZE, MIN_DOUBLE_SIZE, "");
// zoomexp=1 is the 'do nothing' value, 0 effectively forces zoom=1
load_builtin_param_float("zoomexp", (void*) &presetOutputs.zoomexp, presetOutputs.zoomexp_mesh,
load_builtin_param_float("zoomexp", (void*) &presetOutputs->zoomexp, presetOutputs->zoomexp_mesh,
P_FLAG_PER_PIXEL | P_FLAG_NONE, 1.0, MAX_DOUBLE_SIZE, 0, "fzoomexponent");
load_builtin_param_float("cx", (void*) &presetOutputs.cx, presetOutputs.cx_mesh, P_FLAG_PER_PIXEL | P_FLAG_NONE,
load_builtin_param_float("cx", (void*) &presetOutputs->cx, presetOutputs->cx_mesh, P_FLAG_PER_PIXEL | P_FLAG_NONE,
0.0, MAX_DOUBLE_SIZE, MIN_DOUBLE_SIZE, "");
load_builtin_param_float("cy", (void*) &presetOutputs.cy, presetOutputs.cy_mesh, P_FLAG_PER_PIXEL | P_FLAG_NONE,
load_builtin_param_float("cy", (void*) &presetOutputs->cy, presetOutputs->cy_mesh, P_FLAG_PER_PIXEL | P_FLAG_NONE,
0.0, MAX_DOUBLE_SIZE, MIN_DOUBLE_SIZE, "");
load_builtin_param_float("dx", (void*) &presetOutputs.dx, presetOutputs.dx_mesh, P_FLAG_PER_PIXEL | P_FLAG_NONE,
load_builtin_param_float("dx", (void*) &presetOutputs->dx, presetOutputs->dx_mesh, P_FLAG_PER_PIXEL | P_FLAG_NONE,
0.0, MAX_DOUBLE_SIZE, MIN_DOUBLE_SIZE, "");
load_builtin_param_float("dy", (void*) &presetOutputs.dy, presetOutputs.dy_mesh, P_FLAG_PER_PIXEL | P_FLAG_NONE,
load_builtin_param_float("dy", (void*) &presetOutputs->dy, presetOutputs->dy_mesh, P_FLAG_PER_PIXEL | P_FLAG_NONE,
0.0, MAX_DOUBLE_SIZE, MIN_DOUBLE_SIZE, "");
// sx=1 and sy=1 are the 'do nothing' values, 0 causes Inf values in PresetOutputs::PerPixelMath()
load_builtin_param_float("sx", (void*) &presetOutputs.sx, presetOutputs.sx_mesh, P_FLAG_PER_PIXEL | P_FLAG_NONE,
load_builtin_param_float("sx", (void*) &presetOutputs->sx, presetOutputs->sx_mesh, P_FLAG_PER_PIXEL | P_FLAG_NONE,
1.0, MAX_DOUBLE_SIZE, MIN_DOUBLE_SIZE, "");
load_builtin_param_float("sy", (void*) &presetOutputs.sy, presetOutputs.sy_mesh, P_FLAG_PER_PIXEL | P_FLAG_NONE,
load_builtin_param_float("sy", (void*) &presetOutputs->sy, presetOutputs->sy_mesh, P_FLAG_PER_PIXEL | P_FLAG_NONE,
1.0, MAX_DOUBLE_SIZE, MIN_DOUBLE_SIZE, "");
load_builtin_param_float("b1n", (void*) &presetOutputs.blur1n, NULL, P_FLAG_NONE, 0.0, 1.0, 0.0, "");
load_builtin_param_float("b2n", (void*) &presetOutputs.blur2n, NULL, P_FLAG_NONE, 0.0, 1.0, 0.0, "");
load_builtin_param_float("b3n", (void*) &presetOutputs.blur3n, NULL, P_FLAG_NONE, 0.0, 1.0, 0.0, "");
load_builtin_param_float("b1x", (void*) &presetOutputs.blur1x, NULL, P_FLAG_NONE, 0.0, 1.0, 0.0, "");
load_builtin_param_float("b2x", (void*) &presetOutputs.blur2x, NULL, P_FLAG_NONE, 0.0, 1.0, 0.0, "");
load_builtin_param_float("b3x", (void*) &presetOutputs.blur3x, NULL, P_FLAG_NONE, 0.0, 1.0, 0.0, "");
load_builtin_param_float("b1ed", (void*) &presetOutputs.blur1ed, NULL, P_FLAG_NONE, 0.0, 1.0, 0.0, "");
load_builtin_param_float("b1n", (void*) &presetOutputs->blur1n, NULL, P_FLAG_NONE, 0.0, 1.0, 0.0, "");
load_builtin_param_float("b2n", (void*) &presetOutputs->blur2n, NULL, P_FLAG_NONE, 0.0, 1.0, 0.0, "");
load_builtin_param_float("b3n", (void*) &presetOutputs->blur3n, NULL, P_FLAG_NONE, 0.0, 1.0, 0.0, "");
load_builtin_param_float("b1x", (void*) &presetOutputs->blur1x, NULL, P_FLAG_NONE, 0.0, 1.0, 0.0, "");
load_builtin_param_float("b2x", (void*) &presetOutputs->blur2x, NULL, P_FLAG_NONE, 0.0, 1.0, 0.0, "");
load_builtin_param_float("b3x", (void*) &presetOutputs->blur3x, NULL, P_FLAG_NONE, 0.0, 1.0, 0.0, "");
load_builtin_param_float("b1ed", (void*) &presetOutputs->blur1ed, NULL, P_FLAG_NONE, 0.0, 1.0, 0.0, "");
load_builtin_param_float("wave_r", (void*) &presetOutputs.wave.r, NULL, P_FLAG_NONE, 0.0, 1.0, 0.0, "");
load_builtin_param_float("wave_g", (void*) &presetOutputs.wave.g, NULL, P_FLAG_NONE, 0.0, 1.0, 0.0, "");
load_builtin_param_float("wave_b", (void*) &presetOutputs.wave.b, NULL, P_FLAG_NONE, 0.0, 1.0, 0.0, "");
load_builtin_param_float("wave_x", (void*) &presetOutputs.wave.x, NULL, P_FLAG_NONE, 0.0, 1.0, 0.0, "");
load_builtin_param_float("wave_y", (void*) &presetOutputs.wave.y, NULL, P_FLAG_NONE, 0.0, 1.0, 0.0, "");
load_builtin_param_float("wave_mystery", (void*) &presetOutputs.wave.mystery, NULL, P_FLAG_NONE, 0.0, 1.0, -1.0,
load_builtin_param_float("wave_r", (void*) &presetOutputs->wave.r, NULL, P_FLAG_NONE, 0.0, 1.0, 0.0, "");
load_builtin_param_float("wave_g", (void*) &presetOutputs->wave.g, NULL, P_FLAG_NONE, 0.0, 1.0, 0.0, "");
load_builtin_param_float("wave_b", (void*) &presetOutputs->wave.b, NULL, P_FLAG_NONE, 0.0, 1.0, 0.0, "");
load_builtin_param_float("wave_x", (void*) &presetOutputs->wave.x, NULL, P_FLAG_NONE, 0.0, 1.0, 0.0, "");
load_builtin_param_float("wave_y", (void*) &presetOutputs->wave.y, NULL, P_FLAG_NONE, 0.0, 1.0, 0.0, "");
load_builtin_param_float("wave_mystery", (void*) &presetOutputs->wave.mystery, NULL, P_FLAG_NONE, 0.0, 1.0, -1.0,
"fWaveParam");
load_builtin_param_float("ob_size", (void*) &presetOutputs.border.outer_size, NULL, P_FLAG_NONE, 0.0, 0.5, 0, "");
load_builtin_param_float("ob_r", (void*) &presetOutputs.border.outer_r, NULL, P_FLAG_NONE, 0.0, 1.0, 0.0, "");
load_builtin_param_float("ob_g", (void*) &presetOutputs.border.outer_g, NULL, P_FLAG_NONE, 0.0, 1.0, 0.0, "");
load_builtin_param_float("ob_b", (void*) &presetOutputs.border.outer_b, NULL, P_FLAG_NONE, 0.0, 1.0, 0.0, "");
load_builtin_param_float("ob_a", (void*) &presetOutputs.border.outer_a, NULL, P_FLAG_NONE, 0.0, 1.0, 0.0, "");
load_builtin_param_float("ob_size", (void*) &presetOutputs->border.outer_size, NULL, P_FLAG_NONE, 0.0, 0.5, 0, "");
load_builtin_param_float("ob_r", (void*) &presetOutputs->border.outer_r, NULL, P_FLAG_NONE, 0.0, 1.0, 0.0, "");
load_builtin_param_float("ob_g", (void*) &presetOutputs->border.outer_g, NULL, P_FLAG_NONE, 0.0, 1.0, 0.0, "");
load_builtin_param_float("ob_b", (void*) &presetOutputs->border.outer_b, NULL, P_FLAG_NONE, 0.0, 1.0, 0.0, "");
load_builtin_param_float("ob_a", (void*) &presetOutputs->border.outer_a, NULL, P_FLAG_NONE, 0.0, 1.0, 0.0, "");
load_builtin_param_float("ib_size", (void*) &presetOutputs.border.inner_size, NULL, P_FLAG_NONE, 0.0, .5, 0.0, "");
load_builtin_param_float("ib_r", (void*) &presetOutputs.border.inner_r, NULL, P_FLAG_NONE, 0.0, 1.0, 0.0, "");
load_builtin_param_float("ib_g", (void*) &presetOutputs.border.inner_g, NULL, P_FLAG_NONE, 0.0, 1.0, 0.0, "");
load_builtin_param_float("ib_b", (void*) &presetOutputs.border.inner_b, NULL, P_FLAG_NONE, 0.0, 1.0, 0.0, "");
load_builtin_param_float("ib_a", (void*) &presetOutputs.border.inner_a, NULL, P_FLAG_NONE, 0.0, 1.0, 0.0, "");
load_builtin_param_float("ib_size", (void*) &presetOutputs->border.inner_size, NULL, P_FLAG_NONE, 0.0, .5, 0.0, "");
load_builtin_param_float("ib_r", (void*) &presetOutputs->border.inner_r, NULL, P_FLAG_NONE, 0.0, 1.0, 0.0, "");
load_builtin_param_float("ib_g", (void*) &presetOutputs->border.inner_g, NULL, P_FLAG_NONE, 0.0, 1.0, 0.0, "");
load_builtin_param_float("ib_b", (void*) &presetOutputs->border.inner_b, NULL, P_FLAG_NONE, 0.0, 1.0, 0.0, "");
load_builtin_param_float("ib_a", (void*) &presetOutputs->border.inner_a, NULL, P_FLAG_NONE, 0.0, 1.0, 0.0, "");
load_builtin_param_float("mv_r", (void*) &presetOutputs.mv.r, NULL, P_FLAG_NONE, 0.0, 1.0, 0.0, "");
load_builtin_param_float("mv_g", (void*) &presetOutputs.mv.g, NULL, P_FLAG_NONE, 0.0, 1.0, 0.0, "");
load_builtin_param_float("mv_b", (void*) &presetOutputs.mv.b, NULL, P_FLAG_NONE, 0.0, 1.0, 0.0, "");
load_builtin_param_float("mv_x", (void*) &presetOutputs.mv.x_num, NULL, P_FLAG_NONE, 0.0, 64.0, 0.0,
load_builtin_param_float("mv_r", (void*) &presetOutputs->mv.r, NULL, P_FLAG_NONE, 0.0, 1.0, 0.0, "");
load_builtin_param_float("mv_g", (void*) &presetOutputs->mv.g, NULL, P_FLAG_NONE, 0.0, 1.0, 0.0, "");
load_builtin_param_float("mv_b", (void*) &presetOutputs->mv.b, NULL, P_FLAG_NONE, 0.0, 1.0, 0.0, "");
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,
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_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("mv_l", (void*) &presetOutputs->mv.length, NULL, P_FLAG_NONE, 0.0, 5.0, 0.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, "");
load_builtin_param_float("bass", (void*) &presetInputs.bass, NULL, P_FLAG_READONLY, 0.0, MAX_DOUBLE_SIZE, 0.0, "");
@ -446,7 +447,7 @@ int BuiltinParams::load_all_builtin_param(const PresetInputs& presetInputs, Pres
{
std::ostringstream os;
os << "q" << i + 1;
load_builtin_param_float(os.str().c_str(), (void*) &presetOutputs.q[i], NULL, P_FLAG_QVAR, 0, MAX_DOUBLE_SIZE,
load_builtin_param_float(os.str().c_str(), (void*) &presetOutputs->q[i], NULL, P_FLAG_QVAR, 0, MAX_DOUBLE_SIZE,
-MAX_DOUBLE_SIZE, "");
}

View File

@ -44,17 +44,10 @@ public:
/** Construct a new builtin parameter database with variables references given by
* the preset input and output structures */
BuiltinParams(PresetInputs& presetInputs, PresetOutputs& presetOutputs);
BuiltinParams(PresetInputs& presetInputs, PresetOutputs* presetOutputs);
~BuiltinParams();
/** Param database initalizer / destructor functions */
int init_builtin_param_db(const PresetInputs& presetInputs, PresetOutputs& presetOutputs);
int load_all_builtin_param(const PresetInputs& presetInputs, PresetOutputs& presetOutputs);
int destroy_builtin_param_db();
int insert_param_alt_name(Param* param, const std::string& salt_name);
Param* find_builtin_param(const std::string& name);
@ -82,6 +75,14 @@ public:
}
protected:
/** Param database initalizer / destructor functions */
int init_builtin_param_db(const PresetInputs& presetInputs, PresetOutputs* presetOutputs);
int load_all_builtin_param(const PresetInputs& presetInputs, PresetOutputs* presetOutputs);
int destroy_builtin_param_db();
private:
static const bool BUILTIN_PARAMS_DEBUG = false;

View File

@ -204,7 +204,7 @@ std::string IdlePresets::presetText()
}
std::unique_ptr<Preset>
IdlePresets::allocate(MilkdropPresetFactory* factory, const std::string& name, PresetOutputs& presetOutputs)
IdlePresets::allocate(MilkdropPresetFactory* factory, const std::string& name, PresetOutputs* presetOutputs)
{
if (name == IDLE_PRESET_NAME)

View File

@ -19,7 +19,7 @@ public:
/// Allocate a new idle preset instance
/// \returns a newly allocated auto pointer of an idle preset instance
static std::unique_ptr<Preset>
allocate(MilkdropPresetFactory* factory, const std::string& path, PresetOutputs& outputs);
allocate(MilkdropPresetFactory* factory, const std::string& path, PresetOutputs* outputs);
private:
static std::string presetText();

View File

@ -55,9 +55,8 @@
MilkdropPreset::MilkdropPreset(MilkdropPresetFactory* factory, std::istream& in, const std::string& presetName,
PresetOutputs& presetOutputs)
:
Preset(presetName)
PresetOutputs* presetOutputs)
: Preset(presetName)
, builtinParams(_presetInputs, presetOutputs)
, per_pixel_program(nullptr)
, _factory(factory)
@ -68,9 +67,8 @@ MilkdropPreset::MilkdropPreset(MilkdropPresetFactory* factory, std::istream& in,
MilkdropPreset::MilkdropPreset(MilkdropPresetFactory* factory, const std::string& absoluteFilePath,
const std::string& presetName, PresetOutputs& presetOutputs)
:
Preset(presetName)
const std::string& presetName, PresetOutputs* presetOutputs)
: Preset(presetName)
, builtinParams(_presetInputs, presetOutputs)
, per_pixel_program(nullptr)
, _filename(parseFilename(absoluteFilePath))
@ -117,7 +115,7 @@ MilkdropPreset::~MilkdropPreset()
customWaves.clear();
customShapes.clear();
if (nullptr != _factory)
if (_factory)
{
_factory->releasePreset(this);
}
@ -302,14 +300,17 @@ void MilkdropPreset::postloadInitialize()
/// @bug are you handling all the q variables conditions? in particular, the un-init case?
//m_presetOutputs.q1 = 0;
//m_presetOutputs.q2 = 0;
//m_presetOutputs.q3 = 0;
//m_presetOutputs.q4 = 0;
//m_presetOutputs.q5 = 0;
//m_presetOutputs.q6 = 0;
//m_presetOutputs.q7 = 0;
//m_presetOutputs.q8 = 0;
// if (_presetOutputs)
// {
// _presetOutputs->q1 = 0;
// _presetOutputs->q2 = 0;
// _presetOutputs->q3 = 0;
// _presetOutputs->q4 = 0;
// _presetOutputs->q5 = 0;
// _presetOutputs->q6 = 0;
// _presetOutputs->q7 = 0;
// _presetOutputs->q8 = 0;
// }
}
@ -423,9 +424,12 @@ void MilkdropPreset::evaluateFrame()
evalCustomShapePerFrameEquations();
// Setup pointers of the custom waves and shapes to the preset outputs instance
/// @slow an extra O(N) per frame, could do this during eval
_presetOutputs.customWaves = PresetOutputs::cwave_container(customWaves);
_presetOutputs.customShapes = PresetOutputs::cshape_container(customShapes);
if (_presetOutputs)
{
/// @slow an extra O(N) per frame, could do this during eval
_presetOutputs->customWaves = PresetOutputs::cwave_container(customWaves);
_presetOutputs->customShapes = PresetOutputs::cshape_container(customShapes);
}
}
@ -458,16 +462,21 @@ void MilkdropPreset::initialize_PerPixelMeshes()
int gx = presetInputs().gx;
int gy = presetInputs().gy;
init_mesh(_presetOutputs.cx_mesh, presetOutputs().cx, gx, gy);
init_mesh(_presetOutputs.cy_mesh, presetOutputs().cy, gx, gy);
init_mesh(_presetOutputs.sx_mesh, presetOutputs().sx, gx, gy);
init_mesh(_presetOutputs.sy_mesh, presetOutputs().sy, gx, gy);
init_mesh(_presetOutputs.dx_mesh, presetOutputs().dx, gx, gy);
init_mesh(_presetOutputs.dy_mesh, presetOutputs().dy, gx, gy);
init_mesh(_presetOutputs.zoom_mesh, presetOutputs().zoom, gx, gy);
init_mesh(_presetOutputs.zoomexp_mesh, presetOutputs().zoomexp, gx, gy);
init_mesh(_presetOutputs.rot_mesh, presetOutputs().rot, gx, gy);
init_mesh(_presetOutputs.warp_mesh, presetOutputs().warp, gx, gy);
if (!_presetOutputs)
{
return;
}
init_mesh(_presetOutputs->cx_mesh, _presetOutputs->cx, gx, gy);
init_mesh(_presetOutputs->cy_mesh, _presetOutputs->cy, gx, gy);
init_mesh(_presetOutputs->sx_mesh, _presetOutputs->sx, gx, gy);
init_mesh(_presetOutputs->sy_mesh, _presetOutputs->sy, gx, gy);
init_mesh(_presetOutputs->dx_mesh, _presetOutputs->dx, gx, gy);
init_mesh(_presetOutputs->dy_mesh, _presetOutputs->dy, gx, gy);
init_mesh(_presetOutputs->zoom_mesh, _presetOutputs->zoom, gx, gy);
init_mesh(_presetOutputs->zoomexp_mesh, _presetOutputs->zoomexp, gx, gy);
init_mesh(_presetOutputs->rot_mesh, _presetOutputs->rot, gx, gy);
init_mesh(_presetOutputs->warp_mesh, _presetOutputs->warp, gx, gy);
}
@ -514,9 +523,11 @@ void MilkdropPreset::evalPerPixelEqns()
int MilkdropPreset::readIn(std::istream& fs)
{
presetOutputs().compositeShader.programSource.clear();
presetOutputs().warpShader.programSource.clear();
if (_presetOutputs)
{
_presetOutputs->compositeShader.programSource.clear();
_presetOutputs->warpShader.programSource.clear();
}
/* Parse any comments (aka "[preset00]") */
/* We don't do anything with this info so it's okay if it's missing */

View File

@ -72,14 +72,14 @@ public:
/// \param milkdropPresetName a descriptive name for the MilkdropPreset. Usually just the file name
/// \param presetOutputs initialized and filled with data parsed from a MilkdropPreset
MilkdropPreset(MilkdropPresetFactory* factory, const std::string& absoluteFilePath,
const std::string& milkdropPresetName, PresetOutputs& presetOutputs);
const std::string& milkdropPresetName, PresetOutputs* presetOutputs);
/// Load a MilkdropPreset from an input stream with input and output buffers specified.
/// \param in an already initialized input stream to read the MilkdropPreset file from
/// \param milkdropPresetName a descriptive name for the MilkdropPreset. Usually just the file name
/// \param presetOutputs initialized and filled with data parsed from a MilkdropPreset
MilkdropPreset(MilkdropPresetFactory* factory, std::istream& in, const std::string& milkdropPresetName,
PresetOutputs& presetOutputs);
PresetOutputs* presetOutputs);
~MilkdropPreset();
@ -118,7 +118,7 @@ public:
/// \returns A MilkdropPreset output instance with values computed from most recent evaluateFrame()
PresetOutputs& presetOutputs() const
{
return _presetOutputs;
return *_presetOutputs;
}
const PresetInputs& presetInputs() const
@ -144,7 +144,7 @@ public:
PresetOutputs& pipeline()
{
return _presetOutputs;
return *_presetOutputs;
}
void Render(const BeatDetect& music, const PipelineContext& context);
@ -204,8 +204,8 @@ private:
void postloadInitialize();
MilkdropPresetFactory* _factory;
PresetOutputs& _presetOutputs;
MilkdropPresetFactory* _factory{ nullptr };
PresetOutputs* _presetOutputs{ nullptr };
template<class CustomObject>
void transfer_q_variables(std::vector<CustomObject*>& customObjects);
@ -225,7 +225,7 @@ void MilkdropPreset::transfer_q_variables(std::vector<CustomObject*>& customObje
custom_object = *pos;
for (unsigned int i = 0; i < NUM_Q_VARIABLES; i++)
{
custom_object->q[i] = _presetOutputs.q[i];
custom_object->q[i] = _presetOutputs->q[i];
}
}

View File

@ -31,19 +31,23 @@ MilkdropPresetFactory::MilkdropPresetFactory(int gx_, int gy_)
MilkdropPresetFactory::~MilkdropPresetFactory()
{
// std::cerr << "[~MilkdropPresetFactory] destroy infix ops" << std::endl;
Eval::destroy_infix_ops();
// std::cerr << "[~MilkdropPresetFactory] destroy builtin func" << std::endl;
BuiltinFuncs::destroy_builtin_func_db();
// std::cerr << "[~MilkdropPresetFactory] delete preset out puts" << std::endl;
delete (_presetOutputsCache);
// std::cerr << "[~MilkdropPresetFactory] done" << std::endl;
if (_presetOutputsCache)
{
delete (_presetOutputsCache);
_presetOutputsCache = nullptr;
}
}
/* Reinitializes the engine variables to a default (conservative and sane) value */
void resetPresetOutputs(PresetOutputs* presetOutputs)
{
if (!presetOutputs)
{
return;
}
presetOutputs->zoom = 1.0;
presetOutputs->zoomexp = 1.0;
@ -147,7 +151,6 @@ void resetPresetOutputs(PresetOutputs* presetOutputs)
/* Reinitializes the engine variables to a default (conservative and sane) value */
void MilkdropPresetFactory::reset()
{
if (_presetOutputsCache)
{
resetPresetOutputs(_presetOutputsCache);
@ -237,25 +240,32 @@ MilkdropPresetFactory::allocate(const std::string& url, const std::string& name,
std::string path;
if (PresetFactory::protocol(url, path) == PresetFactory::IDLE_PRESET_PROTOCOL)
{
return IdlePresets::allocate(this, path, *presetOutputs);
return IdlePresets::allocate(this, path, presetOutputs);
}
else
{
return std::unique_ptr<Preset>(new MilkdropPreset(this, url, name, *presetOutputs));
return std::unique_ptr<Preset>(new MilkdropPreset(this, url, name, presetOutputs));
}
}
// this gives the preset a way to return the PresetOutput w/o dependency on class projectM behavior
void MilkdropPresetFactory::releasePreset(Preset* preset_)
void MilkdropPresetFactory::releasePreset(Preset* preset)
{
MilkdropPreset* preset = (MilkdropPreset*) preset_;
// return PresetOutputs to the cache
if (nullptr == _presetOutputsCache)
auto milkdropPreset = dynamic_cast<MilkdropPreset*>(preset);
if (!milkdropPreset || !milkdropPreset->_presetOutputs)
{
_presetOutputsCache = &preset->_presetOutputs;
// Instance is not a MilkdropPreset or has no PresetOutput object.
return;
}
// return PresetOutputs to the cache
if (!_presetOutputsCache)
{
_presetOutputsCache = milkdropPreset->_presetOutputs;
}
else
{
delete &preset->_presetOutputs;
delete milkdropPreset->_presetOutputs;
}
}

View File

@ -10,8 +10,7 @@
//
//
#ifndef __MILKDROP_PRESET_FACTORY_HPP
#define __MILKDROP_PRESET_FACTORY_HPP
#pragma once
#include <memory>
#include "../PresetFactory.hpp"
@ -26,15 +25,15 @@ class MilkdropPresetFactory : public PresetFactory
public:
MilkdropPresetFactory(int gx, int gy);
virtual ~MilkdropPresetFactory();
~MilkdropPresetFactory() override;
// called by ~MilkdropPreset
void releasePreset(Preset* preset);
std::unique_ptr<Preset> allocate(const std::string& url, const std::string& name = std::string(),
const std::string& author = std::string());
std::unique_ptr<Preset> allocate(const std::string& url, const std::string& name,
const std::string& author) override;
std::string supportedExtensions() const
std::string supportedExtensions() const override
{
return ".milk .prjm";
}
@ -44,9 +43,7 @@ private:
void reset();
int gx;
int gy;
PresetOutputs* _presetOutputsCache;
int gx{ 0 };
int gy{ 0 };
PresetOutputs* _presetOutputsCache{ nullptr };
};
#endif

View File

@ -706,6 +706,8 @@ int projectM::initPresetTools(int gx, int gy)
void projectM::destroyPresetTools()
{
m_activePreset.reset();
m_activePreset2.reset();
if ( m_presetPos )
delete ( m_presetPos );