diff --git a/src/libraries/JANA/JFactory.cc b/src/libraries/JANA/JFactory.cc index 1366d92ce..f5ffae1a2 100644 --- a/src/libraries/JANA/JFactory.cc +++ b/src/libraries/JANA/JFactory.cc @@ -34,6 +34,12 @@ void JFactory::Create(const std::shared_ptr& event) { throw ex; } } + + if (TestFactoryFlag(REGENERATE) && (mStatus == Status::Inserted)) { + ClearData(); + // ClearData will reset mStatus to Status::Unprocessed + } + if (mStatus == Status::Unprocessed) { try { if (mPreviousRunNumber == -1) { diff --git a/src/libraries/JANA/JFactory.h b/src/libraries/JANA/JFactory.h index abc10f89c..cabaa9930 100644 --- a/src/libraries/JANA/JFactory.h +++ b/src/libraries/JANA/JFactory.h @@ -32,10 +32,11 @@ class JFactory { enum class CreationStatus { NotCreatedYet, Created, Inserted, InsertedViaGetObjects, NeverCreated }; enum JFactory_Flags_t { - JFACTORY_NULL = 0x00, - PERSISTENT = 0x01, - WRITE_TO_OUTPUT = 0x02, - NOT_OBJECT_OWNER = 0x04 + JFACTORY_NULL = 0x00, // Not used anywhere + PERSISTENT = 0x01, // Used heavily. Possibly better served by JServices, hierarchical events, or event groups. + WRITE_TO_OUTPUT = 0x02, // Set in halld_recon but not read except by JANA1 janaroot and janacontrol plugins + NOT_OBJECT_OWNER = 0x04, // Used heavily. Small conflict with PODIO subset collections, which do the same thing at a different level + REGENERATE = 0x08 // Replaces JANA1 JFactory_base::use_factory and JFactory::GetCheckSourceFirst() }; JFactory(std::string aName, std::string aTag = "") @@ -69,6 +70,7 @@ class JFactory { void SetPreviousRunNumber(uint32_t aRunNumber) { mPreviousRunNumber = aRunNumber; } + // Note: JFactory_Flags_t is going to be deprecated. Use Set...Flag()s instead /// Get all flags in the form of a single word inline uint32_t GetFactoryFlags() const { return mFlags; } @@ -87,6 +89,38 @@ class JFactory { return (mFlags & (uint32_t) f) == (uint32_t) f; } + inline void SetPersistentFlag(bool persistent) { + if (persistent) { + SetFactoryFlag(PERSISTENT); } + else { + ClearFactoryFlag(PERSISTENT); } + } + + inline void SetNotOwnerFlag(bool not_owner) { + if (not_owner) { + SetFactoryFlag(NOT_OBJECT_OWNER); } + else { + ClearFactoryFlag(NOT_OBJECT_OWNER); } + } + + inline void SetRegenerateFlag(bool regenerate) { + if (regenerate) { + SetFactoryFlag(REGENERATE); } + else { + ClearFactoryFlag(REGENERATE); } + } + + inline void SetWriteToOutputFlag(bool write_to_output) { + if (write_to_output) { + SetFactoryFlag(WRITE_TO_OUTPUT); } + else { + ClearFactoryFlag(WRITE_TO_OUTPUT); } + } + + inline bool GetWriteToOutputFlag() { + return TestFactoryFlag(WRITE_TO_OUTPUT); + } + /// Get data source value depending on how objects came to be here. (Used mainly by JEvent::Get() ) inline JCallGraphRecorder::JDataSource GetDataSource() const { JCallGraphRecorder::JDataSource datasource = JCallGraphRecorder::DATA_FROM_FACTORY; @@ -158,7 +192,7 @@ class JFactory { std::string mObjectName; std::string mTag; - uint32_t mFlags = 0; + uint32_t mFlags = WRITE_TO_OUTPUT; int32_t mPreviousRunNumber = -1; JApplication* mApp = nullptr; std::unordered_map> mUpcastVTable; diff --git a/src/libraries/JANA/JFactoryT.h b/src/libraries/JANA/JFactoryT.h index 0b6be6d5a..c406620a7 100644 --- a/src/libraries/JANA/JFactoryT.h +++ b/src/libraries/JANA/JFactoryT.h @@ -79,12 +79,7 @@ class JFactoryT : public JFactory { /// exactly once, exceptions are tagged with the originating plugin and eventsource, ChangeRun() is /// called if and only if the run number changes, etc. PairType GetOrCreate(const std::shared_ptr& event) { - if (mStatus == Status::Uninitialized || mStatus == Status::Unprocessed) { - Create(event); - } - if (mStatus != Status::Processed && mStatus != Status::Inserted) { - throw JException("JFactoryT::Status is corrupted"); - } + Create(event); return std::make_pair(mData.cbegin(), mData.cend()); } diff --git a/src/programs/unit_tests/JFactoryTests.cc b/src/programs/unit_tests/JFactoryTests.cc index 49bee65d0..aaaaeff24 100644 --- a/src/programs/unit_tests/JFactoryTests.cc +++ b/src/programs/unit_tests/JFactoryTests.cc @@ -170,5 +170,32 @@ TEST_CASE("JFactoryTests") { data++; } } + + struct RegenerateFactory : public JFactoryT { + RegenerateFactory() { + SetRegenerateFlag(true); + } + void Process(const std::shared_ptr&) override { + mData.emplace_back(new JFactoryTestDummyObject(49)); + Set(mData); + } + }; + + SECTION("Factory regeneration") { + RegenerateFactory sut; + auto event = std::make_shared(); + + std::vector inserted_data; + inserted_data.push_back(new JFactoryTestDummyObject(22)); + inserted_data.push_back(new JFactoryTestDummyObject(618)); + sut.Set(inserted_data); + + REQUIRE(sut.GetStatus() == JFactory::Status::Inserted); + + auto results = sut.GetOrCreate(event); + auto it = results.first; + REQUIRE((*it)->data == 49); + REQUIRE(sut.GetNumObjects() == 1); + } }