GCC Code Coverage Report


Directory: ./
File: include/na64app/extension.hh
Date: 2025-09-01 06:19:01
Exec Total Coverage
Lines: 0 6 0.0%
Functions: 0 2 0.0%
Branches: 0 0 -%

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/str-fmt.hh"
20
21 namespace na64dp {
22 namespace calib { class Manager; } // fwd
23 class iEvProcInfo; // fwd
24
25 /**\brief A base class for (loadable) extension instance
26 *
27 * User handlers may bring some additional dependencies of global/singleton
28 * objects that have to be initialized/bound to NA64SW infrastructure in other
29 * way as other handlers.
30 *
31 * Typical example is ROOT objects like geometry manager, event display window
32 * or other common singletons. This base class provides a way to register such
33 * objects, initialize and access them further with single entry point
34 * (`na64dp::Extensions`).
35 * */
36 struct iRuntimeExtension {
37 virtual ~iRuntimeExtension() {}
38 virtual void init(calib::Manager &, iEvProcInfo * epi) = 0;
39 //virtual std::unordered_map<std::string, std::string> parameters() const = 0;
40 virtual void finalize() {}
41 virtual void set_parameter(const std::string &, const std::string &) = 0;
42
43 /// Helper method, shortcut for `dynamic_cast<>()`
44 template<typename T> T & as() {
45 T * p = dynamic_cast<T*>(this);
46 if(!p) {
47 // TODO: details (demangled RTTI type, etc)
48 NA64DP_RUNTIME_ERROR("Bad cast for extension.");
49 }
50 return *p;
51 }
52 };
53
54 /**\brief An entry point for runtime extensions
55 *
56 * Manages instances of (loadable) extension classes (subclasses of
57 * `iRuntimeExtension`). Implied lifecycle:
58 * 1. Loadable modules adds their extension objects with `add()` method
59 * 2. After logging, monitor and calibration manager are instantiated, an
60 * `init()` method called forwarding calls to extension requested.
61 * 3. After app is done, it calls `shutdown()` method to clear resources used
62 * by extensions.
63 * Note, that some extensions may not create objects to be used during
64 * `init()`, depending on their configuration.
65 * */
66 class Extensions : private std::unordered_map<std::string, iRuntimeExtension *> {
67 private:
68 static Extensions * _self;
69 /// Private ctr invoked by `self()`
70 Extensions();
71 public:
72 /// Returns instance (singleton)
73 static Extensions & self();
74
75 ///\brief Adds runtime extension to be managed by this registry
76 ///
77 ///\throws `DuplicateExtensionName` if extension name is not unique
78 ///\note Delegates ownershit to `Extensions`; assumed to be allocated
79 /// with `new`.
80 bool add(const std::string &, iRuntimeExtension *);
81 /// Returns ref to named `iRuntimeExtension` subclass instance previously
82 /// added with `add()`
83 iRuntimeExtension & operator[](const std::string &);
84
85 /// Sets an extension's parameter
86 void set_parameter(const std::string &, const std::string &);
87 /// Forwars execution to `iExtension::init()`
88 void init( calib::Manager &
89 , iEvProcInfo * epi
90 );
91 /// Called after application done with data processing
92 void finalize();
93 /// Deletes all instantiated extensions
94 void shutdown();
95 }; // class Extensions
96
97 namespace errors {
98
99 class NoExtension : public GenericRuntimeError {
100 public:
101 const std::string extName;
102
103 NoExtension( const std::string & extName_ )
104 : GenericRuntimeError( util::format("Extension \"%s\" is not loaded."
105 , extName_.c_str() ).c_str() )
106 , extName(extName_) {}
107 };
108
109 class DuplicateExtensionName : public GenericRuntimeError {
110 public:
111 const std::string extName;
112
113 DuplicateExtensionName( const std::string & extName_ )
114 : GenericRuntimeError( util::format("Extension name \"%s\" is"
115 " already taken (repeated instantiation?)."
116 , extName_.c_str() ).c_str() )
117 , extName(extName_) {}
118 };
119
120 } // namespace ::na64dp::errors
121 } // namespace na64dp
122
123 /**\brief Registers new runtime extension
124 * \ingroup vctr-defs
125 *
126 * Registers subclasses of `iRuntimeExtension` managed with `Extensions`.
127 *
128 * \param clsName The name of the extension instance
129 */
130 # define REGISTER_EXTENSION( clsName ) \
131 static bool _regResult_ ## clsName = \
132 ::na64dp::Extensions::self().add( # clsName, new clsName );
133
134