ChimeraTK-ApplicationCore 04.06.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
128
130
131 std::string getQualifiedName() const override { return "/" + _name; }
132
133 std::string getFullDescription() const override { return ""; }
134
143
150
155 static void incrementDataLossCounter(const std::string& name);
156
160 static size_t getAndResetDataLossCounter();
161
165 boost::shared_ptr<DeviceManager> getDeviceManager(const std::string& aliasOrCDD);
166
168 std::map<std::string, boost::shared_ptr<DeviceManager>> const& getDeviceManagerMap() { return _deviceManagerMap; }
169
174
179 VersionNumber getStartVersion() const { return _startVersion; }
182
183 size_t getCircularNetworkInvalidityCounter(size_t circularNetworkHash) const {
184 return _circularNetworkInvalidityCounters.at(circularNetworkHash);
185 }
186
187#ifdef CHIMERATK_APPLICATION_CORE_WITH_PYTHON
188 PythonModuleManager& getPythonModuleManager() { return _pythonModuleManager; }
189#endif
190
192
193 protected:
194 friend class Module;
195 friend class VariableNetwork;
200 friend struct StatusAggregator;
201 friend struct detail::TestableMode;
202 friend class NetworkVisitor;
203 friend class ConnectionMaker;
204
205 template<typename UserType>
207
210
213
215 std::list<boost::shared_ptr<InternalModule>> _internalModuleList;
216
218 std::map<std::string, boost::shared_ptr<DeviceManager>> _deviceManagerMap;
219
223
225 bool _initialiseCalled{false};
226
228 bool _runCalled{false};
229
232
235 std::map<size_t, size_t> _pvIdMap;
236
239
243 std::unordered_set<const void*> _debugMode_variableList;
244
246 std::atomic<size_t> _dataLossCounter{0};
247
249 bool _debugDataLoss{false};
250
253
255 VersionNumber _startVersion;
256
258
263 std::map<size_t, std::atomic<uint64_t>> _circularNetworkInvalidityCounters;
264
267 std::map<size_t, std::list<EntityOwner*>> _circularDependencyNetworks;
268
273 std::shared_ptr<Logger> _logger{Logger::getSharedPtr()};
274
278#ifdef CHIMERATK_APPLICATION_CORE_WITH_PYTHON
279 PythonModuleManager _pythonModuleManager;
280#endif
281
283 std::shared_ptr<ConfigReader> _configReader;
285
286 friend class TestFacility; // needs access to testableMode variables
287
288 template<typename UserType>
289 friend class DebugPrintAccessorDecorator; // needs access to the idMap
290 template<typename UserType>
291 friend class MetaDataPropagatingRegisterDecorator; // needs to access circularNetworkInvalidityCounters
292 friend class ApplicationModule; // needs to access circularNetworkInvalidityCounters
294 friend class ConfigReader; // needs access to _configReader to replace it eventually
295
296 VersionNumber getCurrentVersionNumber() const override {
297 throw ChimeraTK::logic_error("getCurrentVersionNumber() called on the application. This is probably "
298 "caused by incorrect ownership of variables/accessors or VariableGroups.");
299 }
300 void setCurrentVersionNumber(VersionNumber) override {
301 throw ChimeraTK::logic_error("setCurrentVersionNumber() called on the application. This is probably "
302 "caused by incorrect ownership of variables/accessors or VariableGroups.");
303 }
304 DataValidity getDataValidity() const override {
305 throw ChimeraTK::logic_error("getDataValidity() called on the application. This is probably "
306 "caused by incorrect ownership of variables/accessors or VariableGroups.");
307 }
309 throw ChimeraTK::logic_error("incrementDataFaultCounter() called on the application. This is probably "
310 "caused by incorrect ownership of variables/accessors or VariableGroups.");
311 }
313 throw ChimeraTK::logic_error("decrementDataFaultCounter() called on the application. This is probably "
314 "caused by incorrect ownership of variables/accessors or VariableGroups.");
315 }
316 std::list<EntityOwner*> getInputModulesRecursively([[maybe_unused]] std::list<EntityOwner*> startList) override {
317 throw ChimeraTK::logic_error("getInputModulesRecursively() called on the application. This is probably "
318 "caused by incorrect ownership of variables/accessors or VariableGroups.");
319 }
320 size_t getCircularNetworkHash() const override {
321 throw ChimeraTK::logic_error("getCircularNetworkHash() called on the application. This is probably "
322 "caused by incorrect ownership of variables/accessors or VariableGroups.");
323 }
324 };
325
326} /* 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.
void debugMakeConnections()
Enable debug output for the ConnectionMaker.
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.
void enableDebugDataLoss()
Enable debug output for lost data.
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.
bool _enableDebugMakeConnections
Flag if debug output is enabled for creation of the variable connections.
std::unordered_set< const void * > _debugMode_variableList
List of variables for which debug output was requested via enableVariableDebugging().
bool _debugDataLoss
Flag whether to debug data loss (as counted with the data loss counter).
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 ...