#ifndef __JTRIGGER__JTRIGGERINTERFACE__ #define __JTRIGGER__JTRIGGERINTERFACE__ #include "JLang/JConversion.hh" #include "JTrigger/JTriggerException.hh" #include "JTrigger/JTriggerInput.hh" #include "JTrigger/JMatch.hh" #include "JTrigger/JModuleCounter.hh" #include "km3net-dataformat/online/JDAQTriggerMask.hh" /** * \author mdejong */ namespace JTRIGGER {} namespace JPP { using namespace JTRIGGER; } namespace JTRIGGER { using JLANG::JAssertConversion; using KM3NETDAQ::NUMBER_OF_TRIGGER_BITS; /** * Type definition of trigger bit. */ typedef unsigned int JTriggerbit_t; /** * Trigger interface. * This interface is used to define a unique bit for each trigger. */ class JTriggerInterface { protected: /** * Default constructor. */ JTriggerInterface() {} /** * Virtual destructor. */ virtual ~JTriggerInterface() {} /** * Auxiliary class for type definition of specific trigger bit. */ template struct JBit { static const JTriggerbit_t value = N; }; /** * Test whether specific trigger bit correponds to derived trigger class. * * This method will be specialised using the marco setTriggerBit() so that * it will return true if this triggered event corresponds to bit N. * * This method will be repeatedly called by method find_trigger_bit() * which in turn is called by the member method JTriggerInterface::getTriggerBit() * so that it returns the correct trigger bit. * * \return false */ template inline bool checkTriggerBit() const { return false; } /** * Recursive method to find the trigger bit of the given trigger data. * * \param bit trigger bit * \return trigger bit */ template inline JTriggerbit_t find_trigger_bit(JBit bit) const { if (checkTriggerBit()) return N; else return find_trigger_bit(JBit()); } /** * Termination method of recursive method to find the trigger bit of the given trigger data. * This method throws an error. * * \param bit trigger bit * \return trigger bit */ inline JTriggerbit_t find_trigger_bit(JBit bit) const { throw JTriggerException("Method find_trigger_bit<>(): no corresponding trigger bit found."); } /** * Get trigger name. * * This method will be specialised using the marco setTriggerBit() so that * it will return name of trigger for bit N. * * This method will be repeatedly called by method get_trigger_name() * which in turn is called by the method JTriggerInterface::getTriggerName() * so that it returns the correct trigger name. * * \return NULL */ template static const char* getTriggerName() { return NULL; } /** * Recursive method to get trigger name for given trigger bit. * * \param bit trigger bit * \param value trigger bit * \return trigger name */ template static const char* get_trigger_name(JBit bit, JTriggerbit_t value) { if (bit.value == value) return getTriggerName(); else return get_trigger_name(JBit(), value); } /** * Termination method of recursive method to get trigger name. * * \param bit trigger bit * \param value trigger bit * \return NULL */ static const char* get_trigger_name(JBit bit, JTriggerbit_t value) { return NULL; } public: typedef JTriggerInput::value_type value_type; typedef JMatch match_type; /** * Get the trigger bit. * * \return trigger bit */ inline JTriggerbit_t getTriggerBit() const { return find_trigger_bit(JBit<0>()); } /** * Get trigger name. * * param bit trigger bit * \return trigger name */ static const char* getTriggerName(JTriggerbit_t bit) { return get_trigger_name(JBit<0>(), bit); } }; /** * This class is used to map trigger class to trigger bit. * It will be specialised using the marco setTriggerBit(). * * The specialiation of this class will ensure unique use of a trigger class. * The trigger bit of a valid trigger class (i.e.\ one defined using * macro setTriggerBit()) is accessible using method getTriggerBit(). */ template struct JTriggerBit {}; /** * Get the trigger bit. * * \return trigger bit */ template inline JTriggerbit_t getTriggerBit() { return JTriggerBit::value; } /** * Get the trigger bit. * * \param event triggered event * \return trigger bit */ template inline JTriggerbit_t getTriggerBit(const JTrigger_t& event) { return JTriggerBit::value; } /** * Get trigger name. * * param bit trigger bit * \return trigger name */ inline const char* getTriggerName(JTriggerbit_t bit) { return JTriggerInterface::getTriggerName(bit); } /** * This class will generate a compiler error if trigger bit is out of range. */ template struct JAssertBit; /** * Implementation of a valid trigger bit. */ template struct JAssertBit {}; } /** * Macro to set trigger bit of a given trigger class. * * This macro should be called for each trigger class. * As a result, the trigger class is mapped to a unique bit. * This mapping is then avaiable in the following ways: * * -# The member method JTriggerInterface::getTriggerBit() * will return the specified trigger bit of the derived class; and * -# The trigger bit is stored as a static data member value of * the template class JTRIGGER::JTriggerBit. * * By using this macro, it is verified -at compile time- that: * -# The trigger bit is unique; * -# The trigger class derives from JTRIGGER::JTriggerInterface; and * -# The trigger class has not been associated to another trigger bit; * * \param JTrigger_t trigger class * \param N trigger bit */ #define setTriggerBit(JTrigger_t, N) \ \ \ template<> \ struct JTriggerBit : \ JAssertConversion, \ JAssertBit \ { \ static const JTriggerbit_t value = N; \ }; \ \ \ template<> \ inline bool JTriggerInterface::checkTriggerBit() const \ { \ return dynamic_cast(this) != NULL; \ } \ \ \ template<> \ const char* JTriggerInterface::getTriggerName() \ { \ return #JTrigger_t; \ } #endif