ChimeraTK-ApplicationCore 04.08.00
Loading...
Searching...
No Matches
Application.h
Go to the documentation of this file.
1// SPDX-FileCopyrightText: Deutsches Elektronen-Synchrotron DESY, MSK, ChimeraTK Project <chimeratk-support@desy.de>
2// SPDX-License-Identifier: LGPL-3.0-or-later
3#pragma once
4
6#include "ConnectionMaker.h"
7#include "Flags.h"
8#include "InternalModule.h"
9#include "Logger.h"
10#include "Model.h"
11#include "ModuleGroup.h"
12#include "TestableMode.h"
13
14#ifdef CHIMERATK_APPLICATION_CORE_WITH_PYTHON
15# include "PythonModuleManager.h"
16#endif
17
18#include <ChimeraTK/ControlSystemAdapter/ApplicationBase.h>
19#include <ChimeraTK/DeviceBackend.h>
20
21#include <atomic>
22#include <mutex>
23
24namespace ChimeraTK {
25
26 /********************************************************************************************************************/
27
28 class Module;
29 class VariableNetwork;
30 class TestFacility;
31 class DeviceManager;
32 class ApplicationModule;
33
34 template<typename UserType>
35 class FanOut;
36 template<typename UserType>
37 class ConsumingFanOut;
38
39 namespace detail {
40 struct TestableMode;
41 } // namespace detail
42
43 /********************************************************************************************************************/
44
45 class Application : public ApplicationBase, public ModuleGroup {
46 public:
51 explicit Application(const std::string& name);
52
53 ~Application() override;
54
55 using ApplicationBase::getName;
56
64 void shutdown() override;
65
66 void initialise() override;
67
68 void optimiseUnmappedVariables(const std::set<std::string>& names) override;
69
70 void run() override;
71
76
80 void generateXML();
81
85 void generateDOT();
86
91 static Application& getInstance();
92
96 static bool hasInstance() { return instance != nullptr; }
97
109 void enableTestableMode();
110
115
120 static void registerThread(const std::string& name);
121
123
124 std::string getQualifiedName() const override { return "/" + _name; }
125
126 std::string getFullDescription() const override { return ""; }
127
136
141 static void incrementDataLossCounter(const std::string& name);
142
146 static size_t getAndResetDataLossCounter();
147
151 boost::shared_ptr<DeviceManager> getDeviceManager(const std::string& aliasOrCDD);
152
154 std::map<std::string, boost::shared_ptr<DeviceManager>> const& getDeviceManagerMap() { return _deviceManagerMap; }
155
160
165 VersionNumber getStartVersion() const { return _startVersion; }
168
169 size_t getCircularNetworkInvalidityCounter(size_t circularNetworkHash) const {
170 return _circularNetworkInvalidityCounters.at(circularNetworkHash);
171 }
172
173#ifdef CHIMERATK_APPLICATION_CORE_WITH_PYTHON
174 PythonModuleManager& getPythonModuleManager() { return _pythonModuleManager; }
175#endif
176
178
179 protected:
180 friend class Module;
181 friend class VariableNetwork;
186 friend struct StatusAggregator;
187 friend struct detail::TestableMode;
188 friend class NetworkVisitor;
189 friend class ConnectionMaker;
190
191 template<typename UserType>
193
196
199
201 std::list<boost::shared_ptr<InternalModule>> _internalModuleList;
202
204 std::map<std::string, boost::shared_ptr<DeviceManager>> _deviceManagerMap;
205
209
211 bool _initialiseCalled{false};
212
214 bool _runCalled{false};
215
218 std::map<size_t, size_t> _pvIdMap;
219
222
226 std::unordered_set<const void*> _debugMode_variableList;
227
229 std::atomic<size_t> _dataLossCounter{0};
230
233
235 VersionNumber _startVersion;
236
238
243 std::map<size_t, std::atomic<uint64_t>> _circularNetworkInvalidityCounters;
244
247 std::map<size_t, std::list<EntityOwner*>> _circularDependencyNetworks;
248
253 std::shared_ptr<Logger> _logger{Logger::getSharedPtr()};
254
258#ifdef CHIMERATK_APPLICATION_CORE_WITH_PYTHON
259 PythonModuleManager _pythonModuleManager;
260#endif
261
263 std::shared_ptr<ConfigReader> _configReader;
265
266 friend class TestFacility; // needs access to testableMode variables
267
268 template<typename UserType>
269 friend class DebugPrintAccessorDecorator; // needs access to the idMap
270 template<typename UserType>
271 friend class MetaDataPropagatingRegisterDecorator; // needs to access circularNetworkInvalidityCounters
272 friend class ApplicationModule; // needs to access circularNetworkInvalidityCounters
274 friend class ConfigReader; // needs access to _configReader to replace it eventually
275
276 VersionNumber getCurrentVersionNumber() const override {
277 throw ChimeraTK::logic_error("getCurrentVersionNumber() called on the application. This is probably "
278 "caused by incorrect ownership of variables/accessors or VariableGroups.");
279 }
280 void setCurrentVersionNumber(VersionNumber) override {
281 throw ChimeraTK::logic_error("setCurrentVersionNumber() called on the application. This is probably "
282 "caused by incorrect ownership of variables/accessors or VariableGroups.");
283 }
284 DataValidity getDataValidity() const override {
285 throw ChimeraTK::logic_error("getDataValidity() called on the application. This is probably "
286 "caused by incorrect ownership of variables/accessors or VariableGroups.");
287 }
289 throw ChimeraTK::logic_error("incrementDataFaultCounter() called on the application. This is probably "
290 "caused by incorrect ownership of variables/accessors or VariableGroups.");
291 }
293 throw ChimeraTK::logic_error("decrementDataFaultCounter() called on the application. This is probably "
294 "caused by incorrect ownership of variables/accessors or VariableGroups.");
295 }
296 std::list<EntityOwner*> getInputModulesRecursively([[maybe_unused]] std::list<EntityOwner*> startList) override {
297 throw ChimeraTK::logic_error("getInputModulesRecursively() called on the application. This is probably "
298 "caused by incorrect ownership of variables/accessors or VariableGroups.");
299 }
300 size_t getCircularNetworkHash() const override {
301 throw ChimeraTK::logic_error("getCircularNetworkHash() called on the application. This is probably "
302 "caused by incorrect ownership of variables/accessors or VariableGroups.");
303 }
304 };
305
306} /* namespace ChimeraTK */
void incrementDataFaultCounter() override
Set the data validity flag to fault and increment the fault counter.
friend class VariableNetworkModuleGraphDumpingVisitor
std::list< EntityOwner * > getInputModulesRecursively(std::list< EntityOwner * > startList) override
Use pointer to the module as unique identifier.
size_t getCircularNetworkHash() const override
Get the ID of the circular dependency network (0 if none).
size_t getCircularNetworkInvalidityCounter(size_t circularNetworkHash) const
ConfigReader & getConfigReader()
void generateXML()
Instead of running the application, just initialise it and output the published variables to an XML f...
Model::RootProxy getModel()
Return the root of the application model.
Definition Application.h:75
std::list< boost::shared_ptr< InternalModule > > _internalModuleList
List of InternalModules.
bool _initialiseCalled
Flag whether initialise() has been called already, to make sure it doesn't get called twice.
void enableTestableMode()
Enable the testable mode.
std::atomic< LifeCycleState > _lifeCycleState
Life-cycle state of the application.
ApplicationModule * getVersionInfoProvider()
LifeCycleState getLifeCycleState() const
Get the current LifeCycleState of the application.
friend struct detail::TestableMode
bool _testFacilityRunApplicationCalled
Flag which is set by the TestFacility in runApplication() at the beginning.
ConfigReader * _defaultConfigReader
std::string getQualifiedName() const override
Get the fully qualified name of the module instance, i.e.
std::map< size_t, std::list< EntityOwner * > > _circularDependencyNetworks
The networks of circular dependencies, reachable by their hash, which serves as unique ID.
void run() override
Execute the module.
void initialise() override
std::shared_ptr< Logger > _logger
Shared Pointer to central logger instance.
detail::TestableMode & getTestableMode()
Get the TestableMode control object of this application.
std::map< size_t, size_t > _pvIdMap
Map from ProcessArray uniqueId to the variable ID for control system variables.
VersionNumber _startVersion
Version number used at application start, e.g.
static void registerThread(const std::string &name)
Register the thread in the application system and give it a name.
bool _runCalled
Flag whether run() has been called already, to make sure it doesn't get called twice.
VersionNumber getCurrentVersionNumber() const override
Return the current version number which has been received with the last push-type read operation.
void enableVariableDebugging(const VariableNetworkNode &node)
Enable debug output for a given variable.
std::map< std::string, boost::shared_ptr< DeviceManager > > _deviceManagerMap
Map of DeviceManagers.
boost::shared_ptr< DeviceManager > getDeviceManager(const std::string &aliasOrCDD)
Return the DeviceManager for the given alias name or CDD.
std::map< std::string, boost::shared_ptr< DeviceManager > > const & getDeviceManagerMap()
Access the device manager map.
std::shared_ptr< ConfigReader > _configReader
Manager for Python-based ApplicationModules.
void optimiseUnmappedVariables(const std::set< std::string > &names) override
detail::TestableMode _testableMode
static Application & getInstance()
Obtain instance of the application.
friend class VariableNetworkGraphDumpingVisitor
void generateDOT()
Instead of running the application, just initialise it and output the published variables to a DOT fi...
ApplicationModule * _versionInfoProvider
VersionNumber getStartVersion() const
Return the start version.
friend class XMLGeneratorVisitor
std::map< size_t, std::atomic< uint64_t > > _circularNetworkInvalidityCounters
Map of atomic invalidity counters for each circular dependency network.
friend class VariableNetwork
ConnectionMaker _cm
Helper class to create connections.
void shutdown() override
This will remove the global pointer to the instance and allows creating another instance afterwards.
std::unordered_set< const void * > _debugMode_variableList
List of variables for which debug output was requested via enableVariableDebugging().
detail::CircularDependencyDetector _circularDependencyDetector
void setCurrentVersionNumber(VersionNumber) override
Set the current version number.
ModuleType getModuleType() const override
Return the module type of this module, or in case of a VirtualModule the module type this VirtualModu...
static size_t getAndResetDataLossCounter()
Return the current value of the data loss counter and (atomically) reset it to 0.
std::atomic< size_t > _dataLossCounter
Counter for how many write() operations have overwritten unread data.
void setVersionInfoProvider(ApplicationModule *provider)
static void incrementDataLossCounter(const std::string &name)
Increment counter for how many write() operations have overwritten unread data.
void decrementDataFaultCounter() override
Decrement the fault counter and set the data validity flag to ok if the counter has reached 0.
friend struct detail::CircularDependencyDetector
static bool hasInstance()
Check whether an instance of Application currently exists.
Definition Application.h:96
Model::RootProxy _model
The model of the application.
DataValidity getDataValidity() const override
Return the data validity flag.
std::string getFullDescription() const override
Obtain the full description including the full description of the owner.
Generic module to read an XML config file and provide the defined values as constant variables.
Decorator of the NDRegisterAccessor which facilitates tests of the application.
std::string _name
The name of this instance.
Decorator of the NDRegisterAccessor which facilitates tests of the application.
NDRegisterAccessorDecorator which propagates meta data attached to input process variables through th...
Proxy representing the root of the application model.
Definition Model.h:210
friend class Application
Definition ModuleGroup.h:47
Base class for ApplicationModule and DeviceModule, to have a common interface for these module types.
Definition Module.h:21
This class loads and unloads the Python modules as specified in the ConfigReader XML file,...
Helper class to facilitate tests of applications based on ApplicationCore.
Class describing a node of a variable network.
const void * getUniqueId() const
Return the unique ID of this node (will change every time the application is started).
InvalidityTracer application module.
LifeCycleState
Enum to define the life-cycle states of an Application.
Definition Flags.h:41
@ initialisation
Initialisation phase including ApplicationModule::prepare().
The StatusAggregator collects results of multiple StatusMonitor instances and aggregates them into a ...