ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/UserCode/grimes/L1Menu/src/TriggerTable.cpp
Revision: 1.3
Committed: Tue Jun 4 08:17:37 2013 UTC (11 years, 11 months ago) by grimes
Branch: MAIN
CVS Tags: HEAD
Changes since 1.2: +0 -4 lines
Log Message:
Multiple changes. Implemented all required triggers, removed the ones not needed and changed some names.

File Contents

# User Rev Content
1 grimes 1.1 #include "l1menu/TriggerTable.h"
2    
3     #include "l1menu/ITrigger.h"
4    
5     #include <sstream>
6     #include <stdexcept>
7    
8 grimes 1.2 //
9     // Declare the pimple class
10     //
11     namespace l1menu
12     {
13     class TriggerTablePrivateMembers
14     {
15     public:
16     struct TriggerRegistryEntry
17     {
18     l1menu::TriggerTable::TriggerDetails details;
19     std::unique_ptr<l1menu::ITrigger> (*creationFunctionPointer)();
20     };
21     struct SuggestedBinning
22     {
23     unsigned int numberOfBins;
24     float lowerEdge;
25     float upperEdge;
26     };
27     std::vector<TriggerRegistryEntry> registeredTriggers;
28     std::map<std::string,std::map<std::string,SuggestedBinning> > suggestedBinning_;
29     const SuggestedBinning& getSuggestedBinning( const std::string& triggerName, const std::string& parameterName );
30     };
31    
32     } // end of namespace l1menu
33    
34     const l1menu::TriggerTablePrivateMembers::SuggestedBinning& l1menu::TriggerTablePrivateMembers::getSuggestedBinning( const std::string& triggerName, const std::string& parameterName )
35     {
36     const auto& iTriggerFindResult=suggestedBinning_.find(triggerName);
37     if( iTriggerFindResult==suggestedBinning_.end() )
38     {
39     throw std::runtime_error( "Trigger \""+triggerName+"\" has no suggested binning registered." );
40     }
41    
42     const auto& iParameterFindResult=iTriggerFindResult->second.find(parameterName);
43     if( iParameterFindResult==iTriggerFindResult->second.end() )
44     {
45     throw std::runtime_error( "Trigger \""+triggerName+"\" has no suggested binning registered for parameter \""+parameterName+"\"." );
46     }
47    
48     return iParameterFindResult->second;
49     }
50    
51     l1menu::TriggerTable& l1menu::TriggerTable::instance()
52     {
53     static TriggerTable onlyInstance;
54     return onlyInstance;
55     }
56    
57     l1menu::TriggerTable::TriggerTable() : pImple_( new l1menu::TriggerTablePrivateMembers )
58     {
59     // No operation. Only declared so that it can be declared private.
60     }
61    
62     l1menu::TriggerTable::~TriggerTable()
63     {
64     // No operation. Only declared so that it can be declared private.
65     }
66 grimes 1.1
67     bool l1menu::TriggerTable::TriggerDetails::operator==( const l1menu::TriggerTable::TriggerDetails& otherTriggerDetails ) const
68     {
69     return name==otherTriggerDetails.name && version==otherTriggerDetails.version;
70     }
71    
72 grimes 1.2 std::unique_ptr<l1menu::ITrigger> l1menu::TriggerTable::getTrigger( const std::string& name ) const
73 grimes 1.1 {
74     // std::cout << "Looking for latest version of " << name << std::endl;
75    
76 grimes 1.2 std::unique_ptr<l1menu::ITrigger> returnValue;
77 grimes 1.1 unsigned int highestVersionNumber=0; // The highest version of the trigger encountered in the list so far
78    
79 grimes 1.2 for( std::vector<TriggerTablePrivateMembers::TriggerRegistryEntry>::const_iterator iRegistryEntry=pImple_->registeredTriggers.begin(); iRegistryEntry!=pImple_->registeredTriggers.end(); ++iRegistryEntry )
80 grimes 1.1 {
81     if( iRegistryEntry->details.name==name && iRegistryEntry->details.version>=highestVersionNumber )
82     {
83     returnValue=(*iRegistryEntry->creationFunctionPointer)();
84     highestVersionNumber=iRegistryEntry->details.version;
85     }
86     }
87    
88     return returnValue;
89     }
90    
91 grimes 1.2 std::unique_ptr<l1menu::ITrigger> l1menu::TriggerTable::getTrigger( const std::string& name, unsigned int version ) const
92 grimes 1.1 {
93     TriggerDetails requestedTriggerDetails{ name, version };
94    
95     // Delegate to the other overload
96     return getTrigger( requestedTriggerDetails );
97     }
98    
99 grimes 1.2 std::unique_ptr<l1menu::ITrigger> l1menu::TriggerTable::getTrigger( const TriggerDetails& details ) const
100 grimes 1.1 {
101     // std::cout << "Looking for version " << details.version << " of " << details.name << std::endl;
102    
103 grimes 1.2 for( std::vector<TriggerTablePrivateMembers::TriggerRegistryEntry>::const_iterator iRegistryEntry=pImple_->registeredTriggers.begin(); iRegistryEntry!=pImple_->registeredTriggers.end(); ++iRegistryEntry )
104 grimes 1.1 {
105     if( iRegistryEntry->details==details )
106     {
107     return (*iRegistryEntry->creationFunctionPointer)();
108     }
109     }
110    
111     // If program flow has reached this point then there are no triggers registered that
112     // match the criteria. Return an empty pointer.
113 grimes 1.2 return std::unique_ptr<l1menu::ITrigger>();
114 grimes 1.1 }
115    
116 grimes 1.2 std::unique_ptr<l1menu::ITrigger> l1menu::TriggerTable::copyTrigger( const l1menu::ITrigger& triggerToCopy ) const
117 grimes 1.1 {
118     // First create a trigger with the matching name and version
119 grimes 1.2 std::unique_ptr<l1menu::ITrigger> newTrigger=getTrigger( triggerToCopy.name(), triggerToCopy.version() );
120 grimes 1.1
121     if( newTrigger.get()==NULL ) throw std::runtime_error( "Unable to copy trigger "+triggerToCopy.name() );
122    
123     //
124     // Now copy all of the parameters over.
125     //
126     // Get the parameter names
127     std::vector<std::string> parameterNames=triggerToCopy.parameterNames();
128     // Then run through and copy the value of each one
129     for( std::vector<std::string>::const_iterator iName=parameterNames.begin(); iName!=parameterNames.end(); ++iName )
130     {
131     newTrigger->parameter(*iName)=triggerToCopy.parameter(*iName);
132     }
133    
134     return newTrigger;
135     }
136    
137     std::vector<l1menu::TriggerTable::TriggerDetails> l1menu::TriggerTable::listTriggers() const
138     {
139     std::vector<TriggerDetails> returnValue;
140    
141     // Copy the relevant parts from the registered triggers into the return value
142 grimes 1.2 for( std::vector<TriggerTablePrivateMembers::TriggerRegistryEntry>::const_iterator iRegistryEntry=pImple_->registeredTriggers.begin(); iRegistryEntry!=pImple_->registeredTriggers.end(); ++iRegistryEntry )
143 grimes 1.1 {
144     returnValue.push_back( iRegistryEntry->details );
145     }
146    
147     return returnValue;
148     }
149    
150 grimes 1.2 void l1menu::TriggerTable::registerTrigger( const std::string& name, unsigned int version, std::unique_ptr<l1menu::ITrigger> (*creationFunctionPointer)() )
151 grimes 1.1 {
152     TriggerDetails newTriggerDetails{ name, version };
153    
154     // First make sure there is not a trigger with the same name and version already registered
155 grimes 1.2 for( std::vector<TriggerTablePrivateMembers::TriggerRegistryEntry>::const_iterator iRegistryEntry=pImple_->registeredTriggers.begin(); iRegistryEntry!=pImple_->registeredTriggers.end(); ++iRegistryEntry )
156 grimes 1.1 {
157     if( iRegistryEntry->details==newTriggerDetails )
158     {
159     std::stringstream errorMessage;
160     errorMessage << "A trigger called \"" << newTriggerDetails.name << "\" with version " << newTriggerDetails.version << " has already been registered in the trigger table.";
161     throw std::logic_error( errorMessage.str() );
162     }
163     }
164    
165     // If program flow has reached this point then there are no triggers with the same name
166     // and version already registered, so it's okay to add the trigger as requested.
167 grimes 1.2 pImple_->registeredTriggers.push_back( TriggerTablePrivateMembers::TriggerRegistryEntry{newTriggerDetails,creationFunctionPointer} );
168     }
169    
170     void l1menu::TriggerTable::registerSuggestedBinning( const std::string& triggerName, const std::string& parameterName, unsigned int numberOfBins, float lowerEdge, float upperEdge )
171     {
172     pImple_->suggestedBinning_[triggerName][parameterName]={ numberOfBins, lowerEdge, upperEdge };
173     }
174    
175     unsigned int l1menu::TriggerTable::getSuggestedNumberOfBins( const std::string& triggerName, const std::string& parameterName ) const
176     {
177     try
178     {
179     return pImple_->getSuggestedBinning( triggerName, parameterName ).numberOfBins;
180     }
181     catch( std::runtime_error& error )
182     {
183     throw std::runtime_error( std::string("TriggerTable::getSuggestedNumberOfBins - ")+error.what() );
184     }
185     }
186    
187     float l1menu::TriggerTable::getSuggestedLowerEdge( const std::string& triggerName, const std::string& parameterName ) const
188     {
189     try
190     {
191     return pImple_->getSuggestedBinning( triggerName, parameterName ).lowerEdge;
192     }
193     catch( std::runtime_error& error )
194     {
195     throw std::runtime_error( std::string("TriggerTable::getSuggestedLowerEdge - ")+error.what() );
196     }
197     }
198    
199     float l1menu::TriggerTable::getSuggestedUpperEdge( const std::string& triggerName, const std::string& parameterName ) const
200     {
201     try
202     {
203     return pImple_->getSuggestedBinning( triggerName, parameterName ).upperEdge;
204     }
205     catch( std::runtime_error& error )
206     {
207     throw std::runtime_error( std::string("TriggerTable::getSuggestedUpperEdge - ")+error.what() );
208     }
209 grimes 1.1 }