📄 ivp_sim_unit.cxx
字号:
for(i=controller_cores.len()-1;i>=0;i--) {
printf(" controlr %lx: ",(long)controller_cores.element_at(i)->l_controller);
int j;
IVP_Sim_Unit_Controller_Core_List *c_info=controller_cores.element_at(i);
for(j=c_info->cores_controlled_by.len()-1;j>=0;j--) {
printf("%lx ",(long)c_info->cores_controlled_by.element_at(j));
}
printf("\n");
}
}
#endif
#ifdef DEBUG
void IVP_Simulation_Unit::sim_unit_debug_consistency() {
//every core has to occur only once
int i,j;
for(i=sim_unit_cores.len()-1;i>=0;i--) {
IVP_Core *search_core=sim_unit_cores.element_at(i);
for(j=i-1;j>=0;j--) {
IVP_ASSERT( sim_unit_cores.element_at(j) != search_core );
}
IVP_ASSERT( !search_core->physical_unmoveable );
IVP_ASSERT( search_core->sim_unit_of_core==this );
}
//every controller has to occur only once
for(i=controller_cores.len()-1;i>=0;i--) {
IVP_Controller *search_controller=controller_cores.element_at(i)->l_controller;
for(j=i-1;j>=0;j--) {
IVP_ASSERT( controller_cores.element_at(j)->l_controller != search_controller );
}
}
//sim_unit_controllers and controller_cores are associated
//IVP_ASSERT( sim_unit_controllers.len() == controller_cores.len() );
for(i=controller_cores.len()-1;i>=0;i--) {
IVP_Sim_Unit_Controller_Core_List *c_info=controller_cores.element_at(i);
//IVP_ASSERT( c_info->l_controller == sim_unit_controllers.element_at(i) );
//every core in controller list must exist
for(j=c_info->cores_controlled_by.len()-1;j>=0;j--) {
IVP_Core *test_core=c_info->cores_controlled_by.element_at(j);
IVP_ASSERT( sim_unit_core_exists(test_core)==IVP_TRUE );
}
}
//all cores must have all their controllers in controller list
for (int i1 = sim_unit_cores.len()-1; i1>=0; i1--){
IVP_Core *my_core = sim_unit_cores.element_at(i1);
for (int i2 = my_core->controllers_of_core.len()-1;i2>=0; i2--){
IVP_Controller *my_controller = my_core->controllers_of_core.element_at(i2);
IVP_ASSERT( controller_is_known_to_sim_unit( my_controller )==IVP_TRUE );
//for every core its via controllers associated cores must exist
IVP_U_Vector<IVP_Core> *core_list = my_controller->get_associated_controlled_cores();
for(int i4=core_list->len()-1;i4>=0;i4--) {
IVP_Core *test_core=core_list->element_at(i4);
IVP_ASSERT( !test_core->physical_unmoveable );
IVP_ASSERT( sim_unit_core_exists( test_core ) == IVP_TRUE );
}
//every core/controller pair must be represented in c_info
int pos=get_pos_of_controller(my_controller);
IVP_Sim_Unit_Controller_Core_List *c_info=controller_cores.element_at(pos);
int found=0;
for(int i5=c_info->cores_controlled_by.len()-1;i5>=0;i5--) {
IVP_Core *tt_core=c_info->cores_controlled_by.element_at(i5);
if(tt_core == my_core) {
found=1;
}
//this controller must be found in my cores controller list
int find_contr=0;
for(int k=0;k<tt_core->controllers_of_core.len();k++) {
if( tt_core->controllers_of_core.element_at(k) == my_controller ) {
find_contr=1;
}
}
IVP_ASSERT(find_contr==1);
}
IVP_ASSERT(found==1);
}
}
}
#endif
void IVP_Controller_Manager::ensure_core_in_simulation(IVP_Core *core) {
core->ensure_core_in_simulation_delayed();
}
//only for Controllers that have all cores computed at the same time
void IVP_Controller_Manager::remove_controller_from_environment( IVP_Controller_Dependent *cntrl, IVP_BOOL silently ) {
IVP_U_Vector<IVP_Core> *controlled_cores=cntrl->get_associated_controlled_cores();
IVP_Simulation_Unit *reference_unit=NULL;
int i;
for(i=controlled_cores->len()-1;i>=0;i--) {
IVP_Core *my_core=controlled_cores->element_at(i);
my_core->rem_core_controller(cntrl);
reference_unit=my_core->sim_unit_of_core;
}
if(reference_unit) {
reference_unit->union_find_needed_for_sim_unit=IVP_TRUE;
if(silently==IVP_FALSE) {
reference_unit->sim_unit_ensure_in_simulation();
}
}
}
void IVP_Controller_Manager::ensure_controller_in_simulation(IVP_Controller_Dependent *cntrl) {
IVP_U_Vector<IVP_Core> *controlled_cores=cntrl->get_associated_controlled_cores();
IVP_ASSERT( controlled_cores->len() > 0);
if(controlled_cores->len() > 0) { // #+# is this to avoid an assert ???
controlled_cores->element_at(0)->sim_unit_of_core->sim_unit_ensure_in_simulation();
}
}
void IVP_Controller_Manager::add_controller_to_core(IVP_Controller_Independent *cntrl, IVP_Core *core){
core->add_core_controller(cntrl);
}
void IVP_Controller_Manager::remove_controller_from_core(IVP_Controller_Independent *cntrl, IVP_Core *core){
core->rem_core_controller(cntrl);
}
//only for Controllers that have all cores computed at the same time
void IVP_Controller_Manager::announce_controller_to_environment( IVP_Controller_Dependent *cntrl ) {
IVP_U_Vector<IVP_Core> *controlled_cores=cntrl->get_associated_controlled_cores();
IVP_Simulation_Unit *reference_unit=NULL;
IVP_BOOL did_fusion=IVP_FALSE;
IVP_Movement_Type mtype=IVP_MT_NOT_SIM;
int i;
for(i=controlled_cores->len()-1;i>=0;i--) {
IVP_Core *test_core=controlled_cores->element_at(i);
if(!test_core->physical_unmoveable) {
mtype=(IVP_Movement_Type)((int)mtype & (int)test_core->movement_state);
IVP_Simulation_Unit *test_sim_unit=test_core->sim_unit_of_core;
if(reference_unit!=NULL) {
if(test_sim_unit!=reference_unit) {
reference_unit->throw_cores_into_my_sim_unit(test_sim_unit); //
P_DELETE(test_sim_unit);
did_fusion=IVP_TRUE;
}
} else {
reference_unit=test_sim_unit;
}
test_core->add_core_controller(cntrl);
}
}
if(did_fusion==IVP_TRUE) {
reference_unit->clean_sim_unit();
reference_unit->sim_unit_calc_redundants();
}
if(mtype<IVP_MT_NOT_SIM) {
reference_unit->sim_unit_revive_for_simulation(l_environment); //ensure in simulation is not enough (cannot handle mixture of simulated and not simulated objects)
}
}
void IVP_Core::rem_core_controller( IVP_Controller *rem_cntrl ) {
controllers_of_core.remove(rem_cntrl);
this->sim_unit_of_core->remove_controller_of_core(this,rem_cntrl);
}
void IVP_Core::add_core_controller( IVP_Controller *add_cntrl ) {
controllers_of_core.add(add_cntrl);
sim_unit_of_core->add_controller_of_core(this,add_cntrl);
}
// e.g. a core enters a water pool
void IVP_Simulation_Unit::add_controller_of_core( IVP_Core *my_core, IVP_Controller *cntrl ) {
if( controller_is_known_to_sim_unit( cntrl ) ) {
;
} else {
add_controller_unit_sim( cntrl );
}
add_controlled_core_for_controller( cntrl, my_core );
this->sim_unit_sort_controllers();
}
// e.g. a core leaves a water pool
void IVP_Simulation_Unit::remove_controller_of_core( IVP_Core *my_core, IVP_Controller *cntrl ) {
int pos=get_pos_of_controller(cntrl);
IVP_ASSERT(pos>=0);
IVP_Sim_Unit_Controller_Core_List *c_info=controller_cores.element_at(pos);
c_info->cores_controlled_by.remove(my_core);
if( c_info->cores_controlled_by.len() <= 0 ) {
P_DELETE(c_info);
controller_cores.remove_at( pos ); //this controller no longer controlls any cores
}
//sim_unit_controllers.delete_at( pos );
}
void IVP_Simulation_Unit::sim_unit_sort_controllers() {
int contr_num=controller_cores.len();
int first=0;
while(1) {
int second=first+1;
if( second >= contr_num ) {
break;
}
IVP_CONTROLLER_PRIORITY second_prio = controller_cores.element_at(second)->l_controller->get_controller_priority();
if( controller_cores.element_at(first)->l_controller->get_controller_priority() > second_prio ) {
sim_unit_exchange_controllers(first,second);
int test_pos=first;
while( (test_pos>0) && ( controller_cores.element_at(test_pos-1)->l_controller->get_controller_priority() > second_prio ) ) {//controller_cores.element_at(test_pos)->l_controller->get_controller_priority() ) ) {
sim_unit_exchange_controllers(test_pos-1,test_pos);
test_pos--;
}
}
first=second;
}
IVP_IF(1) {
for( int i=0; i<contr_num-1; i++ ) {
IVP_ASSERT( !( controller_cores.element_at(i)->l_controller->get_controller_priority() > controller_cores.element_at(i+1)->l_controller->get_controller_priority() ) );
}
}
}
void IVP_Simulation_Unit::sim_unit_exchange_controllers(int first,int second) {
IVP_ASSERT(first>=0);
IVP_ASSERT(second>=0);
IVP_ASSERT(first<controller_cores.len());
IVP_ASSERT(second<controller_cores.len());
//sim_unit_controllers.exchange_vector_elems(first,second);
controller_cores.swap_elems(first,second);
}
IVP_Sim_Units_Manager::IVP_Sim_Units_Manager(IVP_Environment *env) {
l_environment=env;
sim_units_slots[0]=NULL;
still_slot=NULL;
nb = IVP_Time(9.73f);
bt = IVP_Time(0.3f);
}
void IVP_Sim_Units_Manager::add_unit_to_slot(IVP_Simulation_Unit *sim_u,IVP_Simulation_Unit **slot) {
IVP_Simulation_Unit *s_u=*slot;
sim_u->next_sim_unit=s_u;
if(s_u) {
s_u->prev_sim_unit=sim_u;
}
sim_u->prev_sim_unit=NULL;
*slot=sim_u;
}
void IVP_Sim_Units_Manager::add_sim_unit_to_manager(IVP_Simulation_Unit *sim_u) {
IVP_Simulation_Unit **slot;
if( sim_u->get_unit_movement_type() < IVP_MT_NOT_SIM ) {
slot=&sim_units_slots[0];
} else {
slot=&still_slot;
}
add_unit_to_slot(sim_u,slot);
}
void IVP_Sim_Units_Manager::rem_unit_from_slot(IVP_Simulation_Unit *sim_u,IVP_Simulation_Unit **slot)
{
IVP_Simulation_Unit *prev_u,*next_u;
prev_u=sim_u->prev_sim_unit;
next_u=sim_u->next_sim_unit;
if(prev_u) {
prev_u->next_sim_unit=next_u;
} else {
*slot=next_u;
}
if(next_u) {
next_u->prev_sim_unit=prev_u;
}
}
void IVP_Sim_Units_Manager::rem_sim_unit_from_manager(IVP_Simulation_Unit *sim_u) {
IVP_Simulation_Unit **slot;
if( sim_u->get_unit_movement_type() < IVP_MT_NOT_SIM ) {
slot=&sim_units_slots[0];
} else {
slot=&still_slot;
}
rem_unit_from_slot(sim_u,slot);
}
//during reviving of unit all cores are processed
//each core is revived and friction systems for that core are grown
//that may lead to more Simulation_units are fusioned with mine
//after a fusion is done, I have to restart the reviving of cores (Datastructure reassembly)
void IVP_Simulation_Unit::sim_unit_revive_for_simulation(IVP_Environment *env) {
revive_all_cores:
{
for (int i = sim_unit_cores.len()-1; i>=0;i--){
IVP_Core *my_core = sim_unit_cores.element_at(i);
IVP_ASSERT( !my_core->physical_unmoveable );
if(my_core->movement_state>=IVP_MT_NOT_SIM) {
IVP_BOOL fusion_was_done;
fusion_was_done=my_core->revive_simulation_core();
if(fusion_was_done==IVP_TRUE) {
goto revive_all_cores;
}
}
}
}
if(sim_unit_movement_type==IVP_MT_NOT_SIM) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -