mirror of
https://github.com/projectM-visualizer/projectm.git
synced 2026-02-06 10:15:28 +00:00
- SplayTree is gone! excellent.
- some issues with load_custom_wave/shape_init_conds. will resolve soon git-svn-id: https://projectm.svn.sourceforge.net/svnroot/projectm/personal/carm/dev-1.0@271 6778bc44-b910-0410-a7a0-be141de4315d
This commit is contained in:
@ -15,6 +15,10 @@
|
||||
|
||||
/* Loads a builtin function */
|
||||
#include "BuiltinFuncs.hpp"
|
||||
#include <string>
|
||||
#include "Algorithms.hpp"
|
||||
|
||||
using namespace Algorithms;
|
||||
|
||||
std::map<std::string, Func*> * BuiltinFuncs::builtin_func_tree = 0;
|
||||
|
||||
@ -40,23 +44,19 @@ int BuiltinFuncs::load_builtin_func(char * name, float (*func_ptr)(float*), int
|
||||
/* Find a function given its name */
|
||||
Func * BuiltinFuncs::find_func(char * name) {
|
||||
|
||||
Func * func = NULL;
|
||||
|
||||
|
||||
/* First look in the builtin database */
|
||||
func = (Func *)builtin_func_tree->splay_find(name);
|
||||
|
||||
return func;
|
||||
std::map<std::string, Func*>::iterator pos = builtin_func_tree->find(std::string(name));
|
||||
|
||||
if (pos == builtin_func_tree->end())
|
||||
return 0;
|
||||
|
||||
return pos->second;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* Remove a function from the database */
|
||||
int BuiltinFuncs::remove_func( Func *func ) {
|
||||
|
||||
builtin_func_tree->splay_delete(func->name);
|
||||
|
||||
return PROJECTM_SUCCESS;
|
||||
}
|
||||
|
||||
int BuiltinFuncs::load_all_builtin_func() {
|
||||
|
||||
@ -129,7 +129,7 @@ int BuiltinFuncs::init_builtin_func_db() {
|
||||
int retval;
|
||||
|
||||
builtin_func_tree =
|
||||
std::map<std::string, Func*>::create_splaytree((int (*)(const void*,const void*))SplayKeyFunctions::compare_string, (void*(*)(void*))SplayKeyFunctions::copy_string, (void(*)(void*))SplayKeyFunctions::free_string);
|
||||
new std::map<std::string, Func*>();
|
||||
|
||||
if (builtin_func_tree == NULL)
|
||||
return PROJECTM_OUTOFMEM_ERROR;
|
||||
@ -144,14 +144,15 @@ int BuiltinFuncs::init_builtin_func_db() {
|
||||
Generally, do this on projectm exit */
|
||||
int BuiltinFuncs::destroy_builtin_func_db() {
|
||||
|
||||
builtin_func_tree->splay_traverse((void (*)(void*))free_func_helper);
|
||||
return PROJECTM_SUCCESS;
|
||||
traverse<TraverseFunctors::DeleteFunctor<Func> >(*builtin_func_tree);
|
||||
return PROJECTM_SUCCESS;
|
||||
}
|
||||
|
||||
/* Insert a function into the database */
|
||||
int BuiltinFuncs::insert_func( Func *func ) {
|
||||
|
||||
builtin_func_tree->splay_insert(func, func->name);
|
||||
/// @bug check to see if this inserts properly
|
||||
builtin_func_tree->insert(std::make_pair(std::string(func->name), func));
|
||||
|
||||
return PROJECTM_SUCCESS;
|
||||
}
|
||||
|
||||
@ -3,6 +3,9 @@
|
||||
#include "BuiltinParams.hpp"
|
||||
#include "projectM.hpp"
|
||||
#include <cassert>
|
||||
#include "Algorithms.hpp"
|
||||
|
||||
using namespace Algorithms;
|
||||
|
||||
BuiltinParams::BuiltinParams() {}
|
||||
|
||||
@ -94,8 +97,7 @@ int BuiltinParams::load_builtin_param_float(char * name, void * engine_val, void
|
||||
int BuiltinParams::destroy_builtin_param_db()
|
||||
{
|
||||
|
||||
builtin_param_tree->traverse
|
||||
<SplayTreeFunctors::Delete<Param> >();
|
||||
Algorithms::traverse<TraverseFunctors::DeleteFunctor<Param> >(*builtin_param_tree);
|
||||
delete builtin_param_tree;
|
||||
builtin_param_tree = NULL;
|
||||
return PROJECTM_SUCCESS;
|
||||
@ -209,8 +211,9 @@ int BuiltinParams::load_builtin_param_bool(char * name, void * engine_val, short
|
||||
/* Inserts a parameter into the builtin database */
|
||||
int BuiltinParams::insert_builtin_param( Param *param )
|
||||
{
|
||||
std::pair<std::map<std::string, Param*>::iterator, bool> inserteePos = builtin_param_tree->insert(std::make_pair(param->name, param));
|
||||
|
||||
return builtin_param_tree->splay_insert(param, param->name);
|
||||
return inserteePos.second;
|
||||
}
|
||||
|
||||
|
||||
@ -221,7 +224,7 @@ int BuiltinParams::init_builtin_param_db(const PresetInputs & presetInputs, Pres
|
||||
{
|
||||
|
||||
/* Create the builtin parameter splay tree (go Sleator...) */
|
||||
if ((this->builtin_param_tree = std::map<std::string,Param*>::create_splaytree((int (*)(const void*,const void*))SplayKeyFunctions::compare_string,(void* (*)(void*)) SplayKeyFunctions::copy_string, (void (*)(void*))SplayKeyFunctions::free_string)) == NULL)
|
||||
if ((this->builtin_param_tree = new std::map<std::string,Param*>()) == NULL)
|
||||
{
|
||||
if (BUILTIN_PARAMS_DEBUG) printf("init_builtin_param_db: failed to initialize database (FATAL)\n");
|
||||
return PROJECTM_OUTOFMEM_ERROR;
|
||||
@ -358,4 +361,4 @@ int BuiltinParams::load_all_builtin_param(const PresetInputs & presetInputs, Pre
|
||||
|
||||
return PROJECTM_SUCCESS;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -67,7 +67,7 @@ public:
|
||||
|
||||
template <class Fun>
|
||||
void traverse(Fun & fun) {
|
||||
Algorithms::traverse(builtin_param_tree, fun);
|
||||
Algorithms::traverse(*builtin_param_tree, fun);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -37,8 +37,10 @@
|
||||
#include "ParamUtils.hpp"
|
||||
#include "InitCondUtils.hpp"
|
||||
#include "wipemalloc.h"
|
||||
#include "Algorithms.hpp"
|
||||
|
||||
|
||||
using namespace Algorithms;
|
||||
|
||||
void eval_custom_shape_init_conds(CustomShape * custom_shape);
|
||||
void load_unspec_init_cond_shape(Param * param);
|
||||
@ -54,17 +56,17 @@ CustomShape::CustomShape( int id ) {
|
||||
this->per_frame_init_eqn_string_index = 0;
|
||||
|
||||
/* Initialize tree data structures */
|
||||
this->param_tree =
|
||||
std::map<std::string,Param*>::create_splaytree( (int (*)(const void*,const void*))SplayKeyFunctions::compare_string, (void* (*)(void*)) SplayKeyFunctions::copy_string,(void (*)(void*)) SplayKeyFunctions::free_string);
|
||||
|
||||
this->param_tree = new
|
||||
std::map<std::string,Param*>();
|
||||
|
||||
this->per_frame_eqn_tree =
|
||||
std::map<int, PerFrameEqn*>::create_splaytree((int (*)(const void*, const void*))SplayKeyFunctions::compare_int, (void* (*)(void*))SplayKeyFunctions::copy_int,(void (*)(void*))SplayKeyFunctions::free_int);
|
||||
std::map<int, PerFrameEqn*>();
|
||||
|
||||
this->init_cond_tree =
|
||||
std::map<std::string,InitCond*>::create_splaytree((int (*)(const void*,const void*))SplayKeyFunctions::compare_string, (void* (*)(void*)) SplayKeyFunctions::copy_string,(void (*)(void*)) SplayKeyFunctions::free_string);
|
||||
|
||||
std::map<std::string,InitCond*>();
|
||||
|
||||
this->per_frame_init_eqn_tree =
|
||||
std::map<std::string,InitCond*>::create_splaytree((int (*)(const void*, const void*)) SplayKeyFunctions::compare_string, (void* (*)(void*))SplayKeyFunctions::copy_string, (void (*)(void*))SplayKeyFunctions::free_string);
|
||||
std::map<std::string,InitCond*>();
|
||||
|
||||
/* Start: Load custom shape parameters */
|
||||
param = Param::new_param_float("r", P_FLAG_NONE, &this->r, NULL, 1.0, 0.0, 0.5);
|
||||
@ -199,11 +201,11 @@ CustomShape::~CustomShape() {
|
||||
if (param_tree == NULL)
|
||||
return;
|
||||
|
||||
per_frame_eqn_tree->traverse<SplayTreeFunctors::Delete<PerFrameEqn> >();
|
||||
init_cond_tree->traverse<SplayTreeFunctors::Delete<InitCond> >();
|
||||
param_tree->traverse<SplayTreeFunctors::Delete<Param> > ();
|
||||
per_frame_init_eqn_tree->traverse<SplayTreeFunctors::Delete<InitCond> > ();
|
||||
|
||||
traverse<TraverseFunctors::DeleteFunctor<PerFrameEqn> >(per_frame_eqn_tree);
|
||||
traverse<TraverseFunctors::DeleteFunctor<InitCond> >(init_cond_tree);
|
||||
traverse<TraverseFunctors::DeleteFunctor<Param> >(*param_tree);
|
||||
traverse<TraverseFunctors::DeleteFunctor<InitCond> >(per_frame_init_eqn_tree);
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
@ -213,13 +215,15 @@ void CustomShape::load_custom_shape_init() {
|
||||
}
|
||||
|
||||
void CustomShape::eval_custom_shape_init_conds() {
|
||||
per_frame_init_eqn_tree->splay_traverse((void (*)(void*))eval_init_cond_helper );
|
||||
|
||||
for (std::map<std::string, InitCond*>::iterator pos = per_frame_init_eqn_tree.begin(); pos != per_frame_init_eqn_tree.end();++pos)
|
||||
pos->second->evaluate();
|
||||
}
|
||||
|
||||
void CustomShape::load_unspecified_init_conds_shape() {
|
||||
|
||||
InitCondUtils::LoadUnspecInitCond fun(*this->init_cond_tree, *this->per_frame_init_eqn_tree);
|
||||
InitCondUtils::LoadUnspecInitCond fun(this->init_cond_tree, this->per_frame_init_eqn_tree);
|
||||
|
||||
param_tree->traverse(fun);
|
||||
traverse(*param_tree, fun);
|
||||
|
||||
}
|
||||
|
||||
@ -88,9 +88,9 @@ public:
|
||||
float t8;
|
||||
|
||||
/* Data structure to hold per frame / per frame init equations */
|
||||
std::map<std::string,InitCond*> * init_cond_tree;
|
||||
std::map<int, PerFrameEqn*> * per_frame_eqn_tree;
|
||||
std::map<std::string,InitCond*> * per_frame_init_eqn_tree;
|
||||
std::map<std::string,InitCond*> init_cond_tree;
|
||||
std::map<int, PerFrameEqn*> per_frame_eqn_tree;
|
||||
std::map<std::string,InitCond*> per_frame_init_eqn_tree;
|
||||
|
||||
/* Denotes the index of the last character for each stdring buffer */
|
||||
int per_frame_eqn_string_index;
|
||||
|
||||
@ -77,40 +77,6 @@ CustomWave::CustomWave(int id):id(id)
|
||||
this->value2 = (float*)wipemalloc(MAX_SAMPLE_SIZE*sizeof(float));
|
||||
this->sample_mesh = (float*)wipemalloc(MAX_SAMPLE_SIZE*sizeof(float));
|
||||
|
||||
/* Initialize tree data structures */
|
||||
|
||||
if ((this->param_tree =
|
||||
std::map<std::string,Param*>::create_splaytree((int (*)(const void*, const void*))SplayKeyFunctions::compare_string, (void* (*)(void*))SplayKeyFunctions::copy_string, (void (*)(void*))SplayKeyFunctions::free_string)) == NULL) {
|
||||
delete(this);
|
||||
abort();
|
||||
}
|
||||
|
||||
if ((this->per_point_eqn_tree =
|
||||
std::map<int, PerPointEqn*>::create_splaytree((int (*)(const void*, const void*))SplayKeyFunctions::compare_int, (void* (*)(void*))SplayKeyFunctions::copy_int, (void (*)(void*))SplayKeyFunctions::free_int)) == NULL) {
|
||||
delete(this);
|
||||
abort();
|
||||
}
|
||||
|
||||
if ((this->per_frame_eqn_tree =
|
||||
std::map<int, PerFrameEqn*>::create_splaytree((int (*)(const void*, const void*))SplayKeyFunctions::compare_int,(void* (*)(void*)) SplayKeyFunctions::copy_int,(void (*)(void*)) SplayKeyFunctions::free_int)) == NULL) {
|
||||
delete(this);
|
||||
abort();
|
||||
}
|
||||
|
||||
if ((this->init_cond_tree =
|
||||
std::map<std::string,InitCond*>::create_splaytree((int (*)(const void*, const void*))SplayKeyFunctions::compare_string, (void*(*)(void*))SplayKeyFunctions::copy_string,(void (*)(void*)) SplayKeyFunctions::free_string)) == NULL) {
|
||||
delete(this);
|
||||
/// @bug make exception
|
||||
abort();
|
||||
}
|
||||
|
||||
if ((this->per_frame_init_eqn_tree =
|
||||
std::map<std::string,InitCond*>::create_splaytree((int (*)(const void*, const void*))SplayKeyFunctions::compare_string, (void*(*)(void*))SplayKeyFunctions::copy_string, (void (*)(void*))SplayKeyFunctions::free_string)) == NULL) {
|
||||
delete(this);
|
||||
/// @bug make exception
|
||||
abort();
|
||||
}
|
||||
|
||||
|
||||
/* Start: Load custom wave parameters */
|
||||
|
||||
@ -120,9 +86,7 @@ CustomWave::CustomWave(int id):id(id)
|
||||
abort();
|
||||
}
|
||||
|
||||
|
||||
if (ParamUtils::insert(param, this->param_tree) < 0) {
|
||||
delete(this);
|
||||
/// @bug make exception
|
||||
abort();
|
||||
}
|
||||
@ -431,13 +395,22 @@ CustomWave::~CustomWave() {
|
||||
return;
|
||||
|
||||
|
||||
per_point_eqn_tree->traverse<SplayTreeFunctors::Delete<PerPointEqn> >();
|
||||
per_frame_eqn_tree->traverse<SplayTreeFunctors::Delete<PerFrameEqn> >();
|
||||
init_cond_tree->traverse<SplayTreeFunctors::Delete<InitCond> >();
|
||||
param_tree->traverse<SplayTreeFunctors::Delete<Param> > ();
|
||||
per_frame_init_eqn_tree->traverse<SplayTreeFunctors::Delete<InitCond> > ();
|
||||
for (std::map<int, PerPointEqn*>::iterator pos = per_point_eqn_tree.begin(); pos != per_point_eqn_tree.end(); ++pos)
|
||||
delete(pos->second);
|
||||
|
||||
for (std::map<int, PerFrameEqn*>::iterator pos = per_frame_eqn_tree.begin(); pos != per_frame_eqn_tree.end(); ++pos)
|
||||
delete(pos->second);
|
||||
|
||||
for (std::map<std::string, InitCond*>::iterator pos = init_cond_tree.begin(); pos != init_cond_tree.end(); ++pos)
|
||||
delete(pos->second);
|
||||
|
||||
for (std::map<std::string, InitCond*>::iterator pos = per_frame_init_eqn_tree.begin(); pos != per_frame_init_eqn_tree.end(); ++pos)
|
||||
delete(pos->second);
|
||||
|
||||
for (std::map<std::string, Param*>::iterator pos = param_tree->begin(); pos != param_tree->end(); ++pos)
|
||||
delete(pos->second);
|
||||
|
||||
|
||||
|
||||
free(r_mesh);
|
||||
free(g_mesh);
|
||||
free(b_mesh);
|
||||
@ -488,22 +461,24 @@ int CustomWave::add_per_point_eqn(char * name, GenExpr * gen_expr) {
|
||||
}
|
||||
|
||||
/* Find most largest index in the splaytree */
|
||||
if ((per_point_eqn = (PerPointEqn*)per_point_eqn_tree->splay_find_max()) == NULL)
|
||||
|
||||
std::map<int, PerPointEqn*>::iterator pos = --per_point_eqn_tree.end();
|
||||
|
||||
if (pos == per_point_eqn_tree.end())
|
||||
index = 0;
|
||||
else
|
||||
index = per_point_eqn->index+1;
|
||||
index = pos->second->index+1;
|
||||
|
||||
/* Create the per pixel equation given the index, parameter, and general expression */
|
||||
if ((per_point_eqn = PerPointEqn::new_per_point_eqn(index, param, gen_expr)) == NULL)
|
||||
|
||||
if ((per_point_eqn = new PerPointEqn(index, param, gen_expr, samples)) == NULL)
|
||||
return PROJECTM_FAILURE;
|
||||
if (CUSTOM_WAVE_DEBUG)
|
||||
printf("add_per_point_eqn: created new equation (index = %d) (name = \"%s\")\n", per_point_eqn->index, per_point_eqn->param->name);
|
||||
printf("add_per_point_eqn: created new equation (index = %d) (name = \"%s\")\n", per_point_eqn->index, per_point_eqn->param->name.c_str());
|
||||
|
||||
/* Insert the per pixel equation into the preset per pixel database */
|
||||
if (per_point_eqn_tree->splay_insert(per_point_eqn, &per_point_eqn->index) < 0) {
|
||||
delete per_point_eqn;
|
||||
return PROJECTM_FAILURE;
|
||||
}
|
||||
|
||||
per_point_eqn_tree.insert(std::make_pair(per_point_eqn->index, per_point_eqn));
|
||||
|
||||
/* Done */
|
||||
return PROJECTM_SUCCESS;
|
||||
@ -511,8 +486,12 @@ int CustomWave::add_per_point_eqn(char * name, GenExpr * gen_expr) {
|
||||
|
||||
|
||||
void CustomWave::eval_custom_wave_init_conds() {
|
||||
init_cond_tree->splay_traverse((void (*)(void*))eval_init_cond_helper );
|
||||
per_frame_init_eqn_tree->splay_traverse((void (*)(void*))eval_init_cond_helper );
|
||||
|
||||
for (std::map<std::string, InitCond*>::iterator pos = init_cond_tree.begin(); pos != init_cond_tree.end(); ++pos)
|
||||
pos->second->evaluate();
|
||||
|
||||
for (std::map<std::string, InitCond*>::iterator pos = per_frame_init_eqn_tree.begin(); pos != per_frame_init_eqn_tree.end(); ++pos)
|
||||
pos->second->evaluate();
|
||||
}
|
||||
|
||||
/** Evaluate per-point equations */
|
||||
@ -534,8 +513,8 @@ void CustomWave::evalPerPointEqns() {
|
||||
y_mesh[x] = y;
|
||||
|
||||
/* Evaluate per pixel equations */
|
||||
abort();
|
||||
per_point_eqn_tree->splay_traverse((void (*)(void*))eval_per_point_eqn_helper);
|
||||
for (std::map<int, PerPointEqn*>::iterator pos = per_point_eqn_tree.begin(); pos != per_point_eqn_tree.end();++pos)
|
||||
pos->second->evaluate();
|
||||
|
||||
/* Reset index */
|
||||
projectM::currentEngine->mesh_i = -1;
|
||||
@ -543,9 +522,8 @@ void CustomWave::evalPerPointEqns() {
|
||||
|
||||
void CustomWave::load_unspecified_init_conds() {
|
||||
|
||||
InitCondUtils::LoadUnspecInitCond fun(*this->init_cond_tree, *this->per_frame_init_eqn_tree);
|
||||
param_tree->traverse(fun);
|
||||
|
||||
InitCondUtils::LoadUnspecInitCond fun(this->init_cond_tree, this->per_frame_init_eqn_tree);
|
||||
Algorithms::traverse(*param_tree, fun);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -110,10 +110,10 @@ public:
|
||||
float v1,v2;
|
||||
|
||||
/* Data structures to hold per frame and per point equations */
|
||||
std::map<std::string,InitCond*> * init_cond_tree;
|
||||
std::map<int, PerFrameEqn*> * per_frame_eqn_tree;
|
||||
std::map<int, PerPointEqn*> * per_point_eqn_tree;
|
||||
std::map<std::string,InitCond*> * per_frame_init_eqn_tree;
|
||||
std::map<std::string,InitCond*> init_cond_tree;
|
||||
std::map<int, PerFrameEqn*> per_frame_eqn_tree;
|
||||
std::map<int, PerPointEqn*> per_point_eqn_tree;
|
||||
std::map<std::string,InitCond*> per_frame_init_eqn_tree;
|
||||
|
||||
/* Denotes the index of the last character for each string buffer */
|
||||
int per_point_eqn_string_index;
|
||||
@ -135,9 +135,8 @@ public:
|
||||
void evalPerPointEqns();
|
||||
|
||||
void load_unspecified_init_conds();
|
||||
void load_unspec_init_cond() ;
|
||||
|
||||
void eval_custom_wave_init_conds();
|
||||
void load_unspec_init_cond(Param * param);
|
||||
void evalPerPointEqn(PerPointEqn * per_point_eqn);
|
||||
|
||||
|
||||
|
||||
@ -26,7 +26,7 @@
|
||||
* $Log$
|
||||
*/
|
||||
|
||||
/* eval.h: evaluation functions of expressions */
|
||||
/* Eval.hpp: evaluation functions of expressions */
|
||||
|
||||
#ifndef _EVAL_H
|
||||
#define _EVAL_H
|
||||
|
||||
@ -25,18 +25,19 @@
|
||||
#include "Eval.hpp"
|
||||
#include <cassert>
|
||||
|
||||
float GenExpr::eval_gen_expr() {
|
||||
|
||||
float GenExpr::eval_gen_expr(int mesh_i, int mesh_j) {
|
||||
float l;
|
||||
|
||||
switch(type) {
|
||||
case VAL_T:
|
||||
return ((ValExpr*)item)->eval_val_expr();
|
||||
return ((ValExpr*)item)->eval_val_expr(mesh_i, mesh_j);
|
||||
case PREFUN_T:
|
||||
l = ((PrefunExpr *)item)->eval_prefun_expr();
|
||||
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();
|
||||
return ((TreeExpr*)(item))->eval_tree_expr(mesh_i, mesh_j);
|
||||
default:
|
||||
#ifdef EVAL_DEBUG
|
||||
DWRITE( "eval_gen_expr: general expression matched no cases!\n");
|
||||
@ -47,7 +48,7 @@ float GenExpr::eval_gen_expr() {
|
||||
}
|
||||
|
||||
/* Evaluates functions in prefix form */
|
||||
float PrefunExpr::eval_prefun_expr() {
|
||||
float PrefunExpr::eval_prefun_expr(int mesh_i, int mesh_j) {
|
||||
|
||||
int i;
|
||||
float rv;
|
||||
@ -63,7 +64,7 @@ float PrefunExpr::eval_prefun_expr() {
|
||||
#endif
|
||||
/* Evaluate each argument before calling the function itself */
|
||||
for (i = 0; i < num_args; i++) {
|
||||
arg_list[i] = expr_list[i]->eval_gen_expr();
|
||||
arg_list[i] = expr_list[i]->eval_gen_expr(mesh_i, mesh_j);
|
||||
#ifdef EVAL_DEBUG_DOUBLE
|
||||
if (i < (num_args - 1))
|
||||
DWRITE( ", ");
|
||||
@ -83,8 +84,9 @@ float PrefunExpr::eval_prefun_expr() {
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
/* Evaluates a value expression */
|
||||
float ValExpr::eval_val_expr() {
|
||||
float ValExpr::eval_val_expr(int mesh_i, int mesh_j) {
|
||||
|
||||
/* Shouldn't happen */
|
||||
/* Value is a constant, return the float value */
|
||||
@ -120,7 +122,7 @@ float ValExpr::eval_val_expr() {
|
||||
|
||||
if (term.param->matrix_flag | (term.param->flags & P_FLAG_ALWAYS_MATRIX)) {
|
||||
|
||||
/** Sanity check the matrix is there... */
|
||||
/* Sanity check the matrix is there... */
|
||||
assert(term.param->matrix != NULL );
|
||||
|
||||
if (projectM::currentEngine->mesh_i >= 0) {
|
||||
@ -141,7 +143,7 @@ float ValExpr::eval_val_expr() {
|
||||
}
|
||||
|
||||
/* Evaluates an expression tree */
|
||||
float TreeExpr::eval_tree_expr() {
|
||||
float TreeExpr::eval_tree_expr(int mesh_i, int mesh_j) {
|
||||
|
||||
float left_arg, right_arg;
|
||||
|
||||
@ -150,7 +152,7 @@ float TreeExpr::eval_tree_expr() {
|
||||
if (gen_expr == NULL)
|
||||
return 0;
|
||||
else
|
||||
return gen_expr->eval_gen_expr();
|
||||
return gen_expr->eval_gen_expr( mesh_i, mesh_j);
|
||||
}
|
||||
|
||||
/* Otherwise, this node is an infix operator. Evaluate
|
||||
@ -160,7 +162,7 @@ float TreeExpr::eval_tree_expr() {
|
||||
DWRITE( "(");
|
||||
#endif
|
||||
|
||||
left_arg = left->eval_tree_expr();
|
||||
left_arg = left->eval_tree_expr(mesh_i, mesh_j);
|
||||
|
||||
#ifdef EVAL_DEBUG
|
||||
|
||||
@ -192,7 +194,7 @@ float TreeExpr::eval_tree_expr() {
|
||||
|
||||
#endif
|
||||
|
||||
right_arg = right->eval_tree_expr();
|
||||
right_arg = right->eval_tree_expr(mesh_i, mesh_j);
|
||||
|
||||
#ifdef EVAL_DEBUG
|
||||
DWRITE( ")");
|
||||
|
||||
@ -40,77 +40,86 @@ class Param;
|
||||
#define EVAL_ERROR -1
|
||||
|
||||
/* Infix Operator Function */
|
||||
class InfixOp {
|
||||
class InfixOp
|
||||
{
|
||||
public:
|
||||
int type;
|
||||
int precedence;
|
||||
int type;
|
||||
int precedence;
|
||||
|
||||
DLLEXPORT InfixOp( int type, int precedence );
|
||||
};
|
||||
DLLEXPORT InfixOp( int type, int precedence );
|
||||
};
|
||||
|
||||
/** Term */
|
||||
class Term {
|
||||
class Term
|
||||
{
|
||||
public:
|
||||
float constant; /* static variable */
|
||||
Param *param; /* pointer to a changing variable */
|
||||
float constant; /* static variable */
|
||||
Param *param; /* pointer to a changing variable */
|
||||
|
||||
Term() { this->constant = 0; this->param = 0; }
|
||||
};
|
||||
Term() { this->constant = 0; this->param = 0; }
|
||||
};
|
||||
|
||||
/* General Expression Type */
|
||||
class GenExpr {
|
||||
class GenExpr
|
||||
{
|
||||
public:
|
||||
int type;
|
||||
void * item;
|
||||
int type;
|
||||
void * item;
|
||||
|
||||
~GenExpr();
|
||||
~GenExpr();
|
||||
|
||||
static GenExpr *new_gen_expr( int type, void *item );
|
||||
GenExpr *clone_gen_expr();
|
||||
float eval_gen_expr();
|
||||
|
||||
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 );
|
||||
};
|
||||
static GenExpr *new_gen_expr( int type, void *item );
|
||||
GenExpr *clone_gen_expr();
|
||||
float eval_gen_expr(int mesh_i, int 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 {
|
||||
class ValExpr
|
||||
{
|
||||
public:
|
||||
int type;
|
||||
Term term;
|
||||
int type;
|
||||
Term term;
|
||||
|
||||
~ValExpr();
|
||||
static ValExpr *new_val_expr( int type, Term *term );
|
||||
ValExpr *clone_val_expr();
|
||||
~ValExpr();
|
||||
static ValExpr *new_val_expr( int type, Term *term );
|
||||
ValExpr *clone_val_expr();
|
||||
|
||||
float eval_val_expr();
|
||||
};
|
||||
float eval_val_expr(int mesh_i, int mesh_j);
|
||||
};
|
||||
|
||||
/* A binary expression tree ordered by operator precedence */
|
||||
class TreeExpr {
|
||||
class TreeExpr
|
||||
{
|
||||
public:
|
||||
InfixOp * infix_op; /* null if leaf */
|
||||
GenExpr * gen_expr;
|
||||
TreeExpr *left, *right;
|
||||
InfixOp * infix_op; /* null if leaf */
|
||||
GenExpr * gen_expr;
|
||||
TreeExpr *left, *right;
|
||||
|
||||
~TreeExpr();
|
||||
static TreeExpr *new_tree_expr( InfixOp *infix_op, GenExpr *gen_expr,
|
||||
TreeExpr *left, TreeExpr *right );
|
||||
TreeExpr *clone_tree_expr();
|
||||
float eval_tree_expr();
|
||||
};
|
||||
~TreeExpr();
|
||||
static TreeExpr *new_tree_expr( InfixOp *infix_op, GenExpr *gen_expr,
|
||||
TreeExpr *left, TreeExpr *right );
|
||||
TreeExpr *clone_tree_expr();
|
||||
float eval_tree_expr(int mesh_i, int mesh_j);
|
||||
};
|
||||
|
||||
/* A function expression in prefix form */
|
||||
class PrefunExpr {
|
||||
class PrefunExpr
|
||||
{
|
||||
public:
|
||||
float (*func_ptr)(void*);
|
||||
int num_args;
|
||||
GenExpr **expr_list;
|
||||
float (*func_ptr)(void*);
|
||||
int num_args;
|
||||
GenExpr **expr_list;
|
||||
|
||||
~PrefunExpr();
|
||||
PrefunExpr *clone_prefun_expr();
|
||||
float eval_prefun_expr();
|
||||
};
|
||||
~PrefunExpr();
|
||||
PrefunExpr *clone_prefun_expr();
|
||||
|
||||
/* Evaluates functions in prefix form */
|
||||
float eval_prefun_expr(int mesh_i, int mesh_j);
|
||||
|
||||
};
|
||||
|
||||
#endif /** _EXPR_H */
|
||||
|
||||
@ -35,12 +35,14 @@ inline void LoadUnspecInitCond::operator() (Param * param) {
|
||||
|
||||
/* If initial condition was not defined by the preset file, force a default one
|
||||
with the following code */
|
||||
if ((init_cond = m_initCondTree.splay_find(param->name)) == NULL) {
|
||||
|
||||
if (m_initCondTree.find(param->name) == m_initCondTree.end()) {
|
||||
|
||||
/* Make sure initial condition does not exist in the set of per frame initial equations */
|
||||
if ((init_cond = m_perFrameInitEqnTree.splay_find(param->name)) != NULL)
|
||||
return;
|
||||
if (m_perFrameInitEqnTree.find(param->name) != m_perFrameInitEqnTree.end())
|
||||
return;
|
||||
|
||||
// Set an initial vialue via correct union member
|
||||
if (param->type == P_TYPE_BOOL)
|
||||
init_val.bool_val = 0;
|
||||
|
||||
@ -56,10 +58,9 @@ inline void LoadUnspecInitCond::operator() (Param * param) {
|
||||
return;
|
||||
|
||||
/* Insert the initial condition into this presets tree */
|
||||
if (m_initCondTree.splay_insert(init_cond, init_cond->param->name) < 0) {
|
||||
delete init_cond;
|
||||
return;
|
||||
}
|
||||
/// @bug check the reult status of insert
|
||||
m_initCondTree.insert(std::make_pair(init_cond->param->name, init_cond));
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -41,9 +41,9 @@
|
||||
#include "wipemalloc.h"
|
||||
|
||||
/** Constructor */
|
||||
Param::Param( std::string name, short int type, short int flags, void * engine_val, void * matrix,
|
||||
Param::Param( std::string _name, short int type, short int flags, void * engine_val, void * matrix,
|
||||
CValue default_init_val, CValue upper_bound, CValue lower_bound):
|
||||
m_name(name),
|
||||
name(_name),
|
||||
type(type),
|
||||
flags (flags),
|
||||
matrix_flag (0),
|
||||
@ -61,11 +61,12 @@ Param::Param( std::string name, short int type, short int flags, void * engine_v
|
||||
|
||||
|
||||
/* Creates a user defined parameter */
|
||||
Param::Param(char * name) :
|
||||
Param::Param(std::string _name) :
|
||||
type(P_TYPE_DOUBLE),
|
||||
flags(P_FLAG_USERDEF),
|
||||
matrix_flag(0),
|
||||
matrix(0)
|
||||
matrix(0),
|
||||
name(_name)
|
||||
{
|
||||
|
||||
engine_val = new float();
|
||||
@ -73,12 +74,7 @@ Param::Param(char * name) :
|
||||
default_init_val.float_val = DEFAULT_DOUBLE_IV;
|
||||
upper_bound.float_val = DEFAULT_DOUBLE_UB;
|
||||
lower_bound.float_val = DEFAULT_DOUBLE_LB;
|
||||
|
||||
/* Copy given name into parameter structure */
|
||||
strncpy(this->name, name, MAX_TOKEN_SIZE-1);
|
||||
|
||||
(*(float*)this->engine_val) = DEFAULT_DOUBLE_IV;
|
||||
|
||||
|
||||
|
||||
/** @@FIX THIS */
|
||||
//this->gx = projectM::currentEngine->gx;
|
||||
@ -107,7 +103,7 @@ Param::~Param() {
|
||||
}
|
||||
}
|
||||
|
||||
if (PARAM_DEBUG) printf("free_param: freeing \"%s\".\n", name);
|
||||
if (PARAM_DEBUG) printf("free_param: freeing \"%s\".\n", name.c_str());
|
||||
}
|
||||
|
||||
/* Compare string name with parameter name */
|
||||
|
||||
@ -72,7 +72,7 @@ public:
|
||||
int gx, gy;
|
||||
|
||||
/* Function prototypes */
|
||||
Param(char *name, short int type, short int flags,
|
||||
Param(std::string name, short int type, short int flags,
|
||||
void * eqn_val, void *matrix,
|
||||
CValue default_init_val, CValue upper_bound,
|
||||
CValue lower_bound);
|
||||
@ -84,9 +84,6 @@ public:
|
||||
static int init_user_param_db();
|
||||
static int destroy_user_param_db();
|
||||
|
||||
int remove_param();
|
||||
//int insert_param( SplayTree *database );
|
||||
void load_unspec_init_cond();
|
||||
void load_unspec_init_cond_shape();
|
||||
|
||||
|
||||
|
||||
@ -15,15 +15,14 @@ class BuiltinParams;
|
||||
class ParamUtils
|
||||
{
|
||||
public:
|
||||
static void insert(Param * param, std::map<std::string,Param*> * paramTree)
|
||||
static bool insert(Param * param, std::map<std::string,Param*> * paramTree)
|
||||
{
|
||||
|
||||
assert(param);
|
||||
assert(paramTree);
|
||||
|
||||
|
||||
paramTree->insert(std::make_pair(param->name,param))
|
||||
;
|
||||
|
||||
return ((paramTree->insert(std::make_pair(param->name,param))).second);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -1337,7 +1337,7 @@ InitCond * Parser::parse_per_frame_init_eqn(FILE * fs, Preset * preset, std::map
|
||||
}
|
||||
|
||||
/* Compute initial condition value */
|
||||
val = gen_expr->eval_gen_expr();
|
||||
val = gen_expr->eval_gen_expr(-1,-1);
|
||||
|
||||
/* Free the general expression now that we are done with it */
|
||||
delete gen_expr;
|
||||
@ -1390,7 +1390,7 @@ int Parser::parse_wavecode(char * token, FILE * fs, Preset * preset) {
|
||||
/* token should be in the form wavecode_N_var, such as wavecode_1_samples */
|
||||
|
||||
/* Get id and variable name from token string */
|
||||
if (parse_wavecode_prefix(token, &id, &var_string) < 0)
|
||||
if (parse_wavecode_prefix(token, &id, &var_string) < 0)
|
||||
return PROJECTM_PARSE_ERROR;
|
||||
|
||||
//if (PARSE_DEBUG) printf("parse_wavecode: wavecode id = %d, parameter = \"%s\"\n", id, var_string);
|
||||
@ -1437,7 +1437,7 @@ int Parser::parse_wavecode(char * token, FILE * fs, Preset * preset) {
|
||||
return PROJECTM_FAILURE;
|
||||
}
|
||||
|
||||
custom_wave->init_cond_tree->insert(std::make_pair(param->name, init_cond));
|
||||
custom_wave->init_cond_tree.insert(std::make_pair(param->name, init_cond));
|
||||
|
||||
line_mode = CUSTOM_WAVE_WAVECODE_LINE_MODE;
|
||||
|
||||
@ -1518,7 +1518,7 @@ int Parser::parse_shapecode(char * token, FILE * fs, Preset * preset) {
|
||||
return PROJECTM_FAILURE;
|
||||
}
|
||||
|
||||
custom_shape->init_cond_tree->insert(std::make_pair(param->name,init_cond));
|
||||
custom_shape->init_cond_tree.insert(std::make_pair(param->name,init_cond));
|
||||
line_mode = CUSTOM_SHAPE_SHAPECODE_LINE_MODE;
|
||||
|
||||
//if (PARSE_DEBUG) printf("parse_shapecode: [success]\n");
|
||||
@ -1747,7 +1747,7 @@ int Parser::parse_wave_helper(FILE * fs, Preset * preset, int id, char * eqn_ty
|
||||
}
|
||||
|
||||
/* Insert the equation in the per frame equation tree */
|
||||
custom_wave->per_frame_init_eqn_tree->insert(std::make_pair(init_cond->param->name,init_cond));
|
||||
custom_wave->per_frame_init_eqn_tree.insert(std::make_pair(init_cond->param->name,init_cond));
|
||||
|
||||
if (update_string_buffer(custom_wave->per_frame_init_eqn_string_buffer,
|
||||
&custom_wave->per_frame_init_eqn_string_index) < 0) {
|
||||
@ -1804,7 +1804,7 @@ int Parser::parse_wave_helper(FILE * fs, Preset * preset, int id, char * eqn_ty
|
||||
return PROJECTM_FAILURE;
|
||||
}
|
||||
|
||||
custom_wave->per_frame_eqn_tree->insert(std::make_pair(per_frame_eqn->index, per_frame_eqn));
|
||||
custom_wave->per_frame_eqn_tree.insert(std::make_pair(per_frame_eqn->index, per_frame_eqn));
|
||||
//if (PARSE_DEBUG) printf("parse_wave (per_frame): equation %d associated with custom wave %d [success]\n",
|
||||
// per_frame_eqn->index, custom_wave->id);
|
||||
|
||||
@ -1837,14 +1837,14 @@ int Parser::parse_wave_helper(FILE * fs, Preset * preset, int id, char * eqn_ty
|
||||
}
|
||||
}
|
||||
|
||||
/* Parse right side of equation as an expression */
|
||||
/* Parse right side of equation as an expression, First tell parser we are parsing a custom wave */
|
||||
current_wave = custom_wave;
|
||||
if ((gen_expr = parse_gen_expr(fs, NULL, preset)) == NULL) {
|
||||
if (PARSE_DEBUG) printf("parse_wave_helper (per_point): equation evaluated to null? (LINE %d)\n", line_count);
|
||||
|
||||
return PROJECTM_PARSE_ERROR;
|
||||
}
|
||||
current_wave = NULL;
|
||||
|
||||
|
||||
/* Add the per point equation */
|
||||
if (custom_wave->add_per_point_eqn(string, gen_expr) < 0) {
|
||||
@ -1852,7 +1852,8 @@ int Parser::parse_wave_helper(FILE * fs, Preset * preset, int id, char * eqn_ty
|
||||
|
||||
return PROJECTM_PARSE_ERROR;
|
||||
}
|
||||
|
||||
// This tells the parser we are no longer parsing a custom wave
|
||||
current_wave = NULL;
|
||||
|
||||
if (update_string_buffer(custom_wave->per_point_eqn_string_buffer, &custom_wave->per_point_eqn_string_index) < 0)
|
||||
return PROJECTM_FAILURE;
|
||||
@ -2009,7 +2010,7 @@ int Parser::parse_shape_per_frame_init_eqn(FILE * fs, CustomShape * custom_shape
|
||||
}
|
||||
|
||||
/* Insert the equation in the per frame equation tree */
|
||||
custom_shape->per_frame_init_eqn_tree->insert(std::make_pair(init_cond->param->name,init_cond));
|
||||
custom_shape->per_frame_init_eqn_tree.insert(std::make_pair(init_cond->param->name,init_cond));
|
||||
if (update_string_buffer(custom_shape->per_frame_init_eqn_string_buffer,
|
||||
&custom_shape->per_frame_init_eqn_string_index) < 0)
|
||||
return PROJECTM_FAILURE;
|
||||
@ -2066,7 +2067,7 @@ char string[MAX_TOKEN_SIZE];
|
||||
return PROJECTM_FAILURE;
|
||||
}
|
||||
|
||||
custom_shape->per_frame_eqn_tree->insert(std::make_pair(per_frame_eqn->index, per_frame_eqn));
|
||||
custom_shape->per_frame_eqn_tree.insert(std::make_pair(per_frame_eqn->index, per_frame_eqn));
|
||||
|
||||
/* Need to add stuff to string buffer so the editor can read the equations.
|
||||
Why not make a nice little helper function for this? - here it is: */
|
||||
@ -2126,7 +2127,7 @@ char string[MAX_TOKEN_SIZE];
|
||||
return PROJECTM_FAILURE;
|
||||
}
|
||||
|
||||
custom_wave->per_frame_eqn_tree->insert(std::make_pair(per_frame_eqn->index, per_frame_eqn));
|
||||
custom_wave->per_frame_eqn_tree.insert(std::make_pair(per_frame_eqn->index, per_frame_eqn));
|
||||
//if (PARSE_DEBUG) printf("parse_shape (per_frame): equation %d associated with custom shape %d [success]\n",
|
||||
// per_frame_eqn->index, custom_shape->id);
|
||||
|
||||
|
||||
@ -38,12 +38,13 @@
|
||||
void PerFrameEqn::evaluate() {
|
||||
|
||||
if (PER_FRAME_EQN_DEBUG) {
|
||||
printf("per_frame_%d=%s= ", index, param->name);
|
||||
printf("per_frame_%d=%s= ", index, param->name.c_str());
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
//*((float*)per_frame_eqn->param->engine_val) = eval_gen_expr(per_frame_eqn->gen_expr);
|
||||
param->set_param(gen_expr->eval_gen_expr());
|
||||
|
||||
param->set_param(gen_expr->eval_gen_expr(-1,-1));
|
||||
if (PER_FRAME_EQN_DEBUG) printf(" = %.4f\n", *((float*)param->engine_val));
|
||||
|
||||
}
|
||||
|
||||
@ -35,7 +35,7 @@
|
||||
#include <map>
|
||||
|
||||
#include "wipemalloc.h"
|
||||
|
||||
#include <cassert>
|
||||
/* Evaluates a per pixel equation */
|
||||
void PerPixelEqn::evaluate() {
|
||||
|
||||
@ -46,8 +46,8 @@ void PerPixelEqn::evaluate() {
|
||||
eqn_ptr = gen_expr;
|
||||
if (param->matrix == NULL) {
|
||||
if (PER_PIXEL_EQN_DEBUG) printf("evalPerPixelEqn: [begin initializing matrix] (index = %d) (name = %s)\n",
|
||||
index, param->name);
|
||||
|
||||
index, param->name.c_str());
|
||||
|
||||
param_matrix = (float**)wipemalloc(param->gx*sizeof(float*));
|
||||
param->matrix = param_matrix;
|
||||
|
||||
@ -58,10 +58,6 @@ void PerPixelEqn::evaluate() {
|
||||
for (y = 0; y < param->gy; y++)
|
||||
param_matrix[x][y] = 0.0;
|
||||
|
||||
if (param->name == NULL)
|
||||
printf("null parameter?\n");
|
||||
|
||||
// printf("PARAM MATRIX: \"%s\" initialized.\n", per_pixel_eqn->param->name);
|
||||
}
|
||||
else
|
||||
param_matrix = (float**)param->matrix;
|
||||
@ -70,23 +66,23 @@ void PerPixelEqn::evaluate() {
|
||||
printf("something is seriously wrong...\n");
|
||||
|
||||
// param->matrix_flag = 0; /** Force matrix ignore to update time */
|
||||
for (projectM::currentEngine->mesh_i = 0; projectM::currentEngine->mesh_i < param->gx; projectM::currentEngine->mesh_i++) {
|
||||
for (projectM::currentEngine->mesh_j = 0; projectM::currentEngine->mesh_j < param->gy; projectM::currentEngine->mesh_j++) {
|
||||
param_matrix[projectM::currentEngine->mesh_i][projectM::currentEngine->mesh_j] = eqn_ptr->eval_gen_expr();
|
||||
for (int mesh_i = 0; mesh_i < param->gx; mesh_i++) {
|
||||
for (int mesh_j = 0; mesh_j < param->gy; mesh_j++) {
|
||||
param_matrix[mesh_i][mesh_j] = eqn_ptr->eval_gen_expr(mesh_i, mesh_j);
|
||||
}
|
||||
}
|
||||
|
||||
/* Now that this parameter has been referenced with a per
|
||||
pixel equation, we let the evaluator know by setting
|
||||
this flag */
|
||||
param->matrix_flag = 1;
|
||||
param->matrix_flag = true;
|
||||
param->flags |= P_FLAG_PER_PIXEL;
|
||||
}
|
||||
|
||||
PerPixelEqn(int _index, Param * _param, GenExrp *_gen_expr):index(_index), param(_param), gen_expr(_gen_expr) {
|
||||
PerPixelEqn::PerPixelEqn(int _index, Param * _param, GenExpr * _gen_expr):index(_index), param(_param), gen_expr(_gen_expr) {
|
||||
|
||||
assert(index >= 0);
|
||||
assert(param != NULL);
|
||||
assert(gen_expr != null);
|
||||
assert(param != 0);
|
||||
assert(gen_expr != 0);
|
||||
}
|
||||
|
||||
|
||||
@ -39,47 +39,46 @@
|
||||
#include "wipemalloc.h"
|
||||
|
||||
/* Evaluates a per point equation for the current custom wave given by interface_wave ptr */
|
||||
void PerPointEqn::evalPerPointEqn() {
|
||||
void PerPointEqn::evaluate() {
|
||||
|
||||
int samples, size;
|
||||
int size;
|
||||
float * param_matrix;
|
||||
GenExpr * eqn_ptr;
|
||||
abort();
|
||||
|
||||
// samples = CustomWave::interface_wave->samples;
|
||||
|
||||
eqn_ptr = gen_expr;
|
||||
|
||||
if (param->matrix == NULL) {
|
||||
|
||||
if ((param_matrix = (float*) (param->matrix = wipemalloc(size = samples*sizeof(float)))) == NULL)
|
||||
return;
|
||||
|
||||
memset(param_matrix, 0, size);
|
||||
}
|
||||
else
|
||||
param_matrix = (float*)param->matrix;
|
||||
|
||||
|
||||
|
||||
for (projectM::currentEngine->mesh_i = 0; projectM::currentEngine->mesh_i < samples; projectM::currentEngine->mesh_i++) {
|
||||
param_matrix[projectM::currentEngine->mesh_i] = eqn_ptr->eval_gen_expr();
|
||||
for (int i = 0; i < samples; i++) {
|
||||
// -1 is because per points only use one dimension
|
||||
param_matrix[i] = eqn_ptr->eval_gen_expr(i, -1);
|
||||
}
|
||||
|
||||
|
||||
/* Now that this parameter has been referenced with a per
|
||||
point equation, we let the evaluator know by setting
|
||||
this flag */
|
||||
param->matrix_flag = 1;
|
||||
if (!param->matrix_flag)
|
||||
param->matrix_flag = true;
|
||||
}
|
||||
|
||||
PerPointEqn * PerPointEqn::new_per_point_eqn(int index, Param * param, GenExpr * gen_expr) {
|
||||
PerPointEqn * per_point_eqn = NULL;
|
||||
if (param == NULL)
|
||||
return NULL;
|
||||
if (gen_expr == NULL)
|
||||
return NULL;
|
||||
if ((per_point_eqn = (PerPointEqn*)wipemalloc(sizeof(PerPointEqn))) == NULL)
|
||||
return NULL;
|
||||
|
||||
per_point_eqn->index = index;
|
||||
per_point_eqn->gen_expr = gen_expr;
|
||||
per_point_eqn->param = param;
|
||||
return per_point_eqn;
|
||||
}
|
||||
PerPointEqn::PerPointEqn(int _index, Param * _param, GenExpr * _gen_expr, int _samples):
|
||||
index(_index),
|
||||
param(_param),
|
||||
gen_expr(_gen_expr),
|
||||
samples(_samples)
|
||||
{}
|
||||
|
||||
|
||||
PerPointEqn::~PerPointEqn() {
|
||||
|
||||
@ -37,12 +37,13 @@ class PerPointEqn;
|
||||
class PerPointEqn {
|
||||
public:
|
||||
int index;
|
||||
int samples; // the number of samples to iterate over
|
||||
Param *param;
|
||||
GenExpr * gen_expr;
|
||||
|
||||
|
||||
~PerPointEqn();
|
||||
void evalPerPointEqn();
|
||||
static PerPointEqn *new_per_point_eqn( int index, Param *param, GenExpr *gen_expr);
|
||||
void evaluate();
|
||||
PerPointEqn( int index, Param *param, GenExpr *gen_expr, int samples);
|
||||
};
|
||||
|
||||
|
||||
|
||||
@ -70,7 +70,7 @@ Preset::~Preset()
|
||||
Algorithms::traverse<Algorithms::TraverseFunctors::DeleteFunctor<PerFrameEqn> >(*per_frame_eqn_tree);
|
||||
delete per_frame_eqn_tree;
|
||||
|
||||
Algorithms::traverse<Algorithms::TraverseFunctors::DeleteFunctor<Param> >(user_param_tree);
|
||||
Algorithms::traverse<Algorithms::TraverseFunctors::DeleteFunctor<Param> >(*user_param_tree);
|
||||
delete user_param_tree;
|
||||
|
||||
/// @note no need to clear the actual container itself
|
||||
@ -204,11 +204,11 @@ void Preset::evalCustomWavePerFrameEquations()
|
||||
for (PresetOutputs::cwave_container::iterator pos = customWaves->begin(); pos != customWaves->end(); ++pos)
|
||||
{
|
||||
|
||||
std::map<std::string, InitCond*> & init_cond_tree = *(*pos)->init_cond_tree;
|
||||
std::map<std::string, InitCond*> & init_cond_tree = (*pos)->init_cond_tree;
|
||||
for (std::map<std::string, InitCond*>::iterator _pos = init_cond_tree.begin(); _pos != init_cond_tree.end(); ++_pos)
|
||||
_pos->second->evaluate();
|
||||
|
||||
std::map<int, PerFrameEqn*> & per_frame_eqn_tree = *(*pos)->per_frame_eqn_tree;
|
||||
std::map<int, PerFrameEqn*> & per_frame_eqn_tree = (*pos)->per_frame_eqn_tree;
|
||||
for (std::map<int, PerFrameEqn*>::iterator _pos = per_frame_eqn_tree.begin(); _pos != per_frame_eqn_tree.end(); ++_pos)
|
||||
_pos->second->evaluate();
|
||||
}
|
||||
@ -221,11 +221,11 @@ void Preset::evalCustomShapePerFrameEquations()
|
||||
for (PresetOutputs::cshape_container::iterator pos = customShapes->begin(); pos != customShapes->end(); ++pos)
|
||||
{
|
||||
|
||||
std::map<std::string, InitCond*> & init_cond_tree = *(*pos)->init_cond_tree;
|
||||
std::map<std::string, InitCond*> & init_cond_tree = (*pos)->init_cond_tree;
|
||||
for (std::map<std::string, InitCond*>::iterator _pos = init_cond_tree.begin(); _pos != init_cond_tree.end(); ++_pos)
|
||||
_pos->second->evaluate();
|
||||
|
||||
std::map<int, PerFrameEqn*> & per_frame_eqn_tree = *(*pos)->per_frame_eqn_tree;
|
||||
std::map<int, PerFrameEqn*> & per_frame_eqn_tree = (*pos)->per_frame_eqn_tree;
|
||||
for (std::map<int, PerFrameEqn*>::iterator _pos = per_frame_eqn_tree.begin(); _pos != per_frame_eqn_tree.end(); ++_pos)
|
||||
_pos->second->evaluate();
|
||||
}
|
||||
@ -234,21 +234,21 @@ void Preset::evalCustomShapePerFrameEquations()
|
||||
|
||||
void Preset::evalInitConditions()
|
||||
{
|
||||
|
||||
for (std::map<std::string, InitCond*>::iterator pos = per_frame_init_eqn_tree->begin(); pos != per_frame_init_eqn_tree->end(); ++pos)
|
||||
pos->second->evaluate();
|
||||
|
||||
for (std::map<std::string, InitCond*>::iterator pos = per_frame_init_eqn_tree->begin(); pos != per_frame_init_eqn_tree->end(); ++pos)
|
||||
pos->second->evaluate();
|
||||
|
||||
}
|
||||
|
||||
void Preset::evalPerFrameEquations()
|
||||
{
|
||||
|
||||
for (std::map<std::string, InitCond*>::iterator pos = init_cond_tree->begin(); pos != init_cond_tree->end(); ++pos)
|
||||
pos->second->evaluate();
|
||||
for (std::map<std::string, InitCond*>::iterator pos = init_cond_tree->begin(); pos != init_cond_tree->end(); ++pos)
|
||||
pos->second->evaluate();
|
||||
|
||||
for (std::map<int, PerFrameEqn*>::iterator pos = per_frame_eqn_tree->begin(); pos != per_frame_eqn_tree->end(); ++pos)
|
||||
pos->second->evaluate();
|
||||
|
||||
for (std::map<int, PerFrameEqn*>::iterator pos = per_frame_eqn_tree->begin(); pos != per_frame_eqn_tree->end(); ++pos)
|
||||
pos->second->evaluate();
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -261,7 +261,7 @@ void Preset::initialize(const std::string & pathname)
|
||||
this->per_frame_eqn_tree = new std::map<int, PerFrameEqn*>();
|
||||
this->per_pixel_eqn_tree = new std::map<int, PerPixelEqn*>();
|
||||
this->per_frame_init_eqn_tree = new std::map<std::string,InitCond*>();
|
||||
|
||||
|
||||
memset(this->per_pixel_flag, 0, sizeof(int)*NUM_OPS);
|
||||
|
||||
/* Set initial index values */
|
||||
@ -474,17 +474,17 @@ int Preset::write_per_pixel_equations(FILE * fs)
|
||||
void Preset::load_custom_wave_init_conditions()
|
||||
{
|
||||
for (PresetOutputs::cwave_container::iterator pos = customWaves->begin(); pos != customWaves->end(); ++pos)
|
||||
(*pos)->load_unspec_init_cond();
|
||||
(*pos)->load_unspec_init_cond();
|
||||
|
||||
}
|
||||
|
||||
void Preset::load_custom_shape_init_conditions()
|
||||
{
|
||||
|
||||
// void eval_custom_shape_init_conds();
|
||||
// void eval_custom_shape_init_conds();
|
||||
|
||||
for (PresetOutputs::cshape_container::iterator pos = customShapes->begin(); pos != customShapes->end(); ++pos)
|
||||
(*pos)->load_unspec_init_cond_shape();
|
||||
(*pos)->load_unspec_init_cond_shape();
|
||||
}
|
||||
|
||||
|
||||
@ -510,7 +510,9 @@ void Preset::evalPerPixelEqns()
|
||||
{
|
||||
|
||||
/* Evaluate all per pixel equations using splay traversal */
|
||||
per_pixel_eqn_tree->splay_traverse((void (*)(void*))eval_per_pixel_eqn_helper);
|
||||
for (std::map<int, PerPixelEqn*>::iterator pos = per_pixel_eqn_tree->begin();
|
||||
pos != per_pixel_eqn_tree->end(); ++pos)
|
||||
pos->second->evaluate();
|
||||
|
||||
/* Set mesh i / j values to -1 so engine vars are used by default again */
|
||||
this->mesh_i = -1;
|
||||
@ -544,12 +546,13 @@ InitCond * Preset::get_init_cond( Param *param )
|
||||
InitCond * init_cond;
|
||||
CValue init_val;
|
||||
|
||||
if ( param == NULL )
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
assert(param);
|
||||
|
||||
if ((init_cond = (InitCond*)(init_cond_tree->splay_find(param->name))) == NULL)
|
||||
std::map<std::string, InitCond*>::iterator pos = init_cond_tree->find(param->name);
|
||||
|
||||
init_cond = pos == init_cond_tree->end() ? 0 : pos->second;
|
||||
|
||||
if (init_cond == NULL)
|
||||
{
|
||||
|
||||
if (param->type == P_TYPE_BOOL)
|
||||
@ -566,7 +569,10 @@ InitCond * Preset::get_init_cond( Param *param )
|
||||
return NULL;
|
||||
|
||||
/* Insert the initial condition into this presets tree */
|
||||
if (init_cond_tree->splay_insert(init_cond, init_cond->param->name) < 0)
|
||||
std::pair<std::map<std::string, InitCond*>::iterator, bool> inserteePair =
|
||||
init_cond_tree->insert(std::make_pair(init_cond->param->name, init_cond));
|
||||
|
||||
if (!inserteePair.second)
|
||||
{
|
||||
delete init_cond;
|
||||
return NULL;
|
||||
@ -749,7 +755,12 @@ Param * Preset::find(char * name, int flags)
|
||||
/* If the search failed, check the user database */
|
||||
if (param == NULL)
|
||||
{
|
||||
param = (Param*)this->user_param_tree->splay_find(name);
|
||||
std::map<std::string, Param*>::iterator pos = user_param_tree->find(name);
|
||||
|
||||
if (pos == user_param_tree->end())
|
||||
param = 0;
|
||||
else
|
||||
param = pos->second;
|
||||
}
|
||||
|
||||
/* If it doesn't exist in the user (or builtin) database and
|
||||
@ -772,9 +783,12 @@ Param * Preset::find(char * name, int flags)
|
||||
return NULL;
|
||||
}
|
||||
/* Finally, insert the new parameter into this preset's proper splaytree */
|
||||
if (this->user_param_tree->splay_insert(param, param->name) < 0)
|
||||
std::pair<std::map<std::string, Param*>::iterator, bool> inserteePair
|
||||
= user_param_tree->insert(std::make_pair(param->name, param));
|
||||
|
||||
if (!inserteePair.second)
|
||||
{
|
||||
if (PARAM_DEBUG) printf("PARAM \"%s\" already exists in user parameter tree!\n", param->name);
|
||||
if (PARAM_DEBUG) printf("PARAM \"%s\" already exists in user parameter tree!\n", param->name.c_str());
|
||||
delete param;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -1,639 +0,0 @@
|
||||
/**
|
||||
* projectM -- Milkdrop-esque visualisation SDK
|
||||
* Copyright (C)2003-2007 projectM Team
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* See 'LICENSE.txt' included within this release
|
||||
*
|
||||
*/
|
||||
/**
|
||||
* $Id$
|
||||
*
|
||||
* Splay tree
|
||||
*
|
||||
* $Log$
|
||||
*/
|
||||
|
||||
#ifndef _SPLAYTREE_HPP
|
||||
#define _SPLAYTREE_HPP
|
||||
|
||||
#define PERFECT_MATCH 0
|
||||
#define CLOSEST_MATCH 1
|
||||
|
||||
#include "SplayNode.hpp"
|
||||
#include "compare.h"
|
||||
#include "fatal.h"
|
||||
|
||||
#define SPLAYTEE_DUMP_FILE "./splay-dump"
|
||||
|
||||
template <class Data>
|
||||
class SplayTree {
|
||||
|
||||
public:
|
||||
static const int SPLAYTREE_FAILURE = PROJECTM_FAILURE;
|
||||
static const int SPLAYTREE_SUCCESS = PROJECTM_SUCCESS;
|
||||
SplayNode<Data> *root;
|
||||
int (*compare)(const void*,const void*);
|
||||
void * (*copy_key)(void *);
|
||||
void (*free_key)(void*);
|
||||
|
||||
static SplayTree<Data> *create_splaytree(int (*compare)(const void*,const void*), void * (*copy_key)(void*), void (*free_key)(void*));
|
||||
~SplayTree();
|
||||
|
||||
Data * splay_find(const void * key);
|
||||
int splay_insert(Data * data, void * key);
|
||||
int splay_insert_node( SplayNode<Data> *node );
|
||||
int splay_insert_link(void * alias_key, void * orig_key);
|
||||
int splay_delete(void * key);
|
||||
SplayNode<Data> *splay_delete_helper( void *key, SplayNode<Data> *node,
|
||||
int (*compare)(const void *,const void*),
|
||||
void (*free_key)(void*) );
|
||||
int splay_size();
|
||||
int splay_rec_size( SplayNode<Data> *node );
|
||||
|
||||
SplayNode<Data> *splay( const void *key, SplayNode<Data> *t, int *match_type, int (*compare)(const void *,const void *) );
|
||||
|
||||
/** Traverses the entire splaytree in order given a function pointer
|
||||
* @deprecated Use the traverse method instead
|
||||
*/
|
||||
void splay_traverse(void (*func_ptr)(void*));
|
||||
|
||||
|
||||
SplayNode<Data> *get_splaynode_of(void * key);
|
||||
void *splay_find_above_min(void * key);
|
||||
void splay_find_above_min_helper( void *max_key, void **closest_key,
|
||||
SplayNode<Data> *root, int (*compare)(void *,void *));
|
||||
void *splay_find_below_max(void * key);
|
||||
void splay_find_below_max_helper( void *min_key, void **closest_key,
|
||||
SplayNode<Data> *root, int (*compare)(void *,void *));
|
||||
Data *splay_find_min();
|
||||
Data *splay_find_max();
|
||||
|
||||
/** Traverses the splay tree at each node in order with the passed in functor */
|
||||
template <class Fun>
|
||||
void traverse(Fun & functor);
|
||||
|
||||
/** Traverses the splay tree at each node in order by constructing a functor on the fly
|
||||
* and using it to traverse the entire tree. This is a convenience function for functors that don't return
|
||||
* any useful state to the caller. Note that the functor is assumed to take one template type which
|
||||
* matches the datatype of the splay tree. See implementation for more details.
|
||||
*/
|
||||
template <class Fun>
|
||||
void traverse();
|
||||
|
||||
private:
|
||||
void splay_traverse_helper (void (*func_ptr)(void*), SplayNode<Data> * splaynode);
|
||||
|
||||
template <class Fun>
|
||||
void traverseRec(Fun & fun, SplayNode<Data> * splaynode);
|
||||
};
|
||||
|
||||
|
||||
|
||||
/* Creates a splay tree given a compare key function, copy key function, and free key function.
|
||||
Ah yes, the wonders of procedural programming */
|
||||
template <class Data>
|
||||
SplayTree<Data> * SplayTree<Data>::create_splaytree(int (*compare)(const void *,const void*), void * (*copy_key)(void *), void (*free_key)(void*)) {
|
||||
|
||||
SplayTree * splaytree;
|
||||
|
||||
/* Allocate memory for the splaytree struct */
|
||||
if ((splaytree = (SplayTree*)malloc(sizeof(SplayTree))) == NULL)
|
||||
return NULL;
|
||||
|
||||
/* Set struct entries */
|
||||
splaytree->root = NULL;
|
||||
splaytree->compare = compare;
|
||||
splaytree->copy_key = copy_key;
|
||||
splaytree->free_key = free_key;
|
||||
|
||||
/* Return instantiated splay tree */
|
||||
return splaytree;
|
||||
}
|
||||
|
||||
/* Destroys a splay tree */
|
||||
template <class Data>
|
||||
SplayTree<Data>::~SplayTree() {
|
||||
|
||||
/* Recursively free all splaynodes in tree */
|
||||
if ( root != NULL ) {
|
||||
delete root;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template <class Data>
|
||||
template <class Fun>
|
||||
void SplayTree<Data>::traverse(Fun & functor) {
|
||||
|
||||
/* Call recursive helper function */
|
||||
traverseRec(functor, root);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
template <class Data>
|
||||
template <class Fun>
|
||||
void SplayTree<Data>::traverse() {
|
||||
|
||||
Fun functor;
|
||||
/* Call recursive helper function */
|
||||
traverseRec(functor, root);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* Traverses the entire splay tree with the given function func_ptr */
|
||||
template <class Data>
|
||||
void SplayTree<Data>::splay_traverse(void (*func_ptr)(void*)) {
|
||||
|
||||
/* Null argument check */
|
||||
if (func_ptr == NULL)
|
||||
return;
|
||||
|
||||
/* Call recursive helper function */
|
||||
splay_traverse_helper(func_ptr, root );
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* Helper function to traverse the entire splaytree */
|
||||
template <class Data>
|
||||
void SplayTree<Data>::splay_traverse_helper (void (*func_ptr)(void *), SplayNode<Data> * splaynode) {
|
||||
|
||||
/* Normal if this happens, its a base case of recursion */
|
||||
if (splaynode == NULL)
|
||||
return;
|
||||
|
||||
/* Recursively traverse to the left */
|
||||
splay_traverse_helper(func_ptr, splaynode->left);
|
||||
|
||||
|
||||
func_ptr(splaynode->data);
|
||||
|
||||
/* Recursively traverse to the right */
|
||||
splay_traverse_helper(func_ptr, splaynode->right);
|
||||
|
||||
/* Done */
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/* Helper function to traverse the entire splaytree */
|
||||
template <class Data>
|
||||
template <class Fun>
|
||||
void SplayTree<Data>::traverseRec (Fun & fun, SplayNode<Data> * splaynode) {
|
||||
|
||||
/* Normal if this happens, its a base case of recursion */
|
||||
if (splaynode == NULL)
|
||||
return;
|
||||
|
||||
/* Recursively traverse to the left */
|
||||
traverseRec(fun, splaynode->left);
|
||||
|
||||
fun(splaynode->data);
|
||||
|
||||
/* Recursively traverse to the right */
|
||||
traverseRec(fun, splaynode->right);
|
||||
|
||||
/* Done */
|
||||
return;
|
||||
}
|
||||
/* Find the node corresponding to the given key in splaytree, return its data pointer */
|
||||
template <class Data>
|
||||
Data * SplayTree<Data>::splay_find(const void * key) {
|
||||
|
||||
SplayNode<Data> * splaynode;
|
||||
int match_type;
|
||||
|
||||
if (key == NULL)
|
||||
return NULL;
|
||||
|
||||
splaynode = root;
|
||||
|
||||
/* Bring the targeted splay node to the top of the splaytree */
|
||||
splaynode = splay(key, splaynode, &match_type, compare);
|
||||
root = splaynode;
|
||||
|
||||
/* We only want perfect matches, so return null when match isn't perfect */
|
||||
if (match_type == CLOSEST_MATCH)
|
||||
return NULL;
|
||||
|
||||
/* This shouldn't happen because of the match type check, but whatever */
|
||||
if (root == NULL)
|
||||
return NULL;
|
||||
|
||||
return root->data;
|
||||
|
||||
}
|
||||
|
||||
/* Gets the splaynode that the given key points to */
|
||||
template <class Data>
|
||||
SplayNode<Data> * SplayTree<Data>::get_splaynode_of(void * key) {
|
||||
|
||||
SplayNode<Data> * splaynode;
|
||||
int match_type;
|
||||
|
||||
/* Null argument checks */
|
||||
if (key == NULL)
|
||||
return NULL;
|
||||
|
||||
splaynode = root;
|
||||
|
||||
/* Find the splaynode */
|
||||
splaynode = splay(key, splaynode, &match_type, compare);
|
||||
root = splaynode;
|
||||
|
||||
/* Only perfect matches are valid */
|
||||
if (match_type == CLOSEST_MATCH)
|
||||
return NULL;
|
||||
|
||||
/* Return the perfect match splay node */
|
||||
return splaynode;
|
||||
}
|
||||
|
||||
/* Finds the desired node, and changes the tree such that it is the root */
|
||||
template <class Data>
|
||||
SplayNode<Data> * SplayTree<Data>::splay (const void * key, SplayNode<Data> * t, int * match_type, int (*compare)(const void*,const void*)) {
|
||||
|
||||
/* Simple top down splay, not requiring key to be in the tree t.
|
||||
What it does is described above. */
|
||||
|
||||
SplayNode<Data> N, *l, *r, *y;
|
||||
*match_type = CLOSEST_MATCH;
|
||||
|
||||
if (t == NULL) return t;
|
||||
N.left = N.right = NULL;
|
||||
l = r = &N;
|
||||
|
||||
for (;;) {
|
||||
if (compare(key, t->key) < 0) {
|
||||
if (t->left == NULL) break;
|
||||
if (compare(key, t->left->key) < 0) {
|
||||
y = t->left; /* rotate right */
|
||||
t->left = y->right;
|
||||
y->right = t;
|
||||
t = y;
|
||||
if (t->left == NULL) break;
|
||||
}
|
||||
r->left = t; /* link right */
|
||||
r = t;
|
||||
t = t->left;
|
||||
} else if (compare(key, t->key) > 0) {
|
||||
if (t->right == NULL) break;
|
||||
if (compare(key, t->right->key) > 0) {
|
||||
y = t->right; /* rotate left */
|
||||
t->right = y->left;
|
||||
y->left = t;
|
||||
t = y;
|
||||
if (t->right == NULL) break;
|
||||
}
|
||||
l->right = t; /* link left */
|
||||
l = t;
|
||||
t = t->right;
|
||||
} else {
|
||||
*match_type = PERFECT_MATCH;
|
||||
break;
|
||||
}
|
||||
}
|
||||
l->right = t->left; /* assemble */
|
||||
r->left = t->right;
|
||||
t->left = N.right;
|
||||
t->right = N.left;
|
||||
|
||||
return t;
|
||||
|
||||
//return NULL;
|
||||
}
|
||||
|
||||
/* Deletes a splay node from a splay tree. If the node doesn't exist
|
||||
then nothing happens */
|
||||
template <class Data>
|
||||
int SplayTree<Data>::splay_delete(void * key) {
|
||||
|
||||
SplayNode<Data> * splaynode;
|
||||
|
||||
/* Use helper function to delete the node and return the resulting tree */
|
||||
if ((splaynode = splay_delete_helper(key, root, compare, free_key)) == NULL)
|
||||
return SPLAYTREE_FAILURE;
|
||||
|
||||
/* Set new splaytree root equal to the returned splaynode after deletion */
|
||||
root = splaynode;
|
||||
|
||||
/* Finished, no errors */
|
||||
return SPLAYTREE_SUCCESS;
|
||||
}
|
||||
|
||||
/* Deletes a splay node */
|
||||
template <class Data>
|
||||
SplayNode<Data> * SplayTree<Data>::splay_delete_helper(void * key, SplayNode<Data> * splaynode,
|
||||
int (*compare)(const void*,const void*), void (*free_key)(void*)) {
|
||||
|
||||
SplayNode<Data> * new_root;
|
||||
int match_type;
|
||||
|
||||
/* Argument check */
|
||||
if (splaynode == NULL)
|
||||
return NULL;
|
||||
|
||||
splaynode = splay(key, splaynode, &match_type, compare);
|
||||
|
||||
/* If entry wasn't found, quit here */
|
||||
if (match_type == CLOSEST_MATCH)
|
||||
return NULL;
|
||||
|
||||
/* If the targeted node's left pointer is null, then set the new root
|
||||
equal to the splaynode's right child */
|
||||
if (splaynode->left == NULL) {
|
||||
new_root = splaynode->right;
|
||||
}
|
||||
|
||||
/* Otherwise, do something I don't currently understand */
|
||||
else {
|
||||
new_root = splay(key, splaynode->left, &match_type, compare);
|
||||
new_root->right = splaynode->right;
|
||||
}
|
||||
|
||||
/* Set splay nodes children pointers to null */
|
||||
splaynode->left = splaynode->right = NULL;
|
||||
|
||||
/* Free the splaynode (and only this node since its children are now empty */
|
||||
delete splaynode;
|
||||
|
||||
/* Return the resulting tree */
|
||||
return new_root;
|
||||
|
||||
}
|
||||
|
||||
/* Inserts 'data' into the 'splaytree' paired with the passed 'key' */
|
||||
|
||||
template <class Data>
|
||||
int SplayTree<Data>::splay_insert(Data * data, void * key) {
|
||||
|
||||
SplayNode<Data> * splaynode;
|
||||
void * key_clone;
|
||||
|
||||
/* Null argument checks */
|
||||
if (key == NULL) {
|
||||
printf ("splay_insert: null key as argument, returning failure\n");
|
||||
return SPLAYTREE_FAILURE;
|
||||
}
|
||||
/* Clone the key argument */
|
||||
key_clone = copy_key(key);
|
||||
|
||||
/* Create a new splaynode (of regular type) */
|
||||
if ((splaynode = new SplayNode<Data>(key_clone, data, free_key)) == NULL) {
|
||||
free_key(key_clone);
|
||||
printf ("splay_insert: out of memory?\n");
|
||||
return PROJECTM_OUTOFMEM_ERROR;
|
||||
}
|
||||
|
||||
/* Inserts the splaynode into the splaytree */
|
||||
if (splay_insert_node(splaynode) < 0) {
|
||||
printf ("splay_insert: failed to insert node.\n");
|
||||
splaynode->left=splaynode->right=NULL;
|
||||
delete splaynode;
|
||||
return SPLAYTREE_FAILURE;
|
||||
}
|
||||
|
||||
|
||||
return SPLAYTREE_SUCCESS;
|
||||
}
|
||||
|
||||
/* Helper function to insert splaynodes into the splaytree */
|
||||
template <class Data>
|
||||
int SplayTree<Data>::splay_insert_node(SplayNode<Data> * splaynode) {
|
||||
int match_type;
|
||||
int cmpval;
|
||||
void * key;
|
||||
SplayNode<Data> * t;
|
||||
|
||||
/* Null argument checks */
|
||||
if (splaynode == NULL)
|
||||
return SPLAYTREE_FAILURE;
|
||||
|
||||
key = splaynode->key;
|
||||
|
||||
t = root;
|
||||
|
||||
|
||||
/* Root is null, insert splaynode here */
|
||||
if (t == NULL) {
|
||||
splaynode->left = splaynode->right = NULL;
|
||||
root = splaynode;
|
||||
return SPLAYTREE_SUCCESS;
|
||||
|
||||
}
|
||||
|
||||
t = splay(key, t, &match_type, compare);
|
||||
|
||||
if ((cmpval = compare(key,t->key)) < 0) {
|
||||
splaynode->left = t->left;
|
||||
splaynode->right = t;
|
||||
t->left = NULL;
|
||||
root = splaynode;
|
||||
return SPLAYTREE_SUCCESS;
|
||||
|
||||
}
|
||||
|
||||
else if (cmpval > 0) {
|
||||
splaynode->right = t->right;
|
||||
splaynode->left = t;
|
||||
t->right = NULL;
|
||||
root = splaynode;
|
||||
return SPLAYTREE_SUCCESS;
|
||||
}
|
||||
|
||||
/* Item already exists in tree, don't reinsert */
|
||||
else {
|
||||
printf("splay_insert_node: duplicate key detected, ignoring...\n");
|
||||
return SPLAYTREE_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
/* Returns the 'maximum' key that is less than the given key in the splaytree */
|
||||
template <class Data>
|
||||
void * SplayTree<Data>::splay_find_below_max(void * key) {
|
||||
|
||||
void * closest_key;
|
||||
|
||||
if (root == NULL)
|
||||
return NULL;
|
||||
if (key == NULL)
|
||||
return NULL;
|
||||
|
||||
closest_key = NULL;
|
||||
|
||||
splay_find_below_max_helper(key, &closest_key, root, compare);
|
||||
|
||||
if (closest_key == NULL) return NULL;
|
||||
return splay_find(closest_key);
|
||||
}
|
||||
|
||||
|
||||
/* Returns the 'minimum' key that is greater than the given key in the splaytree */
|
||||
template <class Data>
|
||||
void * SplayTree<Data>::splay_find_above_min(void * key) {
|
||||
|
||||
void * closest_key;
|
||||
|
||||
if (root == NULL)
|
||||
return NULL;
|
||||
if (key == NULL)
|
||||
return NULL;
|
||||
closest_key = NULL;
|
||||
|
||||
splay_find_above_min_helper(key, &closest_key, root, compare);
|
||||
|
||||
if (closest_key == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return splay_find(closest_key);
|
||||
}
|
||||
|
||||
/* Helper function */
|
||||
template <class Data>
|
||||
void SplayTree<Data>::splay_find_below_max_helper(void * min_key, void ** closest_key, SplayNode<Data> * root, int (*compare)(void*,void*)) {
|
||||
|
||||
/* Empty root, return*/
|
||||
if (root == NULL)
|
||||
return;
|
||||
|
||||
/* The root key is less than the previously found closest key.
|
||||
Also try to make the key non null if the value is less than the max key */
|
||||
|
||||
if ((*closest_key == NULL) || (compare(root->key, *closest_key) < 0)) {
|
||||
|
||||
/* The root key is less than the given max key, so this is the
|
||||
smallest change from the given max key */
|
||||
if (compare(root->key, min_key) > 0) {
|
||||
|
||||
*closest_key = root->key;
|
||||
|
||||
/* Look right again in case even a greater key exists that is
|
||||
still less than the given max key */
|
||||
splay_find_below_max_helper(min_key, closest_key, root->left, compare);
|
||||
}
|
||||
|
||||
/* The root key is greater than the given max key, and greater than
|
||||
the closest key, so search left */
|
||||
else {
|
||||
splay_find_below_max_helper(min_key, closest_key, root->right, compare);
|
||||
}
|
||||
}
|
||||
|
||||
/* The root key is less than the found closest key, search right */
|
||||
else {
|
||||
splay_find_below_max_helper(min_key, closest_key, root->left, compare);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* Helper function */
|
||||
template <class Data>
|
||||
void SplayTree<Data>::splay_find_above_min_helper(void * max_key, void ** closest_key, SplayNode<Data> * root, int (*compare)(void *,void*)) {
|
||||
|
||||
/* Empty root, stop */
|
||||
if (root == NULL)
|
||||
return;
|
||||
|
||||
/* The root key is greater than the previously found closest key.
|
||||
Also try to make the key non null if the value is less than the min key */
|
||||
|
||||
if ((*closest_key == NULL) || (compare(root->key, *closest_key) > 0)) {
|
||||
|
||||
/* The root key is greater than the given min key, so this is the
|
||||
smallest change from the given min key */
|
||||
if (compare(root->key, max_key) < 0) {
|
||||
|
||||
*closest_key = root->key;
|
||||
|
||||
/* Look left again in case even a smaller key exists that is
|
||||
still greater than the given min key */
|
||||
splay_find_above_min_helper(max_key, closest_key, root->right, compare);
|
||||
}
|
||||
|
||||
/* The root key is less than the given min key, and less than
|
||||
the closest key, so search right */
|
||||
else {
|
||||
splay_find_above_min_helper(max_key, closest_key, root->left, compare);
|
||||
}
|
||||
}
|
||||
|
||||
/* The root key is greater than the found closest key, search left */
|
||||
else {
|
||||
splay_find_above_min_helper(max_key, closest_key, root->right, compare);
|
||||
}
|
||||
}
|
||||
|
||||
/* Find the minimum entry of the splay tree */
|
||||
template <class Data>
|
||||
Data * SplayTree<Data>::splay_find_min() {
|
||||
|
||||
SplayNode<Data> * splaynode;
|
||||
|
||||
if (root == NULL)
|
||||
return NULL;
|
||||
|
||||
splaynode = root;
|
||||
|
||||
while (splaynode->left != NULL)
|
||||
splaynode= splaynode->left;
|
||||
|
||||
return splaynode->data;
|
||||
}
|
||||
|
||||
|
||||
/* Find the maximum entry of the splay tree */
|
||||
template <class Data>
|
||||
Data * SplayTree<Data>::splay_find_max() {
|
||||
|
||||
SplayNode<Data> * splaynode;
|
||||
|
||||
if (root == NULL)
|
||||
return NULL;
|
||||
|
||||
splaynode = root;
|
||||
|
||||
while (splaynode->right != NULL) {
|
||||
printf("data:%d\n", *(int*)splaynode->key);
|
||||
splaynode = splaynode->right;
|
||||
}
|
||||
return splaynode->data;
|
||||
}
|
||||
|
||||
template <class Data>
|
||||
int SplayTree<Data>::splay_size() {
|
||||
|
||||
if ( root == NULL ) {
|
||||
return SPLAYTREE_FAILURE;
|
||||
}
|
||||
return splay_rec_size(root);
|
||||
}
|
||||
|
||||
template <class Data>
|
||||
int SplayTree<Data>::splay_rec_size(SplayNode<Data> * splaynode) {
|
||||
|
||||
if (!splaynode)
|
||||
return 0;
|
||||
|
||||
return 1 + splay_rec_size(splaynode->left) + splay_rec_size(splaynode->right);
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endif /** !_SPLAYTREE_HPP */
|
||||
Reference in New Issue
Block a user