#ifndef __JTRIGGERINTERFACE__ #define __JTRIGGERINTERFACE__ #include "JLang/JConversion.hh" #include "JLang/JAssert.hh" #include "JTrigger/JEvent.hh" #include "JTrigger/JTriggerException.hh" namespace JTRIGGER { namespace { using JLANG::JAssertConversion; using JLANG::JAssert; } /** * maximal number of hits to apply trigger logic (above this limit, always trigger) */ static const int FACTORY_LIMIT = 10000; /** * Trigger interface. * This interface is used to define a unique bit for each trigger. */ class JTriggerInterface { protected: /** * Default constructor. */ JTriggerInterface() {} /** * Virtual destructor. */ virtual ~JTriggerInterface() {} public: /** * Get the trigger bit. * * \return trigger bit */ unsigned int getTriggerBit() const; }; /** * 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 as JTriggerBit<...>::value; */ template struct JTriggerBit {}; namespace { /** * Auxiliary class to ensure unique use of specific trigger bit. * This class will be specialised using the marco setTriggerBit(). */ template struct JBit {}; /** * Test whether specific trigger bit correponds to given trigger data. * This method will be overloaded using the marco setTriggerBit(). * * This method will be recursively called by method find_trigger_bit() * which is in turn called by the member method getTriggerBit() of * the class JTriggerInterface so that it returns the correct trigger bit. * * \param data trigger data * \return true if trigger data correspond to bit N; else false */ template inline bool checkTriggerBit(const JTriggerInterface& data) { return false; } /** * Test whether trigger bit is valid. * * The value is true when trigger bit is valid. */ template struct JBitTest { enum { value = N < NUMBER_OF_TRIGGER_BITS }; }; /** * This class will generate a compiler error if trigger bit is out of range. */ template::value> struct JAssertBit; template struct JAssertBit {}; /** * Recursive method to find the trigger bit of the given trigger data. * * \param data trigger data * \return trigger bit */ template inline unsigned int find_trigger_bit(const JTriggerInterface& data) { if (checkTriggerBit(data)) return N; else return find_trigger_bit(data); } /** * Termination method of recursive method to find the trigger bit of the given trigger data. * This method throws an error. * * \param data trigger data * \return trigger bit */ template<> inline unsigned int find_trigger_bit(const JTriggerInterface& data) { throw JTriggerException("Method: find_trigger_bit<>() no corresponding trigger bit found."); } } /** * Get the trigger bit. * * \return trigger bit */ unsigned int JTriggerInterface::getTriggerBit() const { return find_trigger_bit<0>(*this); } /** * Check the trigger mask of given event. * * \param event event * \return true if JTrigger_t fired in event; else false */ template inline bool checkTriggerMask(const JEvent& event) { return (event.getTriggerMask() & getTriggerMask(JTriggerBit::value)); } } /** * 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 bit. * This mapping is avaiable in the following ways: * * - The member method JTriggerInterface::getTriggerBit() * will return the specified trigger bit. * * - The trigger bit is stored as a static data member of * the template class JTriggerBit, i.e. JTriggerBit::value; * * By using this macro, it is verified (at compile time) that: * - The trigger bit is unique; * - The trigger class derives from JTriggerInterface; * - 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 \ { \ static const unsigned int value = N; \ }; \ \ \ namespace { \ \ template<> \ struct JBit : \ JAssertBit \ { \ static const unsigned int value = N; \ }; \ \ \ template<> \ inline bool checkTriggerBit(const JTriggerInterface& data) \ { \ return dynamic_cast(&data) != NULL; \ } \ } #endif