mirror of
https://github.com/nasa/trick.git
synced 2024-12-30 09:58:53 +00:00
289 lines
9.8 KiB
C++
289 lines
9.8 KiB
C++
/*
|
|
PURPOSE: ( Python input processor )
|
|
REFERENCE: ( Trick Simulation Environment )
|
|
ASSUMPTIONS AND LIMITATIONS: ( None )
|
|
CLASS: ( N/A )
|
|
LIBRARY DEPENDENCY: ( None )
|
|
PROGRAMMERS: ( Alex Lin NASA 2009 )
|
|
*/
|
|
|
|
#include <iostream>
|
|
#include <sstream>
|
|
#include <vector>
|
|
#include <string>
|
|
#include <cmath>
|
|
|
|
#include "trick/EventManager.hh"
|
|
#include "trick/EventInstrument.hh"
|
|
#include "trick/memorymanager_c_intf.h"
|
|
#include "trick/exec_proto.h"
|
|
#include "trick/exec_proto.hh"
|
|
#include "trick/message_proto.h"
|
|
#include "trick/message_type.h"
|
|
|
|
Trick::EventManager * the_em ;
|
|
|
|
Trick::EventManager::EventManager() { the_em = this ; }
|
|
|
|
//Command to get the event object given the event's name
|
|
Trick::Event * Trick::EventManager::get_event(std::string event_name) {
|
|
unsigned int ii ;
|
|
Trick::Event* ret = NULL;
|
|
|
|
/* Find the event name in the active event list and return the pointer to that event */
|
|
for ( ii = 0 ; ii < num_active_events ; ii++ ) {
|
|
if ( ! active_events[ii]->get_name().compare(event_name) ) {
|
|
ret = active_events[ii];
|
|
break ;
|
|
}
|
|
}
|
|
|
|
return(ret) ;
|
|
|
|
}
|
|
|
|
//Add user's event to the active event list.
|
|
int Trick::EventManager::add_to_active_events(Trick::Event * in_event) {
|
|
|
|
for ( unsigned int ii = 0 ; ii < num_active_events ; ii++ ) {
|
|
if (in_event == active_events[ii]) {
|
|
return (0) ;
|
|
}
|
|
}
|
|
num_active_events++;
|
|
if (num_active_events == 1) {
|
|
active_events = (Trick::Event **)TMM_declare_var_s("Trick::Event* [1]");
|
|
} else {
|
|
active_events = (Trick::Event **)TMM_resize_array_1d_a(active_events, num_active_events);
|
|
}
|
|
active_events[num_active_events-1] = in_event ;
|
|
return (0) ;
|
|
}
|
|
|
|
//Command to insert a user's input file event into the input processor's list of events to process.
|
|
int Trick::EventManager::add_event(Trick::Event * in_event) {
|
|
|
|
int ret = 0 ;
|
|
|
|
add_to_active_events(in_event) ;
|
|
|
|
if (in_event->get_thread() < event_processors.size() ) {
|
|
event_processors[in_event->get_thread()]->add_event(in_event) ;
|
|
in_event->add() ;
|
|
} else {
|
|
message_publish(MSG_WARNING, "Event thread number is not in range: thread %d requested, only %d child threads in simulation.\n", in_event->get_thread() , event_processors.size() - 1) ;
|
|
ret = -1 ;
|
|
}
|
|
|
|
return ret ;
|
|
|
|
}
|
|
|
|
/**
|
|
@details
|
|
Command to insert an instrument job (containing in_event) into job queue before target job.
|
|
|
|
-# Find the target job.
|
|
-# If the target job exists
|
|
-# Save the target job information to the event.
|
|
-# Create an EventInstrument with the event and target job information
|
|
-# Add the event instrument to the target job
|
|
-# call the event's add routine if it needs to do anything once it is activated.
|
|
-# else print a warning that the target job does not exist.
|
|
-# Add the event to the list of active events.
|
|
*/
|
|
int Trick::EventManager::add_event_before(Trick::Event * in_event, std::string target_name, unsigned int target_inst) {
|
|
|
|
Trick::JobData * target_job ;
|
|
|
|
target_job = exec_get_job( target_name.c_str() , target_inst ) ;
|
|
if (target_job != NULL ) {
|
|
in_event->set_before_after(Trick::EVENT_BEFORETARGET) ;
|
|
in_event->set_target_name(target_name) ;
|
|
in_event->set_target_inst(target_inst) ;
|
|
Trick::EventInstrument * instru_job = new Trick::EventInstrument(in_event , target_job) ;
|
|
target_job->add_inst_before(instru_job) ;
|
|
events_instrumented.push_back(instru_job) ;
|
|
in_event->add() ;
|
|
} else {
|
|
message_publish(MSG_WARNING, "Event not added before job: %s does not exist.\n", target_name.c_str()) ;
|
|
return (0);
|
|
}
|
|
/* Add in_event to list of active events. */
|
|
add_to_active_events(in_event) ;
|
|
return(0);
|
|
|
|
}
|
|
|
|
/**
|
|
@details
|
|
Command to insert an instrument job (containing in_event) into job queue after target job.
|
|
|
|
-# Find the target job.
|
|
-# If the target job exists
|
|
-# Save the target job information to the event.
|
|
-# Create an EventInstrument with the event and target job information
|
|
-# Add the event instrument to the target job
|
|
-# call the event's add routine if it needs to do anything once it is activated.
|
|
-# else print a warning that the target job does not exist.
|
|
-# Add the event to the list of active events.
|
|
*/
|
|
int Trick::EventManager::add_event_after(Trick::Event * in_event, std::string target_name, unsigned int target_inst) {
|
|
|
|
Trick::JobData * target_job ;
|
|
|
|
target_job = exec_get_job( target_name.c_str() , target_inst ) ;
|
|
if (target_job != NULL ) {
|
|
in_event->set_before_after(Trick::EVENT_AFTERTARGET) ;
|
|
in_event->set_target_name(target_name) ;
|
|
in_event->set_target_inst(target_inst) ;
|
|
Trick::EventInstrument * instru_job = new Trick::EventInstrument(in_event , target_job) ;
|
|
target_job->add_inst_after(instru_job) ;
|
|
events_instrumented.push_back(instru_job) ;
|
|
in_event->add() ;
|
|
} else {
|
|
message_publish(MSG_WARNING, "Event not added before job: %s does not exist.\n", target_name.c_str()) ;
|
|
return (0);
|
|
}
|
|
/* Add in_event to list of active events. */
|
|
add_to_active_events(in_event) ;
|
|
return(0);
|
|
|
|
}
|
|
|
|
// Find the event by name and activate it.
|
|
int Trick::EventManager::activate_event(const char * event_name) {
|
|
Trick::Event* ret = NULL;
|
|
|
|
ret = get_event(event_name) ;
|
|
if (ret != NULL) {
|
|
ret->activate() ;
|
|
}
|
|
return 0 ;
|
|
}
|
|
|
|
// Find the event by name and deactivate it.
|
|
int Trick::EventManager::deactivate_event(const char * event_name) {
|
|
Trick::Event* ret = NULL;
|
|
|
|
ret = get_event(event_name) ;
|
|
if (ret != NULL) {
|
|
ret->deactivate() ;
|
|
}
|
|
return 0 ;
|
|
}
|
|
|
|
//Command to remove an event from everywhere it was added (it can still be added back again).
|
|
int Trick::EventManager::remove_event(Trick::Event * in_event) {
|
|
|
|
unsigned int ii , jj ;
|
|
|
|
if ( in_event->get_before_after() == Trick::EVENT_NOTARGET ) {
|
|
/* If the event is cyclic, remove the event from the event processor on the event's thread */
|
|
event_processors[in_event->get_thread()]->remove_event(in_event) ;
|
|
} else {
|
|
std::vector< Trick::EventInstrument * >::iterator ei_it ;
|
|
for ( ei_it = events_instrumented.begin() ; ei_it != events_instrumented.end() ; ) {
|
|
if ( (*ei_it)->get_event() == in_event ) {
|
|
/* If the event is tied to a job, call the target jobs remove instrument routine */
|
|
Trick::EventInstrument * found_event_instru = *ei_it ;
|
|
ei_it = events_instrumented.erase(ei_it) ;
|
|
found_event_instru->get_target_job()->remove_inst(found_event_instru->name) ;
|
|
delete found_event_instru ;
|
|
} else {
|
|
ei_it++ ;
|
|
}
|
|
}
|
|
}
|
|
|
|
in_event->remove() ;
|
|
|
|
/* Remove it from active event list. */
|
|
for ( ii = 0 ; ii < num_active_events ; ii++ ) {
|
|
if (in_event == active_events[ii]) {
|
|
for ( jj = ii + 1 ; jj < num_active_events ; jj++ ) {
|
|
active_events[jj - 1] = active_events[jj] ;
|
|
}
|
|
num_active_events-- ;
|
|
break ;
|
|
}
|
|
}
|
|
|
|
if (num_active_events == 0) {
|
|
TMM_delete_var_a(active_events);
|
|
active_events = NULL;
|
|
}
|
|
else {
|
|
active_events = (Trick::Event **)TMM_resize_array_1d_a(active_events, num_active_events);
|
|
}
|
|
|
|
if ( in_event->get_free_on_removal() ) {
|
|
TMM_delete_var_a(in_event) ;
|
|
}
|
|
|
|
return 0 ;
|
|
}
|
|
|
|
/**
|
|
@details
|
|
This is called from the S_define file. There will be one event processor assigned to each thread.
|
|
-# Add the incoming input processor to the list of known processors.
|
|
*/
|
|
void Trick::EventManager::add_event_processor(Trick::EventProcessor * in_ep) {
|
|
event_processors.push_back(in_ep) ;
|
|
}
|
|
|
|
//Executive time_tic changed. Update all event times
|
|
int Trick::EventManager::time_tic_changed() {
|
|
|
|
int old_tt ;
|
|
int tt ;
|
|
unsigned int ii ;
|
|
|
|
old_tt = exec_get_old_time_tic_value() ;
|
|
tt = exec_get_time_tic_value() ;
|
|
|
|
for ( ii = 0 ; ii < num_active_events ; ii++ ) {
|
|
active_events[ii]->set_next_tics((long long)round((active_events[ii]->get_next_tics() / old_tt) * tt)) ;
|
|
}
|
|
|
|
return 0 ;
|
|
}
|
|
|
|
// Remove all events attached to jobs before a checkpoint is reloaded.
|
|
int Trick::EventManager::preload_checkpoint() {
|
|
std::vector< Trick::EventInstrument * >::iterator ei_it ;
|
|
for ( ei_it = events_instrumented.begin() ; ei_it != events_instrumented.end() ; ) {
|
|
Trick::EventInstrument * found_event_instru = *ei_it ;
|
|
ei_it = events_instrumented.erase(ei_it) ;
|
|
found_event_instru->get_target_job()->remove_inst(found_event_instru->name) ;
|
|
delete found_event_instru ;
|
|
}
|
|
return 0 ;
|
|
}
|
|
|
|
//Restart job that reloads event_list from checkpointable structures
|
|
int Trick::EventManager::restart() {
|
|
unsigned int ii ;
|
|
|
|
for ( ii = 0 ; ii < num_active_events ; ii++ ) {
|
|
// rebuild the event_list of all events that were "added"
|
|
|
|
/* call the event restart routine to reset anything the event needs to do. */
|
|
active_events[ii]->restart() ;
|
|
|
|
if ( active_events[ii]->get_before_after() == Trick::EVENT_BEFORETARGET ) {
|
|
/* Update event list and insert an instrument job (containing in_event) target job's "before" queue. */
|
|
add_event_before( active_events[ii] , active_events[ii]->get_target_name() , active_events[ii]->get_target_inst() ) ;
|
|
} else if ( active_events[ii]->get_before_after() == Trick::EVENT_AFTERTARGET ) {
|
|
/* Update event list and insert an instrument job (containing in_event) target job's "after" queue. */
|
|
add_event_after( active_events[ii] , active_events[ii]->get_target_name() , active_events[ii]->get_target_inst() ) ;
|
|
} else {
|
|
/* Update event list for normal user events and read events. */
|
|
add_event(active_events[ii]);
|
|
}
|
|
}
|
|
return (0);
|
|
}
|
|
|