| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | /* This file is a part of NA64SW software. | ||
| 2 | * Copyright (C) 2015-2022 NA64 Collaboration, CERN | ||
| 3 | * | ||
| 4 | * NA64SW is free software: you can redistribute it and/or modify | ||
| 5 | * it under the terms of the GNU General Public License as published by | ||
| 6 | * the Free Software Foundation, either version 3 of the License, or | ||
| 7 | * (at your option) any later version. | ||
| 8 | * | ||
| 9 | * This program is distributed in the hope that it will be useful, | ||
| 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | * GNU General Public License for more details. | ||
| 13 | * | ||
| 14 | * You should have received a copy of the GNU General Public License | ||
| 15 | * along with this program. If not, see <https://www.gnu.org/licenses/>. */ | ||
| 16 | |||
| 17 | #pragma once | ||
| 18 | |||
| 19 | #include "na64util/na64/event-id.hh" | ||
| 20 | #include "na64calib/dispatcher.hh" | ||
| 21 | |||
| 22 | #include <yaml-cpp/yaml.h> | ||
| 23 | |||
| 24 | namespace YAML { class Node; } // fwd | ||
| 25 | |||
| 26 | namespace na64dp { | ||
| 27 | namespace calib { | ||
| 28 | namespace aux { | ||
| 29 | /// Default is not implemented | ||
| 30 | template<typename T> void update_payload_to_yaml(const T & pl, YAML::Node & node) { | ||
| 31 | char bf[32]; | ||
| 32 | snprintf(bf, sizeof(bf), "%p", &pl); | ||
| 33 | node["_payloadPtr"] = bf; | ||
| 34 | } | ||
| 35 | /// YAML to YAML | ||
| 36 | template<> void update_payload_to_yaml(const YAML::Node & pl, YAML::Node & node); | ||
| 37 | } // namespace ::na64dp::calib::aux | ||
| 38 | |||
| 39 | struct iLoader; // fwd | ||
| 40 | |||
| 41 | ///\brief Single datum update recipe | ||
| 42 | /// | ||
| 43 | /// A piece of information used to describe which data shall be loaded by | ||
| 44 | /// loader. Issued by `iIndex` subclasses, sorted by manager class and then | ||
| 45 | /// consumed by loaders to actually load the data. | ||
| 46 | struct iUpdate { | ||
| 47 | virtual Dispatcher::CIDataID subject_data_type() const = 0; | ||
| 48 | virtual iLoader * recommended_loader() const = 0; | ||
| 49 | /// This is only for debug | ||
| 50 | ✗ | virtual void to_yaml(YAML::Node & node) const { | |
| 51 | char bf[32]; | ||
| 52 | ✗ | snprintf(bf, sizeof(bf), "%p", this); | |
| 53 | ✗ | node["_ptr"] = bf; | |
| 54 | } | ||
| 55 | ✗ | virtual ~iUpdate() {} | |
| 56 | }; | ||
| 57 | |||
| 58 | template<typename T> | ||
| 59 | struct iSpecificUpdate : public iUpdate { | ||
| 60 | T payload; | ||
| 61 | ✗ | iSpecificUpdate(const T & o) : payload(o) {} | |
| 62 | iSpecificUpdate(const T && o) : payload(o) {} | ||
| 63 | ✗ | virtual ~iSpecificUpdate() {} | |
| 64 | /// This is only for debug | ||
| 65 | ✗ | virtual void to_yaml(YAML::Node & node) const { | |
| 66 | ✗ | aux::update_payload_to_yaml(payload, node); | |
| 67 | } | ||
| 68 | }; | ||
| 69 | |||
| 70 | /// Container type for list of the enqueued updates | ||
| 71 | typedef std::vector<iUpdate*> Updates; | ||
| 72 | |||
| 73 | /**\brief Defines what calibration data have to be updated based on event ID | ||
| 74 | * | ||
| 75 | * Class implementing this interface has to decide which calibration data types | ||
| 76 | * has to be updated between runs. | ||
| 77 | * | ||
| 78 | * Typical subclassing example is, of course, a database querying object that | ||
| 79 | * maintains a connection, issues queries, etc. However the calibration data | ||
| 80 | * itself must not be fetched by index class (we need to follow | ||
| 81 | * application-driven logic of resolving dependencies and order of updates | ||
| 82 | * treatment). In simpler case it may be a config file or just a static, | ||
| 83 | * hard-coded class mapping range to certain update instructions. | ||
| 84 | * | ||
| 85 | * Indices are type-agnostic at the level of `iLoader` meaning that one index | ||
| 86 | * instance may update calibration data of various types. | ||
| 87 | * | ||
| 88 | * The typical user of this class is calibration manager instance that may | ||
| 89 | * maintain a collection of the indices. This way an extensible modular approach | ||
| 90 | * for maintaining calibration data is achieved: indices supersedes | ||
| 91 | * updates (last update shall override previous), dependency resolution, etc. | ||
| 92 | */ | ||
| 93 | struct iIndex { | ||
| 94 | /// Appends list of the run to be updated between events. Type collisions | ||
| 95 | /// (conflicting updates) shall be resolved by displacing the existing with | ||
| 96 | /// current. | ||
| 97 | virtual void append_updates( EventID oldEventID, EventID newEventID | ||
| 98 | , const std::pair<time_t, uint32_t> & oldKey | ||
| 99 | , const std::pair<time_t, uint32_t> & newKey | ||
| 100 | , Updates & ) = 0; | ||
| 101 | /// May be overriden to clean up temporary update objects | ||
| 102 | ✗ | virtual void clear_tmp_update_objects() {} | |
| 103 | ✗ | virtual ~iIndex(){} | |
| 104 | |||
| 105 | virtual void to_yaml( YAML::Node & ) const = 0; | ||
| 106 | }; | ||
| 107 | |||
| 108 | } // namespace ::na64dp::calib | ||
| 109 | } // namespace na64dp | ||
| 110 | |||
| 111 |