Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-10-19 09:07:56

0001 
0002 // Copyright 2020, Jefferson Science Associates, LLC.
0003 // Subject to the terms in the LICENSE file found in the top-level directory.
0004 
0005 #include <iterator>
0006 #include <unistd.h>
0007 
0008 #include "JFactorySet.h"
0009 #include "JANA/Utils/JTablePrinter.h"
0010 #include "JFactory.h"
0011 
0012 //---------------------------------
0013 // JFactorySet    (Constructor)
0014 //---------------------------------
0015 JFactorySet::JFactorySet(void)
0016 {
0017 
0018 }
0019 
0020 //---------------------------------
0021 // ~JFactorySet    (Destructor)
0022 //---------------------------------
0023 JFactorySet::~JFactorySet()
0024 {
0025     // Delete all databundles NOT owned by a factory
0026     for (auto* databundle : mDatabundles) {
0027         if (databundle->GetFactory() == nullptr) {
0028             delete databundle;
0029         }
0030     }
0031 
0032     // Delete the factories, which clears and deletes THEIR databundles
0033     for (auto* factory : mFactories) delete factory;
0034 }
0035 
0036 //---------------------------------
0037 // Add
0038 //---------------------------------
0039 void JFactorySet::Add(JDatabundle* databundle) {
0040     if (databundle->GetUniqueName().empty()) {
0041         throw JException("Attempted to add a databundle with no unique_name");
0042     }
0043     auto named_result = mDatabundleFromUniqueName.find(databundle->GetUniqueName());
0044     if (named_result != std::end(mDatabundleFromUniqueName)) {
0045         // Collection is duplicate. Since this almost certainly indicates a user error, and
0046         // the caller will not be able to do anything about it anyway, throw an exception.
0047         // We show the user which factory is causing this problem, including both plugin names
0048 
0049         auto ex = JException("Attempted to add duplicate databundles");
0050         ex.function_name = "JFactorySet::Add";
0051         ex.instance_name = databundle->GetUniqueName();
0052 
0053         auto fac = databundle->GetFactory();
0054         if (fac != nullptr) {
0055             ex.type_name = fac->GetTypeName();
0056             ex.plugin_name = fac->GetPluginName();
0057             if (named_result->second->GetFactory() != nullptr) {
0058                 ex.plugin_name += ", " + named_result->second->GetFactory()->GetPluginName();
0059             }
0060         }
0061         throw ex;
0062     }
0063 
0064     mDatabundles.push_back(databundle);
0065     mDatabundleFromUniqueName[databundle->GetUniqueName()] = databundle;
0066     mDatabundleFromTypeIndexAndEitherName[{databundle->GetTypeIndex(), databundle->GetUniqueName()}] = databundle;
0067     mDatabundleFromTypeIndexAndEitherName[{databundle->GetTypeIndex(), databundle->GetShortName()}] = databundle;
0068     mDatabundleFromTypeNameAndEitherName[{databundle->GetTypeName(), databundle->GetUniqueName()}] = databundle;
0069     mDatabundleFromTypeNameAndEitherName[{databundle->GetTypeName(), databundle->GetShortName()}] = databundle;
0070     mDatabundlesFromTypeIndex[databundle->GetTypeIndex()].push_back(databundle);
0071     mDatabundlesFromTypeName[databundle->GetTypeName()].push_back(databundle);
0072 }
0073 
0074 //---------------------------------
0075 // Add
0076 //---------------------------------
0077 void JFactorySet::Add(JFactory* factory)
0078 {
0079     /// Add a JFactory to this JFactorySet. The JFactorySet assumes ownership of this factory.
0080     /// If the JFactorySet already contains a JFactory with the same key,
0081     /// throw an exception and let the user figure out what to do.
0082     /// This scenario occurs when the user has multiple JFactory<T> producing the
0083     /// same T JObject, and is not distinguishing between them via tags.
0084     /// Returns bool indicating whether the add succeeded.
0085 
0086     if (factory->GetLevel() != mLevel && mLevel != JEventLevel::None && factory->GetLevel() != JEventLevel::None) {
0087         //LOG << "    Skipping factory with type_name=" << factory->GetTypeName()
0088         //    << ", level=" << toString(factory->GetLevel())
0089         //    << " to event with level= " << toString(mLevel);
0090         delete factory;
0091         return;
0092     }
0093     /*
0094     else {
0095         LOG << "    Adding factory with type_name=" << factory->GetTypeName()
0096             << ", level=" << toString(factory->GetLevel())
0097             << " to event with level= " << toString(mLevel);
0098     }
0099     */
0100 
0101     mFactories.push_back(factory);
0102 
0103     for (auto* output : factory->GetOutputs()) {
0104         if (output->GetLevel() != mLevel && output->GetLevel() != JEventLevel::None) {
0105             auto ex = JException("Factory outputs are required to be at the same level as the factory itself. Factory level = %s, output level = %s", 
0106                              toString(factory->GetLevel()).c_str(), 
0107                              toString(output->GetLevel()).c_str());
0108             ex.instance_name = factory->GetPrefix();
0109             ex.function_name = "JFactorySet::Add";
0110             ex.plugin_name = factory->GetPluginName();
0111             throw ex;
0112         }
0113         auto* databundle = output->GetDatabundle();
0114         databundle->SetFactory(factory); // It's a little weird to set this here
0115         Add(databundle);
0116     }
0117     for (auto* variadic_output : factory->GetVariadicOutputs()) {
0118         if (variadic_output->GetLevel() != mLevel && variadic_output->GetLevel() != JEventLevel::None) {
0119             auto ex = JException("Factory outputs are required to be at the same level as the factory itself. Factory level = %s, output level = %s", 
0120                              toString(factory->GetLevel()).c_str(), 
0121                              toString(variadic_output->GetLevel()).c_str());
0122             ex.instance_name = factory->GetPrefix();
0123             ex.function_name = "JFactorySet::Add";
0124             ex.plugin_name = factory->GetPluginName();
0125             throw ex;
0126         }
0127         for (const auto& databundle : variadic_output->GetDatabundles()) {
0128             databundle->SetFactory(factory); // It's a little weird to set this here
0129             Add(databundle);
0130         }
0131     }
0132 }
0133 
0134 //---------------------------------
0135 // GetDatabundle
0136 //---------------------------------
0137 JDatabundle* JFactorySet::GetDatabundle(const std::string& unique_name) const {
0138     auto it = mDatabundleFromUniqueName.find(unique_name);
0139     if (it != std::end(mDatabundleFromUniqueName)) {
0140         return it->second;
0141     }
0142     return nullptr;
0143 }
0144 
0145 //---------------------------------
0146 // GetDatabundle
0147 //---------------------------------
0148 JDatabundle* JFactorySet::GetDatabundle(const std::string& object_type_name, const std::string& unique_or_short_name) const {
0149     auto it = mDatabundleFromTypeNameAndEitherName.find({object_type_name, unique_or_short_name});
0150     if (it != std::end(mDatabundleFromTypeNameAndEitherName)) {
0151         return it->second;
0152     }
0153     return nullptr;
0154 }
0155 
0156 //---------------------------------
0157 // GetDatabundle
0158 //---------------------------------
0159 JDatabundle* JFactorySet::GetDatabundle(std::type_index object_type_index, const std::string& unique_or_short_name) const {
0160     auto it = mDatabundleFromTypeIndexAndEitherName.find({object_type_index, unique_or_short_name});
0161     if (it != std::end(mDatabundleFromTypeIndexAndEitherName)) {
0162         return it->second;
0163     }
0164     return nullptr;
0165 }
0166 
0167 //---------------------------------
0168 // GetDatabundles
0169 //---------------------------------
0170 const std::vector<JDatabundle*>& JFactorySet::GetDatabundles(std::type_index index) const {
0171     static std::vector<JDatabundle*> no_databundles {};
0172     auto it = mDatabundlesFromTypeIndex.find(index);
0173     if (it != std::end(mDatabundlesFromTypeIndex)) {
0174         return it->second;
0175     }
0176     return no_databundles;
0177 }
0178 
0179 //---------------------------------
0180 // Print
0181 //---------------------------------
0182 void JFactorySet::Print() const {
0183 
0184     JTablePrinter table;
0185     table.AddColumn("Factory type name");
0186     table.AddColumn("Factory prefix");
0187     table.AddColumn("Databundle type name");
0188     table.AddColumn("Databundle unique name");
0189     table.AddColumn("Status");
0190     table.AddColumn("Size");
0191 
0192     for (auto* factory : mFactories) {
0193         for (auto* output: factory->GetOutputs()) {
0194             auto* databundle = output->GetDatabundle();
0195             table | (factory->GetTypeName().empty() ? "[Unset]" : factory->GetTypeName());
0196             table | factory->GetPrefix();
0197             table | databundle->GetTypeName();
0198             table | databundle->GetUniqueName();
0199             switch (databundle->GetStatus()) {
0200                 case JDatabundle::Status::Empty:    table | "Empty";    break;
0201                 case JDatabundle::Status::Created:  table | "Created";  break;
0202                 case JDatabundle::Status::Inserted: table | "Inserted"; break;
0203                 case JDatabundle::Status::Excepted: table | "Excepted"; break;
0204             }
0205             table | databundle->GetSize();
0206         }
0207         for (auto* output: factory->GetVariadicOutputs()) {
0208             for (auto* databundle: output->GetDatabundles()) {
0209                 table | (factory->GetTypeName().empty() ? "[Unset]" : factory->GetTypeName());
0210                 table | factory->GetPrefix();
0211                 table | databundle->GetTypeName();
0212                 table | databundle->GetUniqueName();
0213                 switch (databundle->GetStatus()) {
0214                     case JDatabundle::Status::Empty:    table | "Empty";    break;
0215                     case JDatabundle::Status::Created:  table | "Created";  break;
0216                     case JDatabundle::Status::Inserted: table | "Inserted"; break;
0217                     case JDatabundle::Status::Excepted: table | "Excepted"; break;
0218                 }
0219                 table | databundle->GetSize();
0220             }
0221         }
0222     }
0223     for (auto* databundle : mDatabundles) {
0224         if (databundle->GetFactory() == nullptr) {
0225             table | "[None]";
0226             table | "[None]";
0227             table | databundle->GetTypeName();
0228             table | databundle->GetUniqueName();
0229             switch (databundle->GetStatus()) {
0230                 case JDatabundle::Status::Empty:    table | "Empty";    break;
0231                 case JDatabundle::Status::Created:  table | "Created";  break;
0232                 case JDatabundle::Status::Inserted: table | "Inserted"; break;
0233                 case JDatabundle::Status::Excepted: table | "Excepted"; break;
0234             }
0235             table | databundle->GetSize();
0236         }
0237     }
0238     table.Render(std::cout);
0239 }
0240 
0241 //---------------------------------
0242 // Clear
0243 //---------------------------------
0244 void JFactorySet::Clear() {
0245 
0246     for (auto* factory : mFactories) {
0247         factory->ClearData();
0248     }
0249     for (auto* databundle : mDatabundles) {
0250         // Clear any databundles that did not come from a JFactory
0251         if (databundle->GetFactory() == nullptr) {
0252             databundle->ClearData();
0253         }
0254     }
0255 }
0256 
0257 //---------------------------------
0258 // Finish
0259 //---------------------------------
0260 void JFactorySet::Finish() {
0261     for (auto& factory : mFactories) {
0262         factory->DoFinish();
0263     }
0264 }
0265