📄 ivp_sim_unit.cxx
字号:
// Copyright (C) Ipion Software GmbH 1999-2000. All rights reserved.
#include <ivp_physics.hxx>
#if !defined(WIN32) && !defined(PSXII) && !defined(GEKKO)
# include <alloca.h>
#endif
#ifndef WIN32
# pragma implementation "ivp_sim_unit.hxx"
#endif
#include <ivp_controller.hxx>
#include <ivp_mindist_intern.hxx>
#include <ivp_friction.hxx>
#include <ivp_core_macros.hxx>
#include <ivp_sim_unit.hxx>
#include <ivu_memory.hxx>
#include <ivp_calc_next_psi_solver.hxx>
#include <ivp_performancecounter.hxx>
#include <ivp_time.hxx>
IVP_U_Vector<IVP_Core> IVP_Controller_Independent::empty_list;
#ifdef WIN32
extern long p_get_time();
#endif
//the list of cores is valid, calculate the rest
void IVP_Simulation_Unit::sim_unit_calc_redundants() {
for (int i = sim_unit_cores.len()-1; i>=0; i--){
IVP_Core *my_core = sim_unit_cores.element_at(i);
for (int k = my_core->controllers_of_core.len()-1; k>=0;k--){
IVP_Controller *my_controller = my_core->controllers_of_core.element_at(k);
if( this->controller_is_known_to_sim_unit( my_controller ) == IVP_FALSE ) {
this->add_controller_unit_sim( my_controller );
}
this->add_controlled_core_for_controller( my_controller, my_core );
}
}
sim_unit_sort_controllers();
}
IVP_BOOL IVP_Simulation_Unit::controller_is_known_to_sim_unit( IVP_Controller *my_controller ) {
int i;
for( i=controller_cores.len()-1; i>=0 ; i-- ) {
if( controller_cores.element_at(i)->l_controller == my_controller ) {
return IVP_TRUE;
}
}
return IVP_FALSE;
}
// controller exists; add a core for this controller
void IVP_Simulation_Unit::add_controlled_core_for_controller( IVP_Controller *cntrl, IVP_Core *my_core ) {
int i;
for( i=controller_cores.len()-1; i>=0 ; i-- ) {
if( controller_cores.element_at(i)->l_controller == cntrl ) {
break;
}
}
IVP_ASSERT(i>=0);
//IVP_ASSERT( controller_cores.element_at(i)->l_controller == cntrl );
controller_cores.element_at(i)->cores_controlled_by.add( my_core );
}
void IVP_Simulation_Unit::add_controller_unit_sim( IVP_Controller *new_cntrl ) {
//sim_unit_controllers.add( new_cntrl );
IVP_Sim_Unit_Controller_Core_List *core_list=new IVP_Sim_Unit_Controller_Core_List();
core_list->l_controller=new_cntrl;
controller_cores.add(core_list);
}
void IVP_Simulation_Unit::split_sim_unit(IVP_Core *split_father) {
IVP_ASSERT(split_father);
IVP_Core *my_core;
IVP_Core *next_split_father=NULL;
IVP_BOOL next_split_necessary=IVP_FALSE;
IVP_Simulation_Unit *split_new_unit=new IVP_Simulation_Unit();
split_new_unit->sim_unit_movement_type=IVP_MT_MOVING;
IVP_Sim_Units_Manager *s_man;
s_man= split_father->environment->get_sim_units_manager();
s_man->add_sim_unit_to_manager( split_new_unit );
//faster: operate directly on list, build two new lists -> only linear not quadratic
int i;
for(i=0;i<sim_unit_cores.len();i++) {
my_core=sim_unit_cores.element_at(i);
IVP_Core *test_core=my_core->union_find_get_father();
if( test_core != split_father ) {
if( next_split_father != NULL ) {
if( test_core!=next_split_father ) {
next_split_necessary=IVP_TRUE;
}
} else {
next_split_father=test_core;
}
} else {
sim_unit_cores.remove_at(i);
i--; //size of list is reduced
split_new_unit->sim_unit_cores.add(my_core);
my_core->sim_unit_of_core=split_new_unit;
}
}
split_new_unit->sim_unit_calc_redundants();
#ifdef DEBUG
IVP_IF(1) {
split_new_unit->sim_unit_debug_consistency();
}
#endif
if(next_split_necessary==IVP_TRUE) {
this->split_sim_unit(next_split_father);
}
}
void IVP_Simulation_Unit::perform_test_and_split() {
IVP_Core *father=sim_unit_union_find_test();
if(father) {
this->clean_sim_unit();
split_sim_unit(father);
this->sim_unit_calc_redundants();
#ifdef DEBUG
this->sim_unit_debug_consistency();
#endif
}
}
IVP_Core *IVP_Simulation_Unit::sim_unit_union_find_test()
{
IVP_Core *my_core;
for (int i = sim_unit_cores.len()-1; i>=0;i--){
my_core = sim_unit_cores.element_at(i);
my_core->tmp.union_find_father=NULL;
}
for(int i2=controller_cores.len()-1; i2>=0; i2-- ) {
IVP_Controller *my_controller=controller_cores.element_at(i2)->l_controller;
IVP_U_Vector<IVP_Core> *list_of_cores;
list_of_cores=my_controller->get_associated_controlled_cores();
int j;
j=list_of_cores->len()-1;
if(j>=0) {
IVP_Core *father_core=list_of_cores->element_at(0)->union_find_get_father();
for(;j>=0;j--) {
IVP_Core *test_core=list_of_cores->element_at(j);
IVP_Core *test_father=test_core->union_find_get_father();
if(father_core!=test_father) {
test_father->tmp.union_find_father=father_core;
}
}
}
}
#if 0
for(my_core=this->get_first_sim_unit_core();my_core;my_core=this->get_next_sim_unit_core())
{
IVP_Core *father_core=my_core->union_find_get_father();
for(my_controller=my_core->get_first_core_controller();my_controller;my_controller=my_core->get_next_core_controller()) {
IVP_U_Vector<IVP_Core> *controlled_cores;
controlled_cores=my_controller->get_associated_controlled_cores(my_core);
for(i=controlled_cores->len()-1;i>=0;i--) {
IVP_Core *test_core=controlled_cores->element_at(i);
IVP_Core *test_father=test_core->union_find_get_father();
if(father_core!=test_father) {
test_core->tmp.union_find_father=father_core;
}
}
}
}
#endif
IVP_Core *first_father=this->sim_unit_cores.element_at(0)->union_find_get_father();
// find representative obj for second system (must not be a fixed obj)
{
int j;
for (j = 0; j < sim_unit_cores.len(); j++){
IVP_Core *obj = sim_unit_cores.element_at(j);
IVP_Core *test_father=obj->union_find_get_father();
if(test_father!=first_father) {
return test_father;
}
}
}
return NULL;
}
//clear redundant part
void IVP_Simulation_Unit::clean_sim_unit() {
int i;
for(i=controller_cores.len()-1;i>=0;i--) {
IVP_Sim_Unit_Controller_Core_List *c_info=controller_cores.element_at(i);
P_DELETE( c_info );
}
//sim_unit_controllers.clear();
controller_cores.clear();
}
void IVP_Simulation_Unit::throw_cores_into_my_sim_unit(IVP_Simulation_Unit *second_unit) {
IVP_Environment *env=NULL;
int i;
for ( i=0; i<second_unit->sim_unit_cores.len(); i++){
IVP_Core *my_core = second_unit->sim_unit_cores.element_at(i);
this->add_sim_unit_core( my_core );
env=my_core->environment;
my_core->sim_unit_of_core=this;
}
env->get_sim_units_manager()->rem_sim_unit_from_manager( second_unit );
}
// second_unit is destroyed
void IVP_Simulation_Unit::fusion_simulation_unities(IVP_Simulation_Unit *second_unit) {
this->clean_sim_unit();
throw_cores_into_my_sim_unit(second_unit);
this->sim_unit_calc_redundants();
}
int IVP_Simulation_Unit::get_pos_of_controller( IVP_Controller *contr ) {
int i;
for(i=controller_cores.len()-1;i>=0;i--) {
if(controller_cores.element_at(i)->l_controller == contr) {
break;
}
}
return i;
}
void IVP_Simulation_Unit::sim_unit_remove_core( IVP_Core *del_core ) {
rem_sim_unit_core( del_core );
int i;
for (i = del_core->controllers_of_core.len()-1; i>=0;i--){
IVP_Controller *my_controller= del_core->controllers_of_core.element_at(i);
int pos=get_pos_of_controller(my_controller);
IVP_ASSERT(pos>=0);
IVP_Sim_Unit_Controller_Core_List *c_info=controller_cores.element_at(pos);
c_info->cores_controlled_by.remove(del_core);
if( c_info->cores_controlled_by.len() == 0 ) {
rem_sim_unit_controller( my_controller );
}
}
if(sim_unit_cores.len()==0) {
del_core->environment->get_sim_units_manager()->rem_sim_unit_from_manager(this);
P_DELETE_THIS(this);
}
}
IVP_Simulation_Unit::~IVP_Simulation_Unit() {
this->clean_sim_unit();
;//printf("delete_simu %lx\n",(long)this&0x0000ffff);
}
IVP_Simulation_Unit::IVP_Simulation_Unit() {
//printf("create_simu %lx\n",(long)this&0x0000ffff);
union_find_needed_for_sim_unit = IVP_FALSE;
sim_unit_movement_type = IVP_MT_NOT_SIM;
sim_unit_just_slowed_down = IVP_FALSE;
sim_unit_has_fast_objects = IVP_FALSE;
}
void IVP_Simulation_Unit::rem_sim_unit_controller( IVP_Controller *rem_controller ) {
int pos=get_pos_of_controller( rem_controller );
IVP_ASSERT(pos>=0);
IVP_Sim_Unit_Controller_Core_List *c_info=controller_cores.element_at(pos);
P_DELETE(c_info);
controller_cores.remove_at(pos);
//sim_unit_controllers.delete_at(pos);
}
void IVP_Simulation_Unit::add_sim_unit_core( IVP_Core *add_core ) {
sim_unit_cores.add( add_core );
}
void IVP_Simulation_Unit::rem_sim_unit_core( IVP_Core *del_core ) {
sim_unit_cores.remove( del_core );
}
IVP_BOOL IVP_Simulation_Unit::sim_unit_core_exists(IVP_Core *core) {
int i;
for(i=sim_unit_cores.len()-1;i>=0;i--) {
if(sim_unit_cores.element_at(i) == core) {
return IVP_TRUE;
}
}
return IVP_FALSE;
}
#ifdef DEBUG
void IVP_Simulation_Unit::sim_unit_debug_out() {
printf("sim_unit_cores:\n");
int i;
for(i=sim_unit_cores.len()-1;i>=0;i--) {
IVP_Core *my_core=sim_unit_cores.element_at(i);
printf("%lx: ",(long)my_core);
IVP_Controller *my_cnt;
int j;
for(j=my_core->controllers_of_core.len()-1;j>=0;j--) {
my_cnt=my_core->controllers_of_core.element_at(j);
printf("%lx ",(long)my_cnt);
}
printf("\n");
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -