📄 ivu_active_value.cxx
字号:
// Copyright (C) Ipion Software GmbH 1999-2000. All rights reserved.
// IVP_U_Active_Float ist ein modular kombinierbarer Zahlengeber (Synthesizer)
// und Event-Ausloeser zur Implementierung der Spiel-Logik ausserhalb
// der eigentlichen Grundphysik.
// z.B. fuer IVP_Actuator_Forces (oder Klaenge :-)
// IVP_Active_Float is a modular combinable number generator to implement
// some logics stuff. It is no internal part of the physics but some
// add on for convenience. It is based on event-callbacks to update the
// values when it is necessary. It is used e.g. for IVP_Actuator_Forces.
#include <ivp_physics.hxx>
#include <string.h>
#ifndef WIN32
# pragma implementation "ivu_active_value.hxx"
# pragma implementation "ivu_active_value_hash.hxx"
#endif
#include <ivu_active_value.hxx>
#include <ivu_active_value_hash.hxx>
IVP_Active_Value_Hash::~IVP_Active_Value_Hash()
{
for (int i=this->len()-1; i>=0; i--) {
IVP_U_Active_Value *av;
av = (IVP_U_Active_Value *)this->element_at(i);
if (av){
av->remove_reference();
}
}
}
int IVP_Active_Value_Hash::object_to_index(IVP_U_Active_Value *av)
{
const char *name = av->get_name();
return hash_index( name, strlen( name) );
}
IVP_BOOL IVP_Active_Value_Hash::compare(void *elem0, void *elem1) const
{
IVP_U_Active_Value *av0 = (IVP_U_Active_Value *)elem0;
IVP_U_Active_Value *av1 = (IVP_U_Active_Value *)elem1;
const char *name0 = av0->get_name();
const char *name1 = av1->get_name();
if (p_strcmp(name0, name1) == 0) return IVP_TRUE;
return IVP_FALSE;
}
int IVP_U_Active_Float::change_meter = -1;
IVP_U_Active_Value_Manager::IVP_U_Active_Value_Manager(IVP_BOOL delete_on_env_delete_in)
{
delete_on_env_delete = delete_on_env_delete_in;
// init name hash
this->floats_name_hash = new IVP_Active_Value_Hash(IVP_U_MOD_NAME_HASH_SIZE);
this->ints_name_hash = new IVP_Active_Value_Hash(IVP_U_MOD_NAME_HASH_SIZE);
this->search_active_value = new IVP_U_Active_Value(NULL);
this->mod_current_time = NULL;
this->init_active_values_generic();
}
IVP_U_Active_Value_Manager::~IVP_U_Active_Value_Manager()
{
P_DELETE(this->floats_name_hash); // removes references two
P_DELETE(this->ints_name_hash);
P_DELETE(this->search_active_value);
}
void IVP_U_Active_Value_Manager::init_active_values_generic()
{
IVP_U_Active_Terminal_Double *mod_double_null = new IVP_U_Active_Terminal_Double("double_null", 0.0f);
this->mod_current_time = new IVP_U_Active_Terminal_Double(IVP_ACTIVE_FLOAT_CURRENT_TIME_NAME, 0.0f);
this->insert_active_float(mod_double_null);
this->insert_active_float(mod_current_time);
}
void IVP_U_Active_Value_Manager::insert_active_float(IVP_U_Active_Float *mod)
{
const char *name = mod->get_name();
if(p_strlen(name)==0){
printf("insert_active_float: tried to insert active_IVP_FLOAT without name!\n");
return;
}
IVP_U_Active_Float *found = (IVP_U_Active_Float *)floats_name_hash->find_active_value(mod);
if(found){
printf("insert_active_float: name '%s' already exists in name_hash!\n", name);
return;
}
floats_name_hash->add_active_value(mod);
mod->l_mod_manager = this; // provide backlink
}
void IVP_U_Active_Value_Manager::insert_active_int(IVP_U_Active_Int *mod)
{
const char *name = mod->get_name();
if(p_strlen(name)==0){
printf("insert_active_int: tried to insert active_int without name!\n");
return;
}
IVP_U_Active_Int *found = (IVP_U_Active_Int *)ints_name_hash->find_active_value(mod);
if(found){
printf("insert_active_int: name '%s' already exists in name_hash!\n", name);
return;
}
ints_name_hash->add_active_value(mod);
mod->add_reference();
mod->l_mod_manager = this; // provide backlink
}
void IVP_U_Active_Value_Manager::remove_active_float(IVP_U_Active_Float *mod)
{
floats_name_hash->remove_active_value(mod);
}
void IVP_U_Active_Value_Manager::remove_active_int(IVP_U_Active_Int *mod)
{
ints_name_hash->remove_active_value(mod);
}
void IVP_U_Active_Value_Manager::delay_active_float(IVP_U_Active_Float_Delayed *mod)
{
if (delayed_active_floats.index_of(mod) == -1){
delayed_active_floats.add(mod);
}
}
void IVP_U_Active_Value_Manager::delay_active_int(IVP_U_Active_Int_Delayed *mod)
{
if (delayed_active_ints.index_of(mod) == -1){
delayed_active_ints.add(mod);
}
}
void IVP_U_Active_Value_Manager::update_delayed_active_values()
{
// update all active_floats contained in vector delayed_active_floats
{
IVP_U_Active_Float_Delayed *mod;
int i;
for (i = 0; i< delayed_active_floats.len();i++){
mod = delayed_active_floats.element_at(i);
mod->update_float();
}
delayed_active_floats.clear();
}
{
IVP_U_Active_Int_Delayed *mod;
int i;
for (i = 0; i< delayed_active_ints.len();i++){
mod = delayed_active_ints.element_at(i);
mod->update_int();
}
delayed_active_ints.clear();
}
}
void IVP_U_Active_Value_Manager::refresh_psi_active_values(IVP_Environment *env)
{
if (mod_current_time){
mod_current_time->set_double(env->get_current_time().get_time());
}
update_delayed_active_values();
}
IVP_U_Active_Float *IVP_U_Active_Value_Manager::get_active_float_by_name(const char *i_name)
{
if(!i_name) return 0;
// check module hash first
search_active_value->name = (char *)i_name;// bad hack, thats ok
IVP_U_Active_Float *mod = (IVP_U_Active_Float *)floats_name_hash->find_active_value(search_active_value);
search_active_value->name = NULL;
if (mod) return mod;
// if module name is a number, generate terminal active_floats with
// that (IVP_DOUBLE) value on the fly.
int pos = 0;
if(i_name[pos] == '-') pos++; // for negative sign
if(i_name[pos] == '.') pos++; // for omitted leading zero
if(i_name[pos] >= '0' && i_name[pos] <= '9'){
mod = new IVP_U_Active_Terminal_Double(i_name, p_atof(i_name));
this->insert_active_float(mod);
return mod;
}
return NULL;
}
IVP_U_Active_Int *IVP_U_Active_Value_Manager::get_active_int_by_name(const char *i_name)
{
if(!i_name) return 0;
// check module hash first
search_active_value->name = (char *)i_name;// bad hack, thats ok
IVP_U_Active_Int *mod = (IVP_U_Active_Int *)ints_name_hash->find_active_value(search_active_value);
search_active_value->name = NULL;
if (mod) return mod;
// if module name is a number, generate terminal active_floats with
// that (IVP_DOUBLE) value on the fly.
int pos = 0;
if(i_name[pos] == '-') pos++; // for negative sign
if(i_name[pos] == '.') pos++; // for omitted leading zero
if(i_name[pos] >= '0' && i_name[pos] <= '9'){
mod = new IVP_U_Active_Terminal_Int(i_name, p_atoi(i_name));
this->insert_active_int(mod);
return mod;
}
return NULL;
}
IVP_U_Active_Float *IVP_U_Active_Value_Manager::install_active_float(const char *i_name, IVP_DOUBLE value)
{
// check module hash first
search_active_value->name = (char *)i_name;// bad hack, thats ok
IVP_U_Active_Float *mod = (IVP_U_Active_Float *)floats_name_hash->find_active_value(search_active_value);
search_active_value->name = NULL;
if (mod) return mod;
IVP_U_Active_Terminal_Double *atd = new IVP_U_Active_Terminal_Double(i_name, value);
this->insert_active_float(atd);
return atd;
}
IVP_U_Active_Terminal_Double *IVP_U_Active_Value_Manager::create_active_float(const char *i_name, IVP_DOUBLE value)
{
// check module hash first
search_active_value->name = (char *)i_name;// bad hack, thats ok
IVP_U_Active_Float *mod = (IVP_U_Active_Float *)floats_name_hash->find_active_value(search_active_value);
search_active_value->name = NULL;
if (mod) return NULL;
IVP_U_Active_Terminal_Double *atd = new IVP_U_Active_Terminal_Double(i_name, value);
this->insert_active_float(atd);
return atd;
}
IVP_U_Active_Terminal_Int *IVP_U_Active_Value_Manager::create_active_int(const char *i_name, int value)
{
// check module hash first
search_active_value->name = (char *)i_name;// bad hack, thats ok
IVP_U_Active_Int *mod = (IVP_U_Active_Int *)ints_name_hash->find_active_value(search_active_value);
search_active_value->name = NULL;
if (mod) return NULL;
IVP_U_Active_Terminal_Int *atd = new IVP_U_Active_Terminal_Int(i_name, value);
this->insert_active_int(atd);
return atd;
}
IVP_U_Active_Int *IVP_U_Active_Value_Manager::install_active_int(const char *i_name, int value)
{
// check module hash first
search_active_value->name = (char *)i_name;// bad hack, thats ok
IVP_U_Active_Int *mod = (IVP_U_Active_Int *)ints_name_hash->find_active_value(search_active_value);
search_active_value->name = NULL;
if (mod) return mod;
IVP_U_Active_Terminal_Int *atd = new IVP_U_Active_Terminal_Int(i_name, value);
this->insert_active_int(atd);
return atd;
}
//////////////
IVP_U_Active_Value::IVP_U_Active_Value(const char *name_){
name = p_strdup(name_);
reference_count = 0;
}
IVP_U_Active_Value::~IVP_U_Active_Value(){
P_FREE(name);
IVP_ASSERT(reference_count == 0);
}
IVP_U_Active_Float::IVP_U_Active_Float(const char *i_name) : IVP_U_Active_Value(i_name)
{
// memclear not allowed because of virt. functions
this->last_update = 0; // should be updated
this->l_mod_manager = NULL; // link is done by manager
this->double_value = 0.0f;
}
IVP_U_Active_Int::IVP_U_Active_Int(const char *i_name): IVP_U_Active_Value(i_name)
{
// memclear not allowed because of virt. functions
this->last_update = 0; // should be updated
this->l_mod_manager = NULL; // link is done by manager
this->int_value = 0;
}
IVP_U_Active_Float::~IVP_U_Active_Float()
{
// if(name_hash){
// name_hash->remove(this->name);
// }
// must be done by hand (or by manager), no arg supported by destructor !
return;
}
IVP_U_Active_Int::~IVP_U_Active_Int()
{
// if(name_hash){
// name_hash->remove(this->name);
// }
// must be done by hand (or by manager), no arg supported by destructor !
}
void IVP_U_Active_Float::update_derived()
{
// update all active_float_listener which depend on my value
for (int i = derived_mods.len()-1; i>=0;i--){
IVP_U_Active_Float_Listener *mod = derived_mods.element_at(i);
mod->active_float_changed(this);
}
}
void IVP_U_Active_Int::update_derived()
{
// update all active_float_listener which depend on my value
for( int i = derived_mods.len()-1; i>=0; i--){
IVP_U_Active_Int_Listener *mod= derived_mods.element_at(i);
mod->active_int_changed(this);
}
}
void IVP_U_Active_Float::add_dependency(IVP_U_Active_Float_Listener *derived_active_IVP_FLOAT)
{
// add update callback
this->derived_mods.add(derived_active_IVP_FLOAT);
this->add_reference();
}
void IVP_U_Active_Float::remove_dependency(IVP_U_Active_Float_Listener *derived_active_IVP_FLOAT)
{
// add update callback
this->derived_mods.remove(derived_active_IVP_FLOAT);
this->remove_reference();
}
void IVP_U_Active_Int::add_dependency(IVP_U_Active_Int_Listener *derived_active_int)
{
// add update callback
this->derived_mods.add(derived_active_int);
this->add_reference();
}
void IVP_U_Active_Int::remove_dependency(IVP_U_Active_Int_Listener *derived_active_int)
{
// add update callback
this->derived_mods.remove(derived_active_int);
this->remove_reference();
}
/**** BASIC VALUES ********************/
/**** BASIC VALUES ********************/
/**** BASIC VALUES ********************/
/****** 'terminal' IVP_DOUBLE value ******/
IVP_U_Active_Terminal_Double::IVP_U_Active_Terminal_Double(const char *i_name,
IVP_DOUBLE new_value) : IVP_U_Active_Float(i_name)
{
this->double_value = new_value;
this->old_value = new_value;
}
IVP_U_Active_Terminal_Int::IVP_U_Active_Terminal_Int(const char *i_name,int new_value) : IVP_U_Active_Int(i_name)
{
this->int_value = new_value;
this->old_value = new_value;
}
void IVP_U_Active_Terminal_Double::update_float()
{
if(this->double_value != old_value){
this->old_value = double_value;
this->update_derived();
}
}
void IVP_U_Active_Terminal_Int::update_int()
{
if(this->int_value != old_value){
this->old_value = int_value;
this->update_derived();
}
}
void IVP_U_Active_Terminal_Double::set_double(IVP_DOUBLE new_value, IVP_BOOL delayed_update)
{
this->double_value = new_value;
this->change_meter++;
if(delayed_update && l_mod_manager){
l_mod_manager->delay_active_float(this);
}else{
this->update_float();
}
}
int IVP_U_Active_Terminal_Double::print()
{
printf("DoubleVal");
return 0; // for debugger
}
////////////////////
void IVP_U_Active_Terminal_Int::set_int(int new_value, IVP_BOOL delayed_update)
{
this->int_value = new_value;
IVP_U_Active_Float::change_meter++;
if(delayed_update && l_mod_manager){
l_mod_manager->delay_active_int(this);
}else{
this->update_int();
}
}
int IVP_U_Active_Terminal_Int::print()
{
printf("IntVal");
return 0; // for debugger
}
/*** OSCILLATORS (time dependant) **************/
/*** OSCILLATORS (time dependant) **************/
/*** OSCILLATORS (time dependant) **************/
IVP_U_Active_Sine::IVP_U_Active_Sine(const char *i_name,
IVP_U_Active_Float *time_mod_,
IVP_DOUBLE freq, IVP_DOUBLE amp,
IVP_DOUBLE i_null_level,
IVP_DOUBLE i_time_shift
) : IVP_U_Active_Float(i_name)
{
this->time_mod = time_mod_;
this->time_mod->add_dependency(this);
this->frequence = freq;
this->amplitude = amp;
this->null_level = i_null_level;
this->time_shift = i_time_shift;
this->active_float_changed(this); // no derived existing yet!
}
IVP_U_Active_Sine::~IVP_U_Active_Sine()
{
this->time_mod->remove_dependency(this);
return;
}
void IVP_U_Active_Sine::active_float_changed(IVP_U_Active_Float *)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -