/////////////////////////////////////////////////////////////////// // // A logical group of processors to be executed sequentially. // // A processor block is analogous to a C++ block of statements. // It consists of a list of processors which it runs sequentially when // DSEvent() is called. // // A proc block is an instance of a processor that does no processing // itself rather it calls the processors in it's list. Note that // these processors themselves may be ProcBlocks or derivatives // thereof. // // ProcBlock's have 5 commands to add and alter the processors in // the list. As is common in rat the command will act on the previous // processor (or ProcBlock) where appropriate i.e. the end command // will act on a previous ConditionalProcBlock rather than this // ProcBlock. // // A ProcBlock will accept new commands until it is Closed. // // Author: Stan Seibert // P G Jones // // REVISION HISTORY: // 21/01/2013 : P G Jones - Added start and end of run methods. // 2013-10-11 : P G Jones - Added conditional processor ability. // 2015-05-13 : W Heintzelman - add debug printout so one can easily // identify the process in which a run crashed. // /////////////////////////////////////////////////////////////////// #ifndef __RAT_ProcBlock__ #define __RAT_ProcBlock__ #include #include #include #include namespace RAT { class ProcBlock : public Processor { public: // What type of end block command was issued enum EEndCommand { eEndIf, // endif command, applies to ConditionalProcBlock only eEndWhile, // endwhile command, applies to WhileProcBlock only eEndBlock }; // endblock command, applies to this/ProcBlock only // Construct the ProcBlock // // name: ProcBlock name, defaults to ProcBlock ProcBlock( const std::string& name=std::string( "ProcBlock" ) ); // Close the processor block virtual ~ProcBlock(); // Command to add a new processor // // proc: Processor to add virtual void AddProcessorCommand( Processor* const proc ); // Command to add a new process to the end of the list // // Processor is only added after the block is closed // // proc: Processor to defer add virtual void DeferAddProcessorCommand( Processor* const proc ); // Command to add a new ConditionalProcBlock to the list // // Subsequent AddCommands will be passed to this ProcBlock until it is closed. // // proc: Processor the ConditionalProcBlock should be conditional upon. virtual void IfCommand( Processor* const proc ); // Command to switch the last ConditionalProcBlock to false mode. // // Will Log::Die if last processor is closed. virtual void ElseCommand(); // Command to add a new WhileProcBlock to the list, with the // // Subsequent AddCommands will be passed to this ProcBlock until it is closed. // // proc: Processor the WhileProcBlock should be conditional upon. virtual void WhileCommand( Processor* const proc ); // Close the the current ProcBlock // // Will close this ProcBlock if no nested ProcBlocks are open // // type: Identifies the command used, block will Log::Die if incorrect command applied. virtual void EndCommand( const EEndCommand type ); // Called at the beginning of a run // // Each processor is called in turn // // run: Data structure for the run virtual void BeginOfRun( DS::Run& run ); // Called for each event // // Each processor is called in turn // // run: Data structure for the run // ds: Data structure for the event // // Returns a Is the net condition for all processors in the list, will be OK, FAIL or ABORT virtual Processor::Result DSEvent( DS::Run& run, DS::Entry& ds ); // Called at the end of a run. // // Each processor is called in turn // // run: Data structure for the run virtual void EndOfRun( DS::Run& run ); // Is this block open // // Returns a true if the block is open, false if not bool IsOpen() const { return fOpen; } // Closes THIS clock. virtual void CloseBlock(); protected: // This function calls the processor's DSEvent method with a wrapper to time the execution // // proc: the Processor to run // profiler: the profiler for the processor // run: Data structure for the run // ds: Data structure for the event Processor::Result ProcessEvent( Processor* const proc, Profiler& profiler, DS::Run& run, DS::Entry& ds ); std::vector fEventProfilers; // Profiler details by processor (total time, calls) for DSEvents std::vector fBeginProfilers; // Profiler details by processor (total time, calls) for BeginOfRun std::vector fEndProfilers; // Profiler details by processor (total time, calls) for EndOfRun std::vector fProcessorList; // List of processors executed by this ProcBlock for each DSEvent std::vector fDeferProcessorList; // List of processors to be added to the end of the ProcessorList on close of the block. ProcBlock* fLastAddedProcessor; // A pointer to the last added processor IFF it is a ProcBlock or derivative. bool fOpen; // Bool to state whether this ProcBlock is open or closed. }; } // namespace RAT #endif