Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-09-16 09:14:47

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