/* PURPOSE: ( Process an event. ) REFERENCE: ( Trick Simulation Environment ) ASSUMPTIONS AND LIMITATIONS: ( None ) CLASS: ( N/A ) LIBRARY DEPENDENCY: ( None ) PROGRAMMERS: ( Alex Lin NASA 2014 ) */ #include #include "trick/EventProcessor.hh" #include "trick/TrickConstant.hh" #include "trick/message_proto.h" #include "trick/message_type.h" /** @details -# Add the incoming event to the list of events to be added to the processor. */ void Trick::EventProcessor::add_event(Trick::Event * in_event) { pending_events.push_back(in_event) ; } /** @details -# Remove the incoming event from the set of events being processed -# If the event set is not empty set the process_event job to the first event's next job call time. -# Else set the process_event job to maximum time */ void Trick::EventProcessor::remove_event(Trick::Event * in_event) { std::multiset< Trick::Event *, CompareEventPtrs >::iterator sit = event_set.begin() ; for (sit=event_set.begin(); sit!=event_set.end(); ++sit) { if ((*sit) == in_event) { event_set.erase(sit) ; break; } } if ( !event_set.empty() ) { process_event_job->next_tics = (*(event_set.begin()))->get_next_tics() ; } else { // if there are no events, set the next job call time to max. process_event_job->next_tics = TRICK_MAX_LONG_LONG ; } } //Top of frame job to add new events to processing set. void Trick::EventProcessor::add_pending_events( long long curr_tics , bool is_restart ) { std::vector< Trick::Event * >::iterator it ; for ( it = pending_events.begin() ; it != pending_events.end() ; ) { if ( (*it)->get_cycle_tics() != 0 ) { // this is a cyclic event // If we are not calling this routine during a restart if ( ! is_restart ) { // Set the next time to the current time (*it)->set_next_tics( curr_tics ) ; } } else { // this is a one time event, test to see if the event time has past. if ( (*it)->get_next_tics() < curr_tics ) { // if the time has past, print warning and move to the next event. message_publish(MSG_WARNING, "One time event fire time has already past.\n") ; it = pending_events.erase(it) ; continue ; } } event_set.insert(*it) ; process_event_job->next_tics = (*(event_set.begin()))->get_next_tics() ; it = pending_events.erase(it) ; } } //Automatic job to process input file events. int Trick::EventProcessor::process_event( long long curr_tics ) { std::multiset< Trick::Event *, CompareEventPtrs >::iterator sit = event_set.begin() ; // while we have an event that matches the current time. while ( sit != event_set.end() and (*sit)->get_next_tics() == curr_tics ) { Trick::Event * curr_event = *sit ; // erase the current event out of the set. event_set.erase(sit) ; // if the event is active process it if ( curr_event->is_active() ) { curr_event->process(curr_tics) ; } // if the event has a cycle time, update the time and put the item back in the set if ( curr_event->get_cycle_tics() != 0 ) { curr_event->advance_next_tics() ; event_set.insert(curr_event) ; } // get the next top element of the set. sit = event_set.begin() ; } if ( !event_set.empty() ) { // set the next call time to the first item of the set. process_event_job->next_tics = (*(event_set.begin()))->get_next_tics() ; } else { // if there are no events, set the next job call time to max. process_event_job->next_tics = TRICK_MAX_LONG_LONG ; } return 0 ; } void Trick::EventProcessor::preload_checkpoint() { event_set.clear() ; }