//===-- deluxe/DeluxeSensor.cpp ---------------------------------*- C++ -*-===//
//
//                                 The RoSA Framework
//
//===----------------------------------------------------------------------===//
///
/// \file deluxe/DeluxeSensor.cpp
///
/// \author David Juhasz (david.juhasz@tuwien.ac.at)
///
/// \date 2017-2019
///
/// \brief Implementation of rosa/deluxe/DeluxeSensor.hpp.
///
//===----------------------------------------------------------------------===//

#include "rosa/deluxe/DeluxeSensor.hpp"

#include "rosa/deluxe/DeluxeAgent.hpp"

namespace rosa {
namespace deluxe {

DeluxeSensor::~DeluxeSensor(void) noexcept {
  LOG_TRACE("Destroying DeluxeSensor...");

  // Make sure \p this object is not a registered *slave*.
  if (Master) {
    ASSERT(unwrapAgent(*Master).Kind == atoms::AgentKind); // Sanity check.
    DeluxeAgent &M = static_cast<DeluxeAgent&>(unwrapAgent(*Master));
    ASSERT(M.positionOfSlave(self()) != M.NumberOfInputs); // Sanity check.
    M.registerSlave(M.positionOfSlave(self()), {});
    Master = {};
  }
}

Optional<AgentHandle> DeluxeSensor::master(void) const noexcept {
  return Master;
}

void DeluxeSensor::registerMaster(const Optional<AgentHandle> _Master) noexcept {
  ASSERT(!_Master || unwrapAgent(*_Master).Kind == atoms::AgentKind);

  Master = _Master;
}

void DeluxeSensor::clearSimulationDataSource(void) noexcept {
  SFP = nullptr;
}

bool DeluxeSensor::simulationDataSourceIsSet(void) const noexcept {
  return SFP != nullptr;
}

void DeluxeSensor::handleTrigger(atoms::Trigger) noexcept {
  // Use \c rosa::deluxe::DeluxeSensor::SFP if set, otherwise
  // \c rosa::deluxe::DeluxeSensor::FP.
  const H &F = SFP ? SFP : FP;
  F();
}

} // End namespace deluxe
} // End namespace rosa
