File indexing completed on 2025-12-16 10:36:43
0001 #pragma once
0002 #include "JANA/Components/JDatabundle.h"
0003 #include "JANA/JFactorySet.h"
0004 #include <JANA/Components/JHasOutputs.h>
0005 #include <JANA/Components/JLightweightDatabundle.h>
0006 #include <JANA/Utils/JTypeInfo.h>
0007 #include <typeindex>
0008
0009 namespace jana::components {
0010
0011 template <typename T>
0012 class Output : public JHasOutputs::OutputBase {
0013 std::vector<T*> m_transient_data;
0014 std::vector<T*>* m_external_data = nullptr;
0015 JLightweightDatabundleT<T>* m_databundle;
0016
0017 public:
0018 Output(JHasOutputs* owner, std::string short_name="") {
0019 owner->RegisterOutput(this);
0020 m_databundle = new JLightweightDatabundleT<T>();
0021 m_databundle->SetTypeName(JTypeInfo::demangle<T>());
0022 m_databundle->SetTypeIndex(std::type_index(typeid(T)));
0023 m_databundle->SetShortName(short_name);
0024 SetDatabundle(m_databundle);
0025
0026 }
0027
0028 Output(JHasOutputs* owner, std::vector<T*>* external_data, std::string short_name="") {
0029 owner->RegisterOutput(this);
0030 m_databundle = new JLightweightDatabundleT<T>(external_data);
0031 m_databundle->SetTypeName(JTypeInfo::demangle<T>());
0032 m_databundle->SetTypeIndex(std::type_index(typeid(T)));
0033 m_databundle->SetShortName(short_name);
0034 m_external_data = external_data;
0035 SetDatabundle(m_databundle);
0036
0037 }
0038
0039 void SetNotOwnerFlag(bool not_owner) {
0040 m_databundle->SetNotOwnerFlag(not_owner);
0041 }
0042
0043 std::vector<T*>& operator()() { return (m_external_data == nullptr) ? m_transient_data : *m_external_data; }
0044
0045 JLightweightDatabundleT<T>& GetDatabundle() { return *m_databundle; }
0046
0047 void LagrangianStore(JFactorySet&, JDatabundle::Status status) override {
0048 if (m_external_data == nullptr) {
0049 m_databundle->GetData() = std::move(m_transient_data);
0050 }
0051 m_databundle->SetStatus(status);
0052 }
0053
0054 void EulerianStore(JFactorySet& facset) override {
0055 JLightweightDatabundleT<T>* typed_bundle = nullptr;
0056 auto bundle = facset.GetDatabundle(m_databundle->GetTypeIndex(), m_databundle->GetUniqueName());
0057
0058 if (bundle == nullptr) {
0059
0060 typed_bundle = new JLightweightDatabundleT<T>(*m_databundle);
0061 facset.Add(typed_bundle);
0062 }
0063 else {
0064 typed_bundle = dynamic_cast<JLightweightDatabundleT<T>*>(bundle);
0065 if (typed_bundle == nullptr) {
0066
0067 throw JException("Databundle with unique_name '%s' is not a JLightweightDatabundleT<%s>", m_databundle->GetUniqueName().c_str(), m_databundle->GetTypeName().c_str());
0068 }
0069 }
0070 if (m_external_data == nullptr) {
0071 typed_bundle->GetData() = std::move(m_transient_data);
0072 }
0073 else {
0074 typed_bundle->GetData() = std::move(*m_external_data);
0075 }
0076 typed_bundle->SetStatus(JDatabundle::Status::Inserted);
0077 auto fac = typed_bundle->GetFactory();
0078 if (fac != nullptr) {
0079 UpdateFactoryStatusOnEulerianStore(fac);
0080 }
0081 }
0082 };
0083
0084
0085 template <typename T>
0086 class VariadicOutput : public JHasOutputs::VariadicOutputBase {
0087 std::vector<std::vector<T*>> m_transient_datas;
0088 bool m_not_owner_flag = false;
0089
0090 public:
0091 VariadicOutput(JHasOutputs* owner, std::string short_name="") {
0092 owner->RegisterOutput(this);
0093 auto* databundle = new JLightweightDatabundleT<T>();
0094 databundle->SetTypeName(JTypeInfo::demangle<T>());
0095 databundle->SetTypeIndex(std::type_index(typeid(T)));
0096 databundle->SetShortName(short_name);
0097 GetDatabundles().push_back(databundle);
0098
0099 }
0100
0101 void SetNotOwnerFlag(bool not_owner) {
0102 m_not_owner_flag = not_owner;
0103
0104
0105 for (auto* db : GetDatabundles()) {
0106 auto typed_db = static_cast<JLightweightDatabundleT<T>*>(db);
0107 typed_db->SetNotOwnerFlag(not_owner);
0108 }
0109 }
0110
0111 std::vector<std::vector<T*>>& operator()() { return m_transient_datas; }
0112 std::vector<std::vector<T*>>* operator->() { return &m_transient_datas; }
0113
0114 void SetShortNames(std::vector<std::string> short_names) override {
0115 for (auto& db : GetDatabundles()) {
0116 delete db;
0117 }
0118 GetDatabundles().clear();
0119 m_transient_datas.clear();
0120 for (const std::string& name : short_names) {
0121 auto databundle = new JLightweightDatabundleT<T>;
0122 databundle->SetShortName(name);
0123 databundle->SetTypeName(JTypeInfo::demangle<T>());
0124 databundle->SetTypeIndex(std::type_index(typeid(T)));
0125 databundle->SetNotOwnerFlag(m_not_owner_flag);
0126 GetDatabundles().push_back(databundle);
0127 m_transient_datas.push_back({});
0128 }
0129 }
0130 void SetUniqueNames(std::vector<std::string> unique_names) override {
0131 for (auto& db : GetDatabundles()) {
0132 delete db;
0133 }
0134 GetDatabundles().clear();
0135 m_transient_datas.clear();
0136 for (const std::string& name : unique_names) {
0137 auto databundle = new JLightweightDatabundleT<T>;
0138 databundle->SetUniqueName(name);
0139 databundle->SetTypeName(JTypeInfo::demangle<T>());
0140 databundle->SetTypeIndex(std::type_index(typeid(T)));
0141 databundle->SetNotOwnerFlag(m_not_owner_flag);
0142 GetDatabundles().push_back(databundle);
0143 m_transient_datas.push_back({});
0144 }
0145
0146 }
0147
0148 void LagrangianStore(JFactorySet&, JDatabundle::Status status) override {
0149 if (m_transient_datas.size() != GetDatabundles().size()) {
0150 throw JException("Wrong number of output vectors in variadic output: Expected %d, found %d", GetDatabundles().size(), m_transient_datas.size());
0151 }
0152 size_t i=0;
0153 for (auto* databundle : GetDatabundles()) {
0154 JLightweightDatabundleT<T>* typed_bundle = dynamic_cast<JLightweightDatabundleT<T>*>(databundle);
0155 if (typed_bundle == nullptr) {
0156 throw JException("Databundle is not a JLightweightDatabundleT (Hint: This is an internal error)");
0157 }
0158 typed_bundle->GetData() = std::move(m_transient_datas.at(i));
0159 typed_bundle->SetStatus(status);
0160 i += 1;
0161 }
0162 }
0163
0164 void EulerianStore(JFactorySet& facset) override {
0165
0166 if (m_transient_datas.size() != GetDatabundles().size()) {
0167 throw JException("Wrong number of output vectors in variadic output: Expected %d, found %d", GetDatabundles().size(), m_transient_datas.size());
0168 }
0169 size_t i=0;
0170 for (auto* databundle_prototype : GetDatabundles()) {
0171 JLightweightDatabundleT<T>* typed_databundle = nullptr;
0172 auto* databundle = facset.GetDatabundle(databundle_prototype->GetUniqueName());
0173 if (databundle == nullptr) {
0174 auto* typed_databundle_prototype = dynamic_cast<JLightweightDatabundleT<T>*>(databundle_prototype);
0175 typed_databundle = new JLightweightDatabundleT<T>(*typed_databundle_prototype);
0176 facset.Add(typed_databundle);
0177 }
0178 else {
0179 typed_databundle = dynamic_cast<JLightweightDatabundleT<T>*>(databundle);
0180 if (typed_databundle == nullptr) {
0181 throw JException("Databundle with unique_name '%s' is not a JLightweightDatabundle<%s>", databundle_prototype->GetUniqueName().c_str(), JTypeInfo::demangle<T>().c_str());
0182 }
0183 }
0184 typed_databundle->GetData() = std::move(m_transient_datas.at(i));
0185 typed_databundle->SetStatus(JDatabundle::Status::Inserted);
0186
0187 auto fac = typed_databundle->GetFactory();
0188 if (fac != nullptr) {
0189 UpdateFactoryStatusOnEulerianStore(fac);
0190 }
0191 i += 1;
0192 }
0193 }
0194 };
0195
0196 }
0197
0198 template <typename T> using Output = jana::components::Output<T>;
0199 template <typename T> using VariadicOutput = jana::components::VariadicOutput<T>;