File indexing completed on 2025-07-15 09:15:55
0001
0002
0003
0004
0005 #pragma once
0006
0007 #include <vector>
0008 #include <type_traits>
0009
0010 #include <JANA/JApplication.h>
0011 #include <JANA/JFactory.h>
0012 #include <JANA/JObject.h>
0013 #include <JANA/JVersion.h>
0014 #include <JANA/Utils/JTypeInfo.h>
0015 #include <JANA/Components/JLightweightOutput.h>
0016
0017 #if JANA2_HAVE_ROOT
0018 #include <TObject.h>
0019 #endif
0020
0021
0022 template<typename T>
0023 class JFactoryT : public JFactory {
0024 public:
0025
0026 using IteratorType = typename std::vector<T*>::const_iterator;
0027 using PairType = std::pair<IteratorType, IteratorType>;
0028
0029 JFactoryT(std::string tag="") {
0030 mOutput.GetDatabundle().AttachData(&mData);
0031 SetTag(tag);
0032 SetPrefix(mOutput.GetDatabundle().GetUniqueName());
0033 SetObjectName(mOutput.GetDatabundle().GetTypeName());
0034
0035 EnableGetAs<T>();
0036 EnableGetAs<JObject>( std::is_convertible<T,JObject>() );
0037 #if JANA2_HAVE_ROOT
0038 EnableGetAs<TObject>( std::is_convertible<T,TObject>() );
0039 #endif
0040 }
0041
0042 ~JFactoryT() override = default;
0043
0044 void Init() override {}
0045 void BeginRun(const std::shared_ptr<const JEvent>&) override {}
0046 void ChangeRun(const std::shared_ptr<const JEvent>&) override {}
0047 void EndRun() override {}
0048 void Process(const std::shared_ptr<const JEvent>&) override {}
0049
0050
0051 void SetTag(std::string tag) { mOutput.SetShortName(tag); }
0052
0053 std::type_index GetObjectType(void) const override {
0054 return std::type_index(typeid(T));
0055 }
0056
0057 std::size_t GetNumObjects(void) const override {
0058 return mData.size();
0059 }
0060
0061
0062
0063
0064
0065 PairType CreateAndGetData(const std::shared_ptr<const JEvent>& event) {
0066 Create(*event.get());
0067 return std::make_pair(mData.cbegin(), mData.cend());
0068 }
0069
0070 PairType CreateAndGetData(const JEvent& event) {
0071 Create(event);
0072 return std::make_pair(mData.cbegin(), mData.cend());
0073 }
0074
0075
0076 const std::vector<T*>& GetData() {
0077 return mData;
0078 }
0079
0080
0081 [[deprecated]]
0082 void Set(const std::vector<JObject*>& aData) override {
0083 std::vector<T*> data;
0084 for (auto obj : aData) {
0085 T* casted = dynamic_cast<T*>(obj);
0086 assert(casted != nullptr);
0087 data.push_back(casted);
0088 }
0089 Set(std::move(data));
0090 }
0091
0092
0093 [[deprecated]]
0094 void Insert(JObject* aDatum) override {
0095 T* casted = dynamic_cast<T*>(aDatum);
0096 assert(casted != nullptr);
0097 Insert(casted);
0098 }
0099
0100 virtual void Set(const std::vector<T*>& aData) {
0101 if (aData == mData) {
0102
0103
0104
0105
0106 mStatus = Status::Inserted;
0107 mCreationStatus = CreationStatus::Inserted;
0108 }
0109 else {
0110 ClearData();
0111 mData = aData;
0112 mStatus = Status::Inserted;
0113 mCreationStatus = CreationStatus::Inserted;
0114 }
0115 }
0116
0117 virtual void Set(std::vector<T*>&& aData) {
0118 ClearData();
0119 mData = std::move(aData);
0120 mStatus = Status::Inserted;
0121 mCreationStatus = CreationStatus::Inserted;
0122 }
0123
0124 virtual void Insert(T* aDatum) {
0125 mData.push_back(aDatum);
0126 mStatus = Status::Inserted;
0127 mCreationStatus = CreationStatus::Inserted;
0128 }
0129
0130
0131 inline void SetFactoryFlag(JFactory_Flags_t f) override {
0132 switch (f) {
0133 case JFactory::PERSISTENT: SetPersistentFlag(true); break;
0134 case JFactory::NOT_OBJECT_OWNER: SetNotOwnerFlag(true); break;
0135 case JFactory::REGENERATE: SetRegenerateFlag(true); break;
0136 case JFactory::WRITE_TO_OUTPUT: SetWriteToOutputFlag(true); break;
0137 default: throw JException("Invalid factory flag");
0138 }
0139 }
0140
0141
0142 inline void ClearFactoryFlag(JFactory_Flags_t f) {
0143 switch (f) {
0144 case JFactory::PERSISTENT: SetPersistentFlag(false); break;
0145 case JFactory::NOT_OBJECT_OWNER: SetNotOwnerFlag(false); break;
0146 case JFactory::REGENERATE: SetRegenerateFlag(false); break;
0147 case JFactory::WRITE_TO_OUTPUT: SetWriteToOutputFlag(false); break;
0148 default: throw JException("Invalid factory flag");
0149 }
0150 }
0151
0152 inline void SetPersistentFlag(bool persistent) {
0153 mOutput.GetDatabundle().SetPersistentFlag(persistent);
0154 }
0155
0156 inline void SetNotOwnerFlag(bool not_owner) {
0157 mOutput.GetDatabundle().SetNotOwnerFlag(not_owner);
0158 }
0159
0160
0161
0162
0163
0164
0165
0166 template <typename S> void EnableGetAs ();
0167
0168
0169
0170 template <typename S> void EnableGetAs(std::true_type) { EnableGetAs<S>(); }
0171 template <typename S> void EnableGetAs(std::false_type) {}
0172
0173 void ClearData() override {
0174
0175
0176
0177 if (mStatus == Status::Uninitialized) {
0178
0179 return;
0180 }
0181 mStatus = Status::Unprocessed;
0182 mCreationStatus = CreationStatus::NotCreatedYet;
0183 for (auto* output : GetDatabundleOutputs()) {
0184 for (auto* db : output->GetDatabundles()) {
0185 db->ClearData();
0186 }
0187 }
0188 }
0189
0190
0191 protected:
0192 jana::components::Output<T> mOutput {this};
0193 std::vector<T*> mData;
0194 };
0195
0196 template<typename T>
0197 template<typename S>
0198 void JFactoryT<T>::EnableGetAs() {
0199
0200 auto upcast_lambda = [this]() {
0201 std::vector<S*> results;
0202 for (auto t : mData) {
0203 results.push_back(static_cast<S*>(t));
0204 }
0205 return results;
0206 };
0207
0208 auto key = std::type_index(typeid(S));
0209 using upcast_fn_t = std::function<std::vector<S*>()>;
0210 mUpcastVTable[key] = std::unique_ptr<JAny>(new JAnyT<upcast_fn_t>(std::move(upcast_lambda)));
0211 }
0212
0213