Skip to content
Snippets Groups Projects
ConstantAccessor.h 2.74 KiB
Newer Older
/*
 * ConstantAccessor.h
 *
 *  Created on: Jun 15, 2016
 *      Author: Martin Hierholzer
 */

#ifndef CHIMERATK_CONSTANT_ACCESSOR_H
#define CHIMERATK_CONSTANT_ACCESSOR_H

#include <ChimeraTK/SyncNDRegisterAccessor.h>
/** Implementation of the NDRegisterAccessor which delivers always the same
 * value and ignors any write operations */
template <typename UserType>
class ConstantAccessor : public ChimeraTK::SyncNDRegisterAccessor<UserType> {

public:
  ConstantAccessor(UserType value = 0, size_t length = 1)
      : ChimeraTK::SyncNDRegisterAccessor<UserType>("UnnamedConstantAccessor"),
        _value(length, value) {
    try {
      ChimeraTK::NDRegisterAccessor<UserType>::buffer_2D.resize(1);
      ChimeraTK::NDRegisterAccessor<UserType>::buffer_2D[0] = _value;
    } catch (...) {
      this->shutdown();
      throw;
    }
  }

  ~ConstantAccessor() { this->shutdown(); }

  void doReadTransfer() override {
    if (firstRead) {
      firstRead = false;
      return;
    }
    // block forever
    isInterrupted = false;
    promise.get_future().wait();
    // if we get here, interrupt() has been called
    throw boost::thread_interrupted();
  }

  bool doReadTransferNonBlocking() override {
    if (firstRead) {
      firstRead = false;
      return true;
    }
    return false;
  }

  bool doReadTransferLatest() override { return doReadTransferNonBlocking(); }

  void doPostRead() override {
    ChimeraTK::NDRegisterAccessor<UserType>::buffer_2D[0] = _value;
  }

  bool
  doWriteTransfer(ChimeraTK::VersionNumber /*versionNumber*/ = {}) override {
    return true;
  }

  bool mayReplaceOther(const boost::shared_ptr<ChimeraTK::TransferElement const>
                           &) const override {
    return false; /// @todo implement properly?
  }

  bool isReadOnly() const override { return false; }

  bool isReadable() const override { return true; }

  bool isWriteable() const override { return true; }

  std::vector<boost::shared_ptr<ChimeraTK::TransferElement>>
  getHardwareAccessingElements() override {
    return {};
  }

  void replaceTransferElement(
      boost::shared_ptr<ChimeraTK::TransferElement>) override {}

  std::list<boost::shared_ptr<ChimeraTK::TransferElement>>
  getInternalElements() override {
    return {};
  }

  AccessModeFlags getAccessModeFlags() const override { return {}; }

  void interrupt() override {
    if (isInterrupted)
      return;
    promise.set_value();
    isInterrupted = true;
  }

  VersionNumber getVersionNumber() const override { return versionNumber; }

protected:
  std::vector<UserType> _value;

  bool firstRead{true};

  bool isInterrupted{false};
  boost::promise<void> promise;

  VersionNumber versionNumber;
};

} /* namespace ChimeraTK */

#endif /* CHIMERATK_CONSTANT_ACCESSOR_H */