12#include <ChimeraTK/BackendFactory.h>
14#include <boost/fusion/container/map.hpp>
33 if(_applicationName.empty()) {
35 throw ChimeraTK::logic_error(
"Error: An instance of Application must have its applicationName set.");
40 throw ChimeraTK::logic_error(
41 "Error: The application name may only contain alphanumeric characters and underscores.");
44#pragma GCC diagnostic push
45#pragma GCC diagnostic ignored "-Wdeprecated"
46 _configReader = std::make_shared<ConfigReader>(
this,
"/", name +
"-config.xml");
47#pragma GCC diagnostic pop
51#ifdef CHIMERATK_APPLICATION_CORE_WITH_PYTHON
53 _pythonModuleManager.createModules(*
this);
55 catch(ChimeraTK::logic_error&) {
57 std::rethrow_exception(std::current_exception());
68 ApplicationBase::shutdown();
99 counter, 0, std::memory_order_release, std::memory_order_relaxed)) {
108 throw ChimeraTK::logic_error(
"Application::initialise() was already called before.");
113 module->postConstruct();
126 throw ChimeraTK::logic_error(
127 "Application::initialise() must be called before Application::optimiseUnmappedVariables().");
136 assert(!_applicationName.empty());
138 if(!getPVManager()) {
139 throw ChimeraTK::logic_error(
"Application::run() was called without an instance of ChimeraTK::PVManager.");
144 throw ChimeraTK::logic_error(
145 "Testable mode enabled but Application::run() called directly. Call TestFacility::runApplication() instead.");
150 throw ChimeraTK::logic_error(
"Application::run() has already been called before.");
162 module->setCurrentVersionNumber(getStartVersion());
175 internalModule->activate();
188 auto waitForTestableMode = [](
EntityOwner* module) {
189 while(!module->hasReachedTestableMode()) {
200 waitForTestableMode(internalModule.get());
204 waitForTestableMode(module);
228 internalModule->deactivate();
234 pair.second->terminate();
245 getPythonModuleManager().deinit();
247 ApplicationBase::shutdown();
255 assert(!_applicationName.empty());
259 generator.save(_applicationName +
".xml");
265 assert(!_applicationName.empty());
272 return dynamic_cast<Application&
>(ApplicationBase::getInstance());
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.
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.
bool _testFacilityRunApplicationCalled
Flag which is set by the TestFacility in runApplication() at the beginning.
ConfigReader * _defaultConfigReader
Application(const std::string &name)
The constructor takes the application name as an argument.
void run() override
Execute the module.
void initialise() override
detail::TestableMode & getTestableMode()
Get the TestableMode control object of this application.
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.
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::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.
void generateDOT()
Instead of running the application, just initialise it and output the published variables to a DOT fi...
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.
bool _debugDataLoss
Flag whether to debug data loss (as counted with the data loss counter).
detail::CircularDependencyDetector _circularDependencyDetector
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.
static void incrementDataLossCounter(const std::string &name)
Increment counter for how many write() operations have overwritten unread data.
Model::RootProxy _model
The model of the application.
const T & get(std::string variableName) const
Get value for given configuration variable.
void finalise()
Finalise the model and register all PVs with the control system adapter.
void connect()
Realise connections.
void optimiseUnmappedVariables(const std::set< std::string > &names)
Execute the optimisation request from the control system adapter (remove unused variables)
Base class for owners of other EntityOwners (e.g.
std::list< Module * > getSubmoduleListRecursive() const
Obtain the list of submodules associated with this instance and any submodules.
Proxy representing the root of the application model.
void writeGraphViz(const std::string &filename, Args... args) const
Implementations of RootProxy.
void setDebugConnections(bool enable)
Generate XML representation of variables.
bool checkName(const std::string &name, bool allowDotsAndSlashes)
Check given name for characters which are not allowed in variable or module names.
InvalidityTracer application module.
@ initialisation
Initialisation phase including ApplicationModule::prepare().
@ shutdown
The application is in the process of shutting down.
@ run
Actual run phase with full multi threading.
Logger::StreamProxy logger(Logger::Severity severity, std::string context)
Convenience function to obtain the logger stream.