⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ivu_active_value.cxx

📁 hl2 source code. Do not use it illegal.
💻 CXX
📖 第 1 页 / 共 2 页
字号:
// 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 + -