|
ChimeraTK-DeviceAccess
03.18.00
|
Go to the documentation of this file.
11 #include <ChimeraTK/cppext/future_queue.hpp>
13 #include <boost/bind/bind.hpp>
14 #include <boost/enable_shared_from_this.hpp>
15 #include <boost/numeric/conversion/cast.hpp>
16 #include <boost/shared_ptr.hpp>
17 #include <boost/thread.hpp>
18 #include <boost/thread/future.hpp>
29 class PersistentDataStorage;
60 class DiscardValueException {};
71 std::string description = std::string())
85 using SharedPtr = boost::shared_ptr<TransferElement>;
119 "' which is part of a TransferGroup is not allowed.");
123 "' which is part of a ReadAnyGroup is not allowed.");
125 this->readTransactionInProgress =
false;
149 "' which is part of a TransferGroup is not allowed.");
153 "' which is part of a ReadAnyGroup is not allowed.");
155 this->readTransactionInProgress =
false;
157 bool updateDataBuffer =
false;
162 bool retVal = updateDataBuffer;
187 bool updateDataBuffer =
false;
191 updateDataBuffer =
true;
193 return updateDataBuffer;
207 "' which is part of a TransferGroup is not allowed.");
209 this->writeTransactionInProgress =
false;
210 bool previousDataLost =
true;
215 handleTransferException([&] { previousDataLost =
writeTransfer(versionNumber); });
219 return previousDataLost;
229 "' which is part of a TransferGroup is not allowed.");
231 this->writeTransactionInProgress =
false;
234 bool previousDataLost =
true;
241 return previousDataLost;
279 if(setThisException) {
281 setThisException =
nullptr;
319 template<
typename Callable>
320 void handleTransferException(Callable
function) {
327 catch(boost::thread_interrupted&) {
334 void readTransferAsyncWaitingImpl() {
339 catch(detail::DiscardValueException&) {
356 readTransferAsyncWaitingImpl();
381 bool readTransferAsyncNonWaitingImpl() {
386 catch(detail::DiscardValueException&) {
404 return readTransferAsyncNonWaitingImpl();
412 void preReadAndHandleExceptions(
TransferType type) noexcept {
422 catch(boost::thread_interrupted&) {
433 if(readTransactionInProgress)
return;
436 readTransactionInProgress =
true;
453 void postReadAndHandleExceptions(
TransferType type,
bool updateDataBuffer) {
475 if(readTransactionInProgress) {
476 readTransactionInProgress =
false;
517 catch(boost::thread_interrupted&) {
531 if(writeTransactionInProgress)
return;
536 "' is less than the last version number used.");
538 writeTransactionInProgress =
true;
574 if(writeTransactionInProgress) {
575 writeTransactionInProgress =
false;
677 virtual bool mayReplaceOther(
const boost::shared_ptr<TransferElement const>& other)
const {
791 template<
typename QUEUE_TYPE>
793 dataTransportQueue.push_overwrite_exception(std::make_exception_ptr(boost::thread_interrupted()));
837 bool readTransactionInProgress{
false};
841 bool writeTransactionInProgress{
false};
const char * what() const noexcept override
Return the message describing what exactly went wrong.
bool readLatest()
Read the latest value, discarding any other update since the last read if present.
virtual void doPostRead(TransferType, bool)
Backend specific implementation of postRead().
virtual void setPersistentDataStorage(boost::shared_ptr< ChimeraTK::PersistentDataStorage >)
Associate a persistent data storage object to be updated on each write operation of this ProcessArray...
@ faulty
The data is considered valid.
const std::string & getName() const
Returns the name that identifies the process variable.
void setActiveException(std::exception_ptr &setThisException)
Set an active exception.
TransferElementID _id
The ID of this TransferElement.
virtual bool doWriteTransfer(ChimeraTK::VersionNumber versionNumber)=0
Implementation version of writeTransfer().
virtual void replaceTransferElement([[maybe_unused]] boost::shared_ptr< TransferElement > newElement)
Search for all underlying TransferElements which are considered identical (see sameRegister()) with t...
const std::string & getDescription() const
Returns the description of this variable/register.
bool readNonBlocking()
Read the next value, if available in the input buffer.
cppext::future_queue< void > getReadQueue()
Function to get a copy of the read queue.
virtual boost::shared_ptr< TransferElement > getHighLevelImplElement()
Obtain the highest level implementation TransferElement.
void readTransfer()
Read the data from the device but do not fill it into the user buffer of this TransferElement.
virtual boost::shared_ptr< TransferElement > makeCopyRegisterDecorator()=0
Create a CopyRegisterDecorator of the right type decorating this TransferElement.
bool writeDestructively(ChimeraTK::VersionNumber versionNumber={})
Just like write(), but allows the implementation to destroy the content of the user buffer in the pro...
void interrupt_impl(QUEUE_TYPE &dataTransportQueue)
Implementation of interrupt()
boost::shared_ptr< DeviceBackend > getExceptionBackend()
Return the exception backend.
bool writeTransferDestructively(ChimeraTK::VersionNumber versionNumber)
Write the data to the device.
DataValidity dataValidity() const
Return current validity of the data.
bool _isInTransferGroup
Flag whether this TransferElement has been added to a TransferGroup or not.
void setDataValidity(DataValidity validity=DataValidity::ok)
Set the current DataValidity for this TransferElement.
void preWrite(TransferType type, ChimeraTK::VersionNumber versionNumber)
Transfer the data from the user buffer into the device send buffer, while converting the data from th...
virtual void doReadTransferSynchronously()=0
Implementation version of readTransfer() for synchronous reads.
virtual bool isReadOnly() const =0
Check if transfer element is read only, i.e.
std::exception_ptr _activeException
Exception to be rethrown in postXXX() in case hasSeenException == true Can be set via setActiveExcept...
std::string _unit
Engineering unit.
void makeUnique()
Assign an ID to this instance.
Exception thrown when a runtime error has occured.
Group multiple data accessors to efficiently trigger data transfers on the whole group.
virtual ~TransferElement()=default
Abstract base classes need a virtual destructor.
void postRead(TransferType type, bool updateDataBuffer)
Transfer the data from the device receive buffer into the user buffer, while converting the data into...
AccessModeFlags getAccessModeFlags() const
Return the AccessModeFlags for this TransferElement.
boost::shared_ptr< TransferElement > SharedPtr
A typedef for more compact syntax.
bool has(AccessMode flag) const
Check if a certain flag is in the set.
void postWrite(TransferType type, VersionNumber versionNumber)
Perform any post-write clean-ups if necessary.
virtual std::vector< boost::shared_ptr< TransferElement > > getHardwareAccessingElements()=0
Obtain the underlying TransferElements with actual hardware access.
bool readTransferNonBlocking()
Read the data from the device but do not fill it into the user buffer of this TransferElement.
static constexpr char unitNotSet[]
Constant string to be used as a unit when the unit is not provided or known.
virtual void doPostWrite(TransferType, VersionNumber)
Backend specific implementation of postWrite().
bool write(ChimeraTK::VersionNumber versionNumber={})
Write the data to device.
size_t _id
The actual ID value.
DataValidity
The current state of the data.
virtual bool doWriteTransferDestructively(ChimeraTK::VersionNumber versionNumber)
Implementation version of writeTransferDestructively().
virtual void doPreWrite(TransferType, VersionNumber)
Backend specific implementation of preWrite().
@ wait_for_new_data
Make any read blocking until new data has arrived since the last read.
virtual void setExceptionBackend(boost::shared_ptr< DeviceBackend > exceptionBackend)
Set the backend to which the exception has to be reported.
DataValidity _dataValidity
The validity of the data in the application buffer.
std::string _name
Identifier uniquely identifying the TransferElement.
boost::shared_ptr< DeviceBackend > _exceptionBackend
The backend to which the runtime_errors are reported via DeviceBackend::setException().
TransferElement(std::string name, AccessModeFlags accessModeFlags, std::string unit=std::string(unitNotSet), std::string description=std::string())
Creates a transfer element with the specified name.
TransferType
Used to indicate the applicable operation on a Transferelement.
virtual void doPreRead(TransferType)
Backend specific implementation of preRead().
virtual bool isWriteable() const =0
Check if transfer element is writeable.
void makeUniqueId()
Allow generating a unique ID from derived classes.
void preRead(TransferType type)
Perform any pre-read tasks if necessary.
std::size_t operator()(const ChimeraTK::TransferElementID &f) const
bool operator()(const ChimeraTK::TransferElementID &a, const ChimeraTK::TransferElementID &b) const
std::string _description
Description of this variable/register.
ChimeraTK::VersionNumber getVersionNumber() const
Returns the version number that is associated with the last transfer (i.e.
Base class for register accessors which can be part of a TransferGroup.
virtual bool mayReplaceOther(const boost::shared_ptr< TransferElement const > &other) const
Check whether the TransferElement can be used in places where the TransferElement "other" is currentl...
bool isReadTransactionInProgress() const
Check whether a read transaction is in progress, i.e.
const std::string & getUnit() const
Returns the engineering unit.
TransferElementID getId() const
Obtain unique ID for this TransferElement, see TransferElementID for details.
Group several registers (= TransferElement) to allow waiting for an update of any of the registers.
std::ostream & operator<<(std::ostream &stream, const DataDescriptor::FundamentalType &fundamentalType)
Class for generating and holding version numbers without exposing a numeric representation.
virtual std::list< boost::shared_ptr< TransferElement > > getInternalElements()=0
Obtain the full list of TransferElements internally used by this TransferElement.
cppext::future_queue< void > _readQueue
The queue for asynchronous read transfers.
bool writeTransfer(ChimeraTK::VersionNumber versionNumber)
Write the data to the device.
bool _isInReadAnyGroup
Flag whether this TransferElement has been added to a ReadAnyGroup or not.
TransferElement & operator=(const TransferElement &other)=delete
Set of AccessMode flags with additional functionality for an easier handling.
Simple class holding a unique ID for a TransferElement.
void read()
Read the data from the device.
AccessModeFlags _accessModeFlags
The access mode flags for this transfer element.
bool isWriteTransactionInProgress() const
Check whether a write transaction is in progress, i.e.
virtual bool isReadable() const =0
Check if transfer element is readable.
virtual void interrupt()
Return from a blocking read immediately and throw boost::thread_interrupted.
virtual const std::type_info & getValueType() const =0
Returns the std::type_info for the value type of this transfer element.
Exception thrown when a logic error has occured.
VersionNumber _versionNumber
The version number of the last successful transfer.