7#include <ChimeraTK/ControlSystemAdapter/ControlSystemPVManager.h>
8#include <ChimeraTK/OneDRegisterAccessor.h>
9#include <ChimeraTK/ScalarRegisterAccessor.h>
10#include <ChimeraTK/VariantUserTypes.h>
11#include <ChimeraTK/VoidRegisterAccessor.h>
13#include <boost/fusion/include/at_key.hpp>
22 struct BoolTypeHelper {
27 struct BoolTypeHelper<bool> {
28 using type = ChimeraTK::Boolean;
61 ChimeraTK::VoidRegisterAccessor
getVoid(
const ChimeraTK::RegisterPath& name)
const;
66 ChimeraTK::ScalarRegisterAccessor<T>
getScalar(
const ChimeraTK::RegisterPath& name)
const;
71 ChimeraTK::OneDRegisterAccessor<T>
getArray(
const ChimeraTK::RegisterPath& name)
const;
75 template<
typename TYPE>
76 void writeScalar(
const std::string& name, TYPE value);
80 template<
typename TYPE>
81 void writeArray(
const std::string& name,
const std::vector<TYPE>& value);
85 template<
typename TYPE>
90 template<
typename TYPE>
91 std::vector<TYPE>
readArray(
const std::string& name);
99 void setArrayDefault(
const ChimeraTK::RegisterPath& name,
const std::vector<T>& value);
104 boost::shared_ptr<ChimeraTK::NDRegisterAccessor<T>>
getAccessor(
const ChimeraTK::RegisterPath& name)
const;
113 static void setConfigScalar(
const ChimeraTK::RegisterPath& name,
const T& value);
119 static void setConfigArray(
const ChimeraTK::RegisterPath& name,
const std::vector<T>& value);
128 template<
typename UserType>
129 using AccessorMap = std::map<std::string, boost::shared_ptr<ChimeraTK::NDRegisterAccessor<UserType>>>;
133 template<
typename UserType>
134 using Defaults = std::map<std::string, std::vector<UserType>>;
140 static std::map<ChimeraTK::RegisterPath, ChimeraTK::UserTypeVariantNoVoid>
_configScalars;
142 template<
typename UserType>
146 static std::map<ChimeraTK::RegisterPath, ChimeraTK::UserTypeTemplateVariantNoVoid<Vector>>
_configArrays;
156 return getAccessor<T>(name);
163 return getAccessor<T>(name);
168 template<
typename TYPE>
170 auto acc = getScalar<typename detail::BoolTypeHelper<TYPE>::type>(name);
177 template<
typename TYPE>
179 auto acc = getArray<typename detail::BoolTypeHelper<TYPE>::type>(name);
180 if constexpr(!std::is_same<TYPE, bool>::value) {
184 assert(value.size() == acc.getNElements());
185 std::transform(value.begin(), value.end(), acc.begin(), [](
const bool& v) -> ChimeraTK::Boolean { return v; });
192 template<
typename TYPE>
194 auto acc = getScalar<typename detail::BoolTypeHelper<TYPE>::type>(name);
201 template<
typename TYPE>
203 auto acc = getArray<typename detail::BoolTypeHelper<TYPE>::type>(name);
213 throw ChimeraTK::logic_error(
"TestFacility::setScalarDefault() called after runApplication().");
225 throw ChimeraTK::logic_error(
"TestFacility::setArrayDefault() called after runApplication().");
229 throw ChimeraTK::logic_error(
"Process variable '" + name +
"' does not exist.");
233 auto pv =
_pvManager->getProcessArray<
typename detail::BoolTypeHelper<T>::type>(name);
235 auto pvUntyped =
_pvManager->getProcessVariable(name);
236 throw ChimeraTK::logic_error(
"Process variable '" + name +
"' requested by the wrong type: " +
typeid(T).name() +
237 " != " + pvUntyped->getValueType().name());
241 auto& tv = boost::fusion::at_key<typename detail::BoolTypeHelper<T>::type>(
_defaults.table)[name];
242 if constexpr(!std::is_same<T, bool>::value) {
246 tv.resize(value.size());
247 std::transform(value.begin(), value.end(), tv.begin(), [](
const bool& v) -> ChimeraTK::Boolean { return v; });
255 const ChimeraTK::RegisterPath& name)
const {
257 if(boost::fusion::at_key<T>(
_accessorMap.table).count(name) > 0) {
258 return boost::fusion::at_key<T>(
_accessorMap.table)[name];
262 auto pv =
_pvManager->getProcessArray<T>(name);
264 throw ChimeraTK::logic_error(
"Process variable '" + name +
"' does not exist.");
271 pv, detail::TestableMode::DecoratorType::WRITE,
"ControlSystem:" + name, it->second);
274 boost::fusion::at_key<T>(
_accessorMap.table)[name] = pv;
278 return boost::fusion::at_key<T>(
_accessorMap.table)[name];
bool _testFacilityRunApplicationCalled
Flag which is set by the TestFacility in runApplication() at the beginning.
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.
Generic module to read an XML config file and provide the defined values as constant variables.
Helper class to facilitate tests of applications based on ApplicationCore.
ChimeraTK::OneDRegisterAccessor< T > getArray(const ChimeraTK::RegisterPath &name) const
Obtain an array-type process variable from the application, which is published to the control system.
static void setConfigScalar(const ChimeraTK::RegisterPath &name, const T &value)
Set ConfigReader scalar variable for the next instantiated Applicaton.
boost::shared_ptr< ChimeraTK::NDRegisterAccessor< T > > getAccessor(const ChimeraTK::RegisterPath &name) const
Function to obtain a process variable from the control system.
ChimeraTK::TemplateUserTypeMap< AccessorMap > _accessorMap
ChimeraTK::TemplateUserTypeMap< Defaults > _defaults
std::map< std::string, std::vector< UserType > > Defaults
TYPE readScalar(const std::string &name)
Convenience function to read the latest value of a scalar process variable in a single call.
bool canStepApplication() const
Check whether data has been sent to the application so stepApplication() can be called.
void writeArray(const std::string &name, const std::vector< TYPE > &value)
Convenience function to write an array process variable in a single call.
static std::map< ChimeraTK::RegisterPath, ChimeraTK::UserTypeTemplateVariantNoVoid< Vector > > _configArrays
boost::shared_ptr< ControlSystemPVManager > getPvManager() const
void writeScalar(const std::string &name, TYPE value)
Convenience function to write a scalar process variable in a single call.
void stepApplication(bool waitForDeviceInitialisation=true) const
Perform a "step" of the application.
ChimeraTK::VoidRegisterAccessor getVoid(const ChimeraTK::RegisterPath &name) const
Obtain a void process variable from the application, which is published to the control system.
static std::map< ChimeraTK::RegisterPath, ChimeraTK::UserTypeVariantNoVoid > _configScalars
boost::shared_ptr< ControlSystemPVManager > _pvManager
ChimeraTK::ScalarRegisterAccessor< T > getScalar(const ChimeraTK::RegisterPath &name) const
Obtain a scalar process variable from the application, which is published to the control system.
std::vector< TYPE > readArray(const std::string &name)
Convenience function to read the latest value of an array process variable in a single call.
void runApplication() const
Start the application in testable mode.
void setArrayDefault(const ChimeraTK::RegisterPath &name, const std::vector< T > &value)
Set default value for array process variable.
static void setConfigArray(const ChimeraTK::RegisterPath &name, const std::vector< T > &value)
Set ConfigReader array variable for the next instantiated Applicaton.
void setScalarDefault(const ChimeraTK::RegisterPath &name, const T &value)
Set default value for scalar process variable.
std::map< std::string, boost::shared_ptr< ChimeraTK::NDRegisterAccessor< UserType > > > AccessorMap
std::vector< UserType > Vector
InvalidityTracer application module.