18 const std::exception_ptr& firstDetectedRuntimeError) {
19 for(
const auto& elem : elements) {
21 for(
const auto& lowLevelElem : elem->getHardwareAccessingElements()) {
25 if(lowLevelElem->_activeException) {
27 elem->_activeException = lowLevelElem->_activeException;
34 elem->postReadAndHandleExceptions(
TransferType::read, firstDetectedRuntimeError ==
nullptr);
50 std::exception_ptr firstDetectedRuntimeError{
nullptr};
54 if((elem->_activeException !=
nullptr) && (firstDetectedRuntimeError ==
nullptr)) {
55 firstDetectedRuntimeError = elem->_activeException;
64 if((elem->_activeException !=
nullptr) && (firstDetectedRuntimeError ==
nullptr)) {
65 firstDetectedRuntimeError = elem->_activeException;
69 if(firstDetectedRuntimeError ==
nullptr) {
72 const auto& elem = it.first;
73 elem->handleTransferException([&] { elem->readTransfer(); });
74 if((elem->_activeException !=
nullptr) && (firstDetectedRuntimeError ==
nullptr)) {
75 firstDetectedRuntimeError = elem->_activeException;
103 assert(firstDetectedRuntimeError !=
nullptr);
106 std::rethrow_exception(firstDetectedRuntimeError);
117 std::exception_ptr firstDetectedRuntimeError{
nullptr};
120 if((elem->_activeException !=
nullptr) && (firstDetectedRuntimeError ==
nullptr)) {
121 firstDetectedRuntimeError = elem->_activeException;
125 if(firstDetectedRuntimeError ==
nullptr) {
127 const auto& elem = it.first;
128 elem->handleTransferException([&] { elem->writeTransfer(versionNumber); });
129 if((elem->_activeException !=
nullptr) && (firstDetectedRuntimeError ==
nullptr)) {
130 firstDetectedRuntimeError = elem->_activeException;
138 for(
const auto& lowLevelElem : elem->getHardwareAccessingElements()) {
142 if(lowLevelElem->_activeException) {
144 elem->_activeException = lowLevelElem->_activeException;
157 assert(firstDetectedRuntimeError !=
nullptr);
159 std::rethrow_exception(firstDetectedRuntimeError);
199 "A TransferGroup can only be used with transfer elements that don't have aAccessMode::wait_for_new_data.");
213 if(not isTemporary) {
215 auto list = hlElem1->getInternalElements();
216 list.push_front(hlElem1);
218 for(
const auto& replacement : list) {
230 for(
const auto& hlElem1 : highLevelElementsWithNewAccessor) {
231 auto list = hlElem1->getInternalElements();
232 list.push_front(hlElem1);
234 for(
const auto& replacement : list) {
238 hlElem->replaceTransferElement(replacement);
254 for(
const auto& hwElem : hlElem->getHardwareAccessingElements()) {
262 if(boost::dynamic_pointer_cast<ChimeraTK::CopyRegisterDecoratorTrait>(hlElem) !=
nullptr) {
265 for(
const auto& hwElem : hlElem->getInternalElements()) {
266 if(boost::dynamic_pointer_cast<ChimeraTK::CopyRegisterDecoratorTrait>(hwElem) !=
nullptr) {
281 struct TransferGroupTransferElementAbstractor : TransferElementAbstractor {
282 explicit TransferGroupTransferElementAbstractor(boost::shared_ptr<TransferElement> impl)
286 _impl->replaceTransferElement(std::move(newElement));
295 auto x = detail::TransferGroupTransferElementAbstractor(accessor);
296 addAccessorImpl(x,
true);
302 addAccessorImpl(accessor,
false);
320 std::cout <<
"=== Accessors added to this group: " << std::endl;
322 std::cout <<
" - " << elem->getName() << std::endl;
324 std::cout <<
"=== Low-level transfer elements in this group: " << std::endl;
326 std::cout <<
" - " << elem.first->getName() << std::endl;
328 std::cout <<
"===" << std::endl;
bool has(AccessMode flag) const
Check if a certain flag is in the set.
Base class for register accessors abstractors independent of the UserType.
const boost::shared_ptr< TransferElement > & getHighLevelImplElement()
Obtain the highest level implementation TransferElement.
void replaceTransferElement(const boost::shared_ptr< TransferElement > &newElement)
Search for all underlying TransferElements which are considered identical (see mayReplaceOther()) wit...
TransferElementAbstractor()=default
Create an uninitialised abstractor - just for late initialisation.
AccessModeFlags getAccessModeFlags() const
Return the AccessModeFlags for this TransferElement.
boost::shared_ptr< TransferElement > _impl
Untyped pointer to implementation.
std::set< boost::shared_ptr< TransferElement > > _copyDecorators
List of all CopyRegisterDecorators in the group.
void addAccessor(TransferElementAbstractor &accessor)
Add a register accessor to the group.
bool _isReadable
Cached value whether all elements are readable.
bool _isWriteable
Cached value whether all elements are writeable.
std::set< boost::shared_ptr< TransferElement > > _highLevelElements
List of high-level TransferElements in this group which are directly used by the user.
bool _cachedReadableWriteableIsValid
Flag whether to update the cached information.
bool isReadOnly()
Check if transfer group is read-only.
std::map< boost::shared_ptr< TransferElement >, bool > _lowLevelElementsAndExceptionFlags
List of low-level TransferElements in this group, which are directly responsible for the hardware acc...
bool isWriteable()
Check if transfer group is writeable.
void write(VersionNumber versionNumber={})
Trigger write transfer for all accessors in the group.
bool isReadable()
Check if transfer group is readable.
void dump()
Print information about the accessors in this group to screen, which might help to understand which t...
void updateIsReadableWriteable()
Helper function to update the cached state variables.
void runPostReads(const std::set< boost::shared_ptr< TransferElement > > &elements, const std::exception_ptr &firstDetectedRuntimeError)
void read()
Trigger read transfer for all accessors in the group.
Class for generating and holding version numbers without exposing a numeric representation.
Exception thrown when a logic error has occured.
Exception thrown when a runtime error has occured.
@ wait_for_new_data
Make any read blocking until new data has arrived since the last read.