<commit_before>// //////////////////////////////////////////////////////////////////////
// Import section
// //////////////////////////////////////////////////////////////////////
// STL
#include <cassert>
// StdAir
#include <stdair/stdair_exceptions.hpp>
#include <stdair/basic/BasConst_Event.hpp>
#include <stdair/bom/EventStruct.hpp>
#include <stdair/service/Logger.hpp>
// SEvMgr
#include <sevmgr/basic/BasConst_EventQueueManager.hpp>
#include <sevmgr/bom/EventQueue.hpp>

namespace SEVMGR {

  // //////////////////////////////////////////////////////////////////////
  EventQueue::EventQueue()
    : _key (DEFAULT_EVENT_QUEUE_ID), _parent (NULL),
      _progressStatus (stdair::DEFAULT_PROGRESS_STATUS,
                       stdair::DEFAULT_PROGRESS_STATUS) {
  }

  // //////////////////////////////////////////////////////////////////////
  EventQueue::EventQueue (const Key_T& iKey)
    : _key (iKey), _parent (NULL),
      _progressStatus (stdair::DEFAULT_PROGRESS_STATUS,
                       stdair::DEFAULT_PROGRESS_STATUS) {
  }

  // //////////////////////////////////////////////////////////////////////
  EventQueue::EventQueue (const EventQueue& iEventQueue)
    : _key (DEFAULT_EVENT_QUEUE_ID), _parent (NULL),
      _progressStatus (stdair::DEFAULT_PROGRESS_STATUS,
                       stdair::DEFAULT_PROGRESS_STATUS) {
    assert (false);
  }

  // //////////////////////////////////////////////////////////////////////
  EventQueue::~EventQueue() {
    _eventList.clear();
  }

  // //////////////////////////////////////////////////////////////////////
  std::string EventQueue::toString() const {
    std::ostringstream oStr;
    oStr << "(" << _eventList.size() << ") "
         << _progressStatus.getCurrentNb() << "/{"
         << _progressStatus.getExpectedNb() << ","
         << _progressStatus.getActualNb() << "}";
    return oStr.str();
  }

  // //////////////////////////////////////////////////////////////////////
  std::string EventQueue::display() const {
    std::ostringstream oStr;

    oStr << toString();

    return oStr.str();
  }

  // //////////////////////////////////////////////////////////////////////
  std::string EventQueue::list () const {
    std::ostringstream oStr;
    oStr << describeKey () << "\n"
	 << toString() << "\n";

    // Browse the events
    for (stdair::EventList_T::const_iterator itEvent = _eventList.begin();
	 itEvent != _eventList.end(); ++itEvent) {
      const stdair::EventListElement_T* lEventListElement_ptr = &(*itEvent);
      assert (lEventListElement_ptr != NULL);
      const stdair::EventListElement_T& lEventListElement =
	*lEventListElement_ptr;
      const stdair::EventStruct& lEvent = lEventListElement.second;
      const stdair::EventType::EN_EventType& lEventType = lEvent.getEventType();

      switch (lEventType) {
      case stdair::EventType::BKG_REQ:
      case stdair::EventType::CX:
      case stdair::EventType::BRK_PT: {
        // Delegate the JSON export to the dedicated service
        oStr << lEvent.describe();
        break;
      }
      case stdair::EventType::OPT_NOT_4_FD:
      case stdair::EventType::SNAPSHOT:
      case stdair::EventType::RM:
      default:
        break;
      }

    }
    return oStr.str();
  }

  // //////////////////////////////////////////////////////////////////////
  stdair::Count_T EventQueue::getQueueSize () const {
    return _eventList.size();
  }

  // //////////////////////////////////////////////////////////////////////
  bool EventQueue::isQueueEmpty () const {
    return _eventList.empty();
  }

  // //////////////////////////////////////////////////////////////////////
  bool EventQueue::isQueueDone () const {
    const bool isQueueEmpty = _eventList.empty();
    return isQueueEmpty;
  }

  // //////////////////////////////////////////////////////////////////////
  void EventQueue::reset () {
    // Reset only the current number of events, not the expected one
    _progressStatus.reset();

    // Empty the list of events
    _eventList.clear();

    // Reset the progress statuses for all the event types
    for (ProgressStatusMap_T::iterator itProgressStatus =
           _progressStatusMap.begin();
         itProgressStatus != _progressStatusMap.end(); ++itProgressStatus) {
      stdair::ProgressStatus& lProgressStatus = itProgressStatus->second;
      lProgressStatus.reset();
    }
  }

  // //////////////////////////////////////////////////////////////////////
  bool EventQueue::
  hasProgressStatus (const stdair::EventType::EN_EventType& iType) const {

    bool hasProgressStatus = true;

    // Retrieve the ProgressStatus structure corresponding to the
    // given event type
    ProgressStatusMap_T::const_iterator itProgressStatus =
      _progressStatusMap.find (iType);
    if (itProgressStatus == _progressStatusMap.end()) {
      //
      STDAIR_LOG_DEBUG ("No ProgressStatus structure can be retrieved in the "
                        << "EventQueue: " << display());

      hasProgressStatus = false;
    }

    return hasProgressStatus;
  }

  // //////////////////////////////////////////////////////////////////////
  const stdair::Count_T& EventQueue::
  getCurrentNbOfEvents (const stdair::EventType::EN_EventType& iType) const {

    // Retrieve the ProgressStatus structure corresponding to the
    // given event type
    ProgressStatusMap_T::const_iterator itProgressStatus =
      _progressStatusMap.find (iType);
    if (itProgressStatus == _progressStatusMap.end()) {
      //
      STDAIR_LOG_ERROR ("No ProgressStatus structure can be retrieved in the "
                        << "EventQueue: " << display());
      assert (false);
    }

    const stdair::ProgressStatus& lProgressStatus = itProgressStatus->second;
    return lProgressStatus.getCurrentNb();
  }

  // //////////////////////////////////////////////////////////////////////
  const stdair::Count_T& EventQueue::
  getExpectedTotalNbOfEvents (const stdair::EventType::EN_EventType& iType) const {

    // Retrieve the ProgressStatus structure corresponding to the
    // given event type
    ProgressStatusMap_T::const_iterator itProgressStatus =
      _progressStatusMap.find (iType);
    if (itProgressStatus == _progressStatusMap.end()) {
      std::ostringstream oStr;
      oStr << "No ProgressStatus structure can be retrieved in the EventQueue '"
           << display() << "'. The EventQueue should be initialised, e.g., by "
           << "calling a buildSampleBom() method.";
      //
      STDAIR_LOG_ERROR (oStr.str());
      throw EventQueueException (oStr.str());
    }

    const stdair::ProgressStatus& lProgressStatus = itProgressStatus->second;
    return lProgressStatus.getExpectedNb();
  }

  // //////////////////////////////////////////////////////////////////////
  const stdair::Count_T& EventQueue::
  getActualTotalNbOfEvents (const stdair::EventType::EN_EventType& iType) const {

    // Retrieve the ProgressStatus structure corresponding to the
    // given event type
    ProgressStatusMap_T::const_iterator itProgressStatus =
      _progressStatusMap.find (iType);
    if (itProgressStatus == _progressStatusMap.end()) {
      //
      STDAIR_LOG_ERROR ("No ProgressStatus structure can be retrieved in the "
                        << "EventQueue: " << display());
      assert (false);
    }

    const stdair::ProgressStatus& lProgressStatus = itProgressStatus->second;
    return lProgressStatus.getActualNb();
  }

  // //////////////////////////////////////////////////////////////////////
  void EventQueue::updateStatus (const stdair::EventType::EN_EventType& iType,
                                 const stdair::ProgressStatus& iProgressStatus) {

    // Retrieve, if existing, the ProgressStatus structure
    // corresponding to the given event type
    ProgressStatusMap_T::iterator itProgressStatus =
      _progressStatusMap.find (iType);
    if (itProgressStatus == _progressStatusMap.end()) {
      const bool hasInsertBeenSuccessful =
        _progressStatusMap.insert (ProgressStatusMap_T::
                                   value_type (iType, iProgressStatus)).second;

      if (hasInsertBeenSuccessful == false) {
        STDAIR_LOG_ERROR ("No progress_status can be inserted "
                          << "for the following event type: "
                          << stdair::EventType::getLabel(iType)
                          << ". EventQueue: " << toString());
        throw stdair::EventException ("No progress_status can be inserted for the "
				      "following event type: "
				      + stdair::EventType::getLabel(iType)
				      + ". EventQueue: " + toString());
      }

      return;
    }

    stdair::ProgressStatus& lProgressStatus = itProgressStatus->second;

    // Update the progress status
    const stdair::Count_T& lCurrentNb = iProgressStatus.getCurrentNb();
    lProgressStatus.setCurrentNb (lCurrentNb);

    const stdair::Count_T& lExpectedNb = iProgressStatus.getExpectedNb();
    lProgressStatus.setExpectedNb(lProgressStatus.getExpectedNb() + lExpectedNb);

    const stdair::Count_T& lActualNb = iProgressStatus.getActualNb();
    lProgressStatus.setActualNb (lProgressStatus.getActualNb() + lActualNb);
  }

  // //////////////////////////////////////////////////////////////////////
  void EventQueue::
  addStatus (const stdair::EventType::EN_EventType& iType,
             const stdair::NbOfEvents_T& iExpectedTotalNbOfEvents) {

    // Initialise the progress status object
    const stdair::Count_T lExpectedTotalNbOfEventsInt =
      static_cast<const stdair::Count_T> (std::floor (iExpectedTotalNbOfEvents));
    const stdair::ProgressStatus lProgressStatus (lExpectedTotalNbOfEventsInt);

    // Update the progress status for the given event type
    updateStatus (iType, lProgressStatus);

    // Update the overall progress status
    const stdair::Count_T lExpectedNb =
      static_cast<const stdair::Count_T> (_progressStatus.getExpectedNb()
				  + iExpectedTotalNbOfEvents);
    _progressStatus.setExpectedNb (lExpectedNb);

    const stdair::Count_T lActualNb =
      static_cast<const stdair::Count_T> (_progressStatus.getActualNb()
				  + iExpectedTotalNbOfEvents);
    _progressStatus.setActualNb (lActualNb);

  }

  // //////////////////////////////////////////////////////////////////////
  void EventQueue::updateStatus (const stdair::EventType::EN_EventType& iType,
                                 const stdair::NbOfEvents_T& iActualNbOfEvents) {

    // Initialise the progress status object for the type key
    stdair:: Count_T lActualNbOfEventsInt =
      static_cast<const  stdair::Count_T> (std::floor (iActualNbOfEvents));

    // Update the progress status for the corresponding content type key
    ProgressStatusMap_T::iterator itProgressStatus =
      _progressStatusMap.find (iType);
    if (itProgressStatus != _progressStatusMap.end()) {

      //
      stdair::ProgressStatus& lProgressStatus = itProgressStatus->second;

      // Update the overall progress status
      const stdair::Count_T lActualEventTypeNb = lProgressStatus.getActualNb();
      const stdair::Count_T lActualTotalNb = _progressStatus.getActualNb();
      _progressStatus.setActualNb (lActualTotalNb + iActualNbOfEvents - lActualEventTypeNb);

      // Update the progress status for the corresponding type key
      lProgressStatus.setActualNb (lActualNbOfEventsInt);
    }
  }

  // //////////////////////////////////////////////////////////////////////
  void EventQueue::setStatus (const stdair::EventType::EN_EventType& iType,
                              const stdair::ProgressStatus& iProgressStatus) {

    // Retrieve the ProgressStatus structure corresponding to the
    // given event type
    ProgressStatusMap_T::iterator itProgressStatus =
      _progressStatusMap.find (iType);
    // assert (itProgressStatus != _progressStatusMap.end());
    if (itProgressStatus != _progressStatusMap.end()) {
      // Update the ProgressStatus structure
      itProgressStatus->second = iProgressStatus;
    }
  }

  // //////////////////////////////////////////////////////////////////////
  stdair::ProgressStatus EventQueue::
  getStatus (const stdair::EventType::EN_EventType& iType) const {

    // Retrieve the ProgressStatus structure corresponding to the
    // given event type
    ProgressStatusMap_T::const_iterator itProgressStatus =
      _progressStatusMap.find (iType);
    if (itProgressStatus != _progressStatusMap.end()) {
      const stdair::ProgressStatus& oProgressStatus = itProgressStatus->second;
      return oProgressStatus;
    }

    return stdair::ProgressStatus();
  }

  // //////////////////////////////////////////////////////////////////////
  stdair::ProgressPercentage_T EventQueue::
  calculateProgress (const stdair::EventType::EN_EventType& iType) const {

    // Retrieve the ProgressStatus structure corresponding to the
    // given event type
    ProgressStatusMap_T::const_iterator itProgressStatus =
      _progressStatusMap.find (iType);
    if (itProgressStatus == _progressStatusMap.end()) {
      //
      STDAIR_LOG_ERROR ("No ProgressStatus structure can be retrieved in the "
                        << "EventQueue: " << display());
      assert (false);
    }

    const stdair::ProgressStatus& lProgressStatus = itProgressStatus->second;
    return lProgressStatus.progress();
  }

  // //////////////////////////////////////////////////////////////////////
  stdair::ProgressStatusSet EventQueue::popEvent (stdair::EventStruct& ioEventStruct) {

    if (_eventList.empty() == true) {
      std::ostringstream oStr;
      oStr << "The event queue '" << describeKey() << "' is empty. "
	   << "No event can be popped.";
      //
      STDAIR_LOG_ERROR (oStr.str());
      throw EventQueueException (oStr.str());
    }

    /**
     * 1. Update the event queue itself.
     */
    // Get an iterator on the first event (sorted by date-time stamps)
    stdair::EventList_T::iterator itEvent = _eventList.begin();

    /**
     * Extract (a copy of) the corresponding Event structure. We make
     * a copy here, as the original EventStruct structure is removed
     * from the list (and erased). Moreover, the resulting EventStruct
     * structure will be returned by this method.
     */
    ioEventStruct = itEvent->second;
    // Retrieve the event type
    const stdair::EventType::EN_EventType& lEventType = ioEventStruct.getEventType();
    stdair::ProgressStatusSet oProgressStatusSet (lEventType);

    // Update the (current number part of the) overall progress status,
    // to account for the event that is being popped out of the event
    // queue.
    ++_progressStatus;

    // Remove the event, which has just been retrieved
    _eventList.erase (itEvent);

    /**
     * 2. Update the progress statuses held by the EventStruct structure.
     *
     * 2.1. Update the progress status specific to the event type (e.g.,
     *      booking request, optimisation notification).
     */

    // Retrieve the progress status specific to that event type
    stdair::ProgressStatus lEventTypeProgressStatus = getStatus (lEventType);

    // Increase the current number of events
    ++lEventTypeProgressStatus;

    // Store back the progress status
    setStatus (lEventType, lEventTypeProgressStatus);

    // Update the progress status of the progress status set, specific to
    // the event type.
    oProgressStatusSet.setTypeSpecificStatus (lEventTypeProgressStatus);

    /**
     * 2.2. Update the overall progress status.
     */
    // Update the overall progress status of the progress status set.
    oProgressStatusSet.setOverallStatus (_progressStatus);

    //
    return oProgressStatusSet;
  }

  // //////////////////////////////////////////////////////////////////////
  bool EventQueue::addEvent (stdair::EventStruct& ioEventStruct) {
    bool insertionSucceeded =
      _eventList.insert (stdair::EventListElement_T (ioEventStruct.getEventTimeStamp(),
						     ioEventStruct)).second;

    /**
     * If the insertion has not been successful, try repeatedly until
     * the insertion becomes successful.
     *
     * The date-time is counted in milliseconds (1e-3 second). Hence,
     * one thousand (1e3) of attempts correspond to 1 second.
     *
     * The check on one thousand (1e3) is made in order to avoid
     * potential infinite loops. In such case, however, an assertion
     * will fail: it is always better that an assertion fails rather
     * than entering an infinite loop.
     */
    const unsigned int idx = 0;
    while (insertionSucceeded == false && idx != 1e3) {
      // Increment the date-time stamp (expressed in milliseconds)
      ioEventStruct.incrementEventTimeStamp();

      // Retry to insert into the event queue
      insertionSucceeded =
        _eventList.insert (stdair::EventListElement_T (ioEventStruct.getEventTimeStamp(),
						       ioEventStruct)).second;
    }
    assert (idx != 1e3);

    return insertionSucceeded;
  }

  // //////////////////////////////////////////////////////////////////////
  bool EventQueue::hasEventDateTime (const stdair::DateTime_T& iDateTime) {

    bool hasSearchEventBeenSucessful = true;

    /**
     * Compute the number of milliseconds between the
     * date-time of the event and DEFAULT_EVENT_OLDEST_DATETIME
     * (as of Feb. 2011, that date is set to Jan. 1, 2010).
     */
    const stdair::Duration_T lDuration =
      iDateTime - stdair::DEFAULT_EVENT_OLDEST_DATETIME;
    const stdair::LongDuration_T lDateTimeStamp =
      lDuration.total_milliseconds();

    // Searches the container for an element with iDateTime as key
    stdair::EventList_T::iterator itEvent =
      _eventList.find (lDateTimeStamp);

    // An iterator to map::end means the specified key has not found in the
    // container.
    if (itEvent == _eventList.end()) {
      hasSearchEventBeenSucessful = false;
    }

    return hasSearchEventBeenSucessful;

  }

}
<commit_msg>Revert "[Dev] Removed the display of rm events and snap shots for a lighter display of the queue."<commit_after>// //////////////////////////////////////////////////////////////////////
// Import section
// //////////////////////////////////////////////////////////////////////
// STL
#include <cassert>
// StdAir
#include <stdair/stdair_exceptions.hpp>
#include <stdair/basic/BasConst_Event.hpp>
#include <stdair/bom/EventStruct.hpp>
#include <stdair/service/Logger.hpp>
// SEvMgr
#include <sevmgr/basic/BasConst_EventQueueManager.hpp>
#include <sevmgr/bom/EventQueue.hpp>

namespace SEVMGR {

  // //////////////////////////////////////////////////////////////////////
  EventQueue::EventQueue()
    : _key (DEFAULT_EVENT_QUEUE_ID), _parent (NULL),
      _progressStatus (stdair::DEFAULT_PROGRESS_STATUS,
                       stdair::DEFAULT_PROGRESS_STATUS) {
  }

  // //////////////////////////////////////////////////////////////////////
  EventQueue::EventQueue (const Key_T& iKey)
    : _key (iKey), _parent (NULL),
      _progressStatus (stdair::DEFAULT_PROGRESS_STATUS,
                       stdair::DEFAULT_PROGRESS_STATUS) {
  }

  // //////////////////////////////////////////////////////////////////////
  EventQueue::EventQueue (const EventQueue& iEventQueue)
    : _key (DEFAULT_EVENT_QUEUE_ID), _parent (NULL),
      _progressStatus (stdair::DEFAULT_PROGRESS_STATUS,
                       stdair::DEFAULT_PROGRESS_STATUS) {
    assert (false);
  }

  // //////////////////////////////////////////////////////////////////////
  EventQueue::~EventQueue() {
    _eventList.clear();
  }

  // //////////////////////////////////////////////////////////////////////
  std::string EventQueue::toString() const {
    std::ostringstream oStr;
    oStr << "(" << _eventList.size() << ") "
         << _progressStatus.getCurrentNb() << "/{"
         << _progressStatus.getExpectedNb() << ","
         << _progressStatus.getActualNb() << "}";
    return oStr.str();
  }

  // //////////////////////////////////////////////////////////////////////
  std::string EventQueue::display() const {
    std::ostringstream oStr;

    oStr << toString();

    return oStr.str();
  }

  // //////////////////////////////////////////////////////////////////////
  std::string EventQueue::list () const {
    std::ostringstream oStr;
    oStr << describeKey () << "\n"
	 << toString() << "\n";

    // Browse the events
    for (stdair::EventList_T::const_iterator itEvent = _eventList.begin();
	 itEvent != _eventList.end(); ++itEvent) {
      const stdair::EventListElement_T* lEventListElement_ptr = &(*itEvent);
      assert (lEventListElement_ptr != NULL);
      const stdair::EventListElement_T& lEventListElement =
	*lEventListElement_ptr;
      const stdair::EventStruct& lEvent = lEventListElement.second;

      // Delegate the JSON export to the dedicated service
      oStr << lEvent.describe() << "\n";
    }

    return oStr.str();
  }

  // //////////////////////////////////////////////////////////////////////
  stdair::Count_T EventQueue::getQueueSize () const {
    return _eventList.size();
  }

  // //////////////////////////////////////////////////////////////////////
  bool EventQueue::isQueueEmpty () const {
    return _eventList.empty();
  }

  // //////////////////////////////////////////////////////////////////////
  bool EventQueue::isQueueDone () const {
    const bool isQueueEmpty = _eventList.empty();
    return isQueueEmpty;
  }

  // //////////////////////////////////////////////////////////////////////
  void EventQueue::reset () {
    // Reset only the current number of events, not the expected one
    _progressStatus.reset();

    // Empty the list of events
    _eventList.clear();

    // Reset the progress statuses for all the event types
    for (ProgressStatusMap_T::iterator itProgressStatus =
           _progressStatusMap.begin();
         itProgressStatus != _progressStatusMap.end(); ++itProgressStatus) {
      stdair::ProgressStatus& lProgressStatus = itProgressStatus->second;
      lProgressStatus.reset();
    }
  }

  // //////////////////////////////////////////////////////////////////////
  bool EventQueue::
  hasProgressStatus (const stdair::EventType::EN_EventType& iType) const {

    bool hasProgressStatus = true;

    // Retrieve the ProgressStatus structure corresponding to the
    // given event type
    ProgressStatusMap_T::const_iterator itProgressStatus =
      _progressStatusMap.find (iType);
    if (itProgressStatus == _progressStatusMap.end()) {
      //
      STDAIR_LOG_DEBUG ("No ProgressStatus structure can be retrieved in the "
                        << "EventQueue: " << display());

      hasProgressStatus = false;
    }

    return hasProgressStatus;
  }

  // //////////////////////////////////////////////////////////////////////
  const stdair::Count_T& EventQueue::
  getCurrentNbOfEvents (const stdair::EventType::EN_EventType& iType) const {

    // Retrieve the ProgressStatus structure corresponding to the
    // given event type
    ProgressStatusMap_T::const_iterator itProgressStatus =
      _progressStatusMap.find (iType);
    if (itProgressStatus == _progressStatusMap.end()) {
      //
      STDAIR_LOG_ERROR ("No ProgressStatus structure can be retrieved in the "
                        << "EventQueue: " << display());
      assert (false);
    }

    const stdair::ProgressStatus& lProgressStatus = itProgressStatus->second;
    return lProgressStatus.getCurrentNb();
  }

  // //////////////////////////////////////////////////////////////////////
  const stdair::Count_T& EventQueue::
  getExpectedTotalNbOfEvents (const stdair::EventType::EN_EventType& iType) const {

    // Retrieve the ProgressStatus structure corresponding to the
    // given event type
    ProgressStatusMap_T::const_iterator itProgressStatus =
      _progressStatusMap.find (iType);
    if (itProgressStatus == _progressStatusMap.end()) {
      std::ostringstream oStr;
      oStr << "No ProgressStatus structure can be retrieved in the EventQueue '"
           << display() << "'. The EventQueue should be initialised, e.g., by "
           << "calling a buildSampleBom() method.";
      //
      STDAIR_LOG_ERROR (oStr.str());
      throw EventQueueException (oStr.str());
    }

    const stdair::ProgressStatus& lProgressStatus = itProgressStatus->second;
    return lProgressStatus.getExpectedNb();
  }

  // //////////////////////////////////////////////////////////////////////
  const stdair::Count_T& EventQueue::
  getActualTotalNbOfEvents (const stdair::EventType::EN_EventType& iType) const {

    // Retrieve the ProgressStatus structure corresponding to the
    // given event type
    ProgressStatusMap_T::const_iterator itProgressStatus =
      _progressStatusMap.find (iType);
    if (itProgressStatus == _progressStatusMap.end()) {
      //
      STDAIR_LOG_ERROR ("No ProgressStatus structure can be retrieved in the "
                        << "EventQueue: " << display());
      assert (false);
    }

    const stdair::ProgressStatus& lProgressStatus = itProgressStatus->second;
    return lProgressStatus.getActualNb();
  }

  // //////////////////////////////////////////////////////////////////////
  void EventQueue::updateStatus (const stdair::EventType::EN_EventType& iType,
                                 const stdair::ProgressStatus& iProgressStatus) {

    // Retrieve, if existing, the ProgressStatus structure
    // corresponding to the given event type
    ProgressStatusMap_T::iterator itProgressStatus =
      _progressStatusMap.find (iType);
    if (itProgressStatus == _progressStatusMap.end()) {
      const bool hasInsertBeenSuccessful =
        _progressStatusMap.insert (ProgressStatusMap_T::
                                   value_type (iType, iProgressStatus)).second;

      if (hasInsertBeenSuccessful == false) {
        STDAIR_LOG_ERROR ("No progress_status can be inserted "
                          << "for the following event type: "
                          << stdair::EventType::getLabel(iType)
                          << ". EventQueue: " << toString());
        throw stdair::EventException ("No progress_status can be inserted for the "
				      "following event type: "
				      + stdair::EventType::getLabel(iType)
				      + ". EventQueue: " + toString());
      }

      return;
    }

    stdair::ProgressStatus& lProgressStatus = itProgressStatus->second;

    // Update the progress status
    const stdair::Count_T& lCurrentNb = iProgressStatus.getCurrentNb();
    lProgressStatus.setCurrentNb (lCurrentNb);

    const stdair::Count_T& lExpectedNb = iProgressStatus.getExpectedNb();
    lProgressStatus.setExpectedNb(lProgressStatus.getExpectedNb() + lExpectedNb);

    const stdair::Count_T& lActualNb = iProgressStatus.getActualNb();
    lProgressStatus.setActualNb (lProgressStatus.getActualNb() + lActualNb);
  }

  // //////////////////////////////////////////////////////////////////////
  void EventQueue::
  addStatus (const stdair::EventType::EN_EventType& iType,
             const stdair::NbOfEvents_T& iExpectedTotalNbOfEvents) {

    // Initialise the progress status object
    const stdair::Count_T lExpectedTotalNbOfEventsInt =
      static_cast<const stdair::Count_T> (std::floor (iExpectedTotalNbOfEvents));
    const stdair::ProgressStatus lProgressStatus (lExpectedTotalNbOfEventsInt);

    // Update the progress status for the given event type
    updateStatus (iType, lProgressStatus);

    // Update the overall progress status
    const stdair::Count_T lExpectedNb =
      static_cast<const stdair::Count_T> (_progressStatus.getExpectedNb()
				  + iExpectedTotalNbOfEvents);
    _progressStatus.setExpectedNb (lExpectedNb);

    const stdair::Count_T lActualNb =
      static_cast<const stdair::Count_T> (_progressStatus.getActualNb()
				  + iExpectedTotalNbOfEvents);
    _progressStatus.setActualNb (lActualNb);

  }

  // //////////////////////////////////////////////////////////////////////
  void EventQueue::updateStatus (const stdair::EventType::EN_EventType& iType,
                                 const stdair::NbOfEvents_T& iActualNbOfEvents) {

    // Initialise the progress status object for the type key
    stdair:: Count_T lActualNbOfEventsInt =
      static_cast<const  stdair::Count_T> (std::floor (iActualNbOfEvents));

    // Update the progress status for the corresponding content type key
    ProgressStatusMap_T::iterator itProgressStatus =
      _progressStatusMap.find (iType);
    if (itProgressStatus != _progressStatusMap.end()) {

      //
      stdair::ProgressStatus& lProgressStatus = itProgressStatus->second;

      // Update the overall progress status
      const stdair::Count_T lActualEventTypeNb = lProgressStatus.getActualNb();
      const stdair::Count_T lActualTotalNb = _progressStatus.getActualNb();
      _progressStatus.setActualNb (lActualTotalNb + iActualNbOfEvents - lActualEventTypeNb);

      // Update the progress status for the corresponding type key
      lProgressStatus.setActualNb (lActualNbOfEventsInt);
    }
  }

  // //////////////////////////////////////////////////////////////////////
  void EventQueue::setStatus (const stdair::EventType::EN_EventType& iType,
                              const stdair::ProgressStatus& iProgressStatus) {

    // Retrieve the ProgressStatus structure corresponding to the
    // given event type
    ProgressStatusMap_T::iterator itProgressStatus =
      _progressStatusMap.find (iType);
    // assert (itProgressStatus != _progressStatusMap.end());
    if (itProgressStatus != _progressStatusMap.end()) {
      // Update the ProgressStatus structure
      itProgressStatus->second = iProgressStatus;
    }
  }

  // //////////////////////////////////////////////////////////////////////
  stdair::ProgressStatus EventQueue::
  getStatus (const stdair::EventType::EN_EventType& iType) const {

    // Retrieve the ProgressStatus structure corresponding to the
    // given event type
    ProgressStatusMap_T::const_iterator itProgressStatus =
      _progressStatusMap.find (iType);
    if (itProgressStatus != _progressStatusMap.end()) {
      const stdair::ProgressStatus& oProgressStatus = itProgressStatus->second;
      return oProgressStatus;
    }

    return stdair::ProgressStatus();
  }

  // //////////////////////////////////////////////////////////////////////
  stdair::ProgressPercentage_T EventQueue::
  calculateProgress (const stdair::EventType::EN_EventType& iType) const {

    // Retrieve the ProgressStatus structure corresponding to the
    // given event type
    ProgressStatusMap_T::const_iterator itProgressStatus =
      _progressStatusMap.find (iType);
    if (itProgressStatus == _progressStatusMap.end()) {
      //
      STDAIR_LOG_ERROR ("No ProgressStatus structure can be retrieved in the "
                        << "EventQueue: " << display());
      assert (false);
    }

    const stdair::ProgressStatus& lProgressStatus = itProgressStatus->second;
    return lProgressStatus.progress();
  }

  // //////////////////////////////////////////////////////////////////////
  stdair::ProgressStatusSet EventQueue::popEvent (stdair::EventStruct& ioEventStruct) {

    if (_eventList.empty() == true) {
      std::ostringstream oStr;
      oStr << "The event queue '" << describeKey() << "' is empty. "
	   << "No event can be popped.";
      //
      STDAIR_LOG_ERROR (oStr.str());
      throw EventQueueException (oStr.str());
    }

    /**
     * 1. Update the event queue itself.
     */
    // Get an iterator on the first event (sorted by date-time stamps)
    stdair::EventList_T::iterator itEvent = _eventList.begin();

    /**
     * Extract (a copy of) the corresponding Event structure. We make
     * a copy here, as the original EventStruct structure is removed
     * from the list (and erased). Moreover, the resulting EventStruct
     * structure will be returned by this method.
     */
    ioEventStruct = itEvent->second;
    // Retrieve the event type
    const stdair::EventType::EN_EventType& lEventType = ioEventStruct.getEventType();
    stdair::ProgressStatusSet oProgressStatusSet (lEventType);

    // Update the (current number part of the) overall progress status,
    // to account for the event that is being popped out of the event
    // queue.
    ++_progressStatus;

    // Remove the event, which has just been retrieved
    _eventList.erase (itEvent);

    /**
     * 2. Update the progress statuses held by the EventStruct structure.
     *
     * 2.1. Update the progress status specific to the event type (e.g.,
     *      booking request, optimisation notification).
     */

    // Retrieve the progress status specific to that event type
    stdair::ProgressStatus lEventTypeProgressStatus = getStatus (lEventType);

    // Increase the current number of events
    ++lEventTypeProgressStatus;

    // Store back the progress status
    setStatus (lEventType, lEventTypeProgressStatus);

    // Update the progress status of the progress status set, specific to
    // the event type.
    oProgressStatusSet.setTypeSpecificStatus (lEventTypeProgressStatus);

    /**
     * 2.2. Update the overall progress status.
     */
    // Update the overall progress status of the progress status set.
    oProgressStatusSet.setOverallStatus (_progressStatus);

    //
    return oProgressStatusSet;
  }

  // //////////////////////////////////////////////////////////////////////
  bool EventQueue::addEvent (stdair::EventStruct& ioEventStruct) {
    bool insertionSucceeded =
      _eventList.insert (stdair::EventListElement_T (ioEventStruct.getEventTimeStamp(),
						     ioEventStruct)).second;

    /**
     * If the insertion has not been successful, try repeatedly until
     * the insertion becomes successful.
     *
     * The date-time is counted in milliseconds (1e-3 second). Hence,
     * one thousand (1e3) of attempts correspond to 1 second.
     *
     * The check on one thousand (1e3) is made in order to avoid
     * potential infinite loops. In such case, however, an assertion
     * will fail: it is always better that an assertion fails rather
     * than entering an infinite loop.
     */
    const unsigned int idx = 0;
    while (insertionSucceeded == false && idx != 1e3) {
      // Increment the date-time stamp (expressed in milliseconds)
      ioEventStruct.incrementEventTimeStamp();

      // Retry to insert into the event queue
      insertionSucceeded =
        _eventList.insert (stdair::EventListElement_T (ioEventStruct.getEventTimeStamp(),
						       ioEventStruct)).second;
    }
    assert (idx != 1e3);

    return insertionSucceeded;
  }

  // //////////////////////////////////////////////////////////////////////
  bool EventQueue::hasEventDateTime (const stdair::DateTime_T& iDateTime) {

    bool hasSearchEventBeenSucessful = true;

    /**
     * Compute the number of milliseconds between the
     * date-time of the event and DEFAULT_EVENT_OLDEST_DATETIME
     * (as of Feb. 2011, that date is set to Jan. 1, 2010).
     */
    const stdair::Duration_T lDuration =
      iDateTime - stdair::DEFAULT_EVENT_OLDEST_DATETIME;
    const stdair::LongDuration_T lDateTimeStamp =
      lDuration.total_milliseconds();

    // Searches the container for an element with iDateTime as key
    stdair::EventList_T::iterator itEvent =
      _eventList.find (lDateTimeStamp);

    // An iterator to map::end means the specified key has not found in the
    // container.
    if (itEvent == _eventList.end()) {
      hasSearchEventBeenSucessful = false;
    }

    return hasSearchEventBeenSucessful;

  }

}
<|endoftext|>


<commit_before>#include "HE_Vulkan.h"

#include <map>
#include <string>

#include "HE_String.h"

using namespace std::string_literals;

namespace vk
{
	ResultErrorException::ResultErrorException(VkResult e)
		: m_sMessage{ "Vulkan returned error "s + to_string(e) }
	{ }

	ResultErrorException::ResultErrorException(VkResult e, gsl::cstring_span<> sContext)
		: m_sMessage{ HE::Format("Vulkan returned error {0} from: {1}", e, sContext) }
	{ }

	const char* ResultErrorException::what() const
	{
		return m_sMessage.c_str();
	}

	namespace
	{
		template<typename... String>
		void CheckErrorImpl(VkResult result, std::initializer_list<VkResult> results, String... s)
		{
			auto const pError = std::find(begin(results), end(results), result);
			if (pError != end(results))
			{
				throw ResultErrorException{ result, s... };
			}
		}

		template<VkResult... Errors>
		void CheckError(VkResult err)
		{
			if (err != VK_SUCCESS)
			{
				CheckErrorImpl(err, { Errors... });
			}
		}

		template<VkResult... Errors>
		void CheckError(VkResult err, gsl::cstring_span<> sContext)
		{
			if (err != VK_SUCCESS)
			{
				CheckErrorImpl(err, { Errors... }, sContext);
			}
		}
	}

	VkInstanceCreateInfo MakeInstanceCreateInfo(const VkApplicationInfo* pApplicationInfo,
		gsl::span<gsl::czstring<> const> enabledLayerNames,
		gsl::span<gsl::czstring<> const> enabledExtensionNames,
		const void* pNext) noexcept
	{
		VkInstanceCreateInfo ret;
		ret.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
		ret.pNext = pNext;
		ret.flags = 0;
		ret.pApplicationInfo = pApplicationInfo;
		ret.enabledLayerCount = static_cast<uint32_t>(pEnabledLayerNames.size());
		ret.ppEnabledLayerNames = pEnabledLayerNames.size() != 0 ? &*pEnabledLayerNames.begin() : nullptr;
		ret.enabledExtensionCount = static_cast<uint32_t>(pEnabledExtensionNames.size());
		ret.ppEnabledExtensionNames = pEnabledExtensionNames.size() != 0  ? &*pEnabledExtensionNames.begin() : nullptr;

		return ret;
	}

	VkApplicationInfo MakeApplicationInfo(const char* pApplicationName, uint32_t applicationVersion, const void* pNext) noexcept
	{
		VkApplicationInfo ret;
		ret.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
		ret.pNext = pNext;
		ret.pApplicationName = pApplicationName;
		ret.applicationVersion = applicationVersion;
		ret.pEngineName = "HazelEngine";
		ret.engineVersion = VK_MAKE_VERSION(0, 0, 1);
		ret.apiVersion = VK_API_VERSION;

		return ret;
	}

	VkInstance CreateInstance(const VkInstanceCreateInfo& pCreateInfo, const VkAllocationCallbacks* pAllocator)
	{
		VkInstance instance;
		auto const err = vkCreateInstance(&pCreateInfo, pAllocator, &instance);
		CheckError<VK_ERROR_OUT_OF_HOST_MEMORY, VK_ERROR_OUT_OF_DEVICE_MEMORY,
			VK_ERROR_INITIALIZATION_FAILED, VK_ERROR_LAYER_NOT_PRESENT,
			VK_ERROR_EXTENSION_NOT_PRESENT, VK_ERROR_INCOMPATIBLE_DRIVER>(err, "CreateInstance");
		return instance;
	}

	void DestroyInstance(VkInstance instance, const VkAllocationCallbacks* pAllocator) noexcept
	{
		vkDestroyInstance(instance, pAllocator);
	}

	std::vector<VkPhysicalDevice> EnumeratePhysicalDevices(VkInstance instance)
	{
		uint32_t physicalDeviceCount;
		auto const err1 = vkEnumeratePhysicalDevices(instance, &physicalDeviceCount, nullptr);
		CheckError<VK_ERROR_OUT_OF_HOST_MEMORY, VK_ERROR_OUT_OF_DEVICE_MEMORY, VK_ERROR_INITIALIZATION_FAILED>(err1, "EnumeratePhysicalDevices");

		std::vector<VkPhysicalDevice> devices(physicalDeviceCount);
		auto const err2 = vkEnumeratePhysicalDevices(instance, &physicalDeviceCount, devices.data());
		CheckError<VK_ERROR_OUT_OF_HOST_MEMORY, VK_ERROR_OUT_OF_DEVICE_MEMORY, VK_ERROR_INITIALIZATION_FAILED>(err2, "EnumeratePhysicalDevices");

		return devices;
	}

	VkPhysicalDeviceProperties GetPhysicalDeviceProperties(VkPhysicalDevice physicalDevice) noexcept
	{
		VkPhysicalDeviceProperties props;
		vkGetPhysicalDeviceProperties(physicalDevice, &props);
		return props;
	}

	std::vector<VkQueueFamilyProperties> GetPhysicalDeviceQueueFamilyProperties(VkPhysicalDevice physicalDevice) noexcept
	{
		uint32_t physicalDeviceCount;
		vkGetPhysicalDeviceQueueFamilyProperties(physicalDevice, &physicalDeviceCount, nullptr);

		std::vector<VkQueueFamilyProperties> deviceQueueFamilyProperties(physicalDeviceCount);
		vkGetPhysicalDeviceQueueFamilyProperties(physicalDevice, &physicalDeviceCount, deviceQueueFamilyProperties.data());

		return deviceQueueFamilyProperties;
	}

	VkDeviceCreateInfo MakeDeviceCreateInfo( gsl::span<const VkDeviceQueueCreateInfo> queueCreateInfos,
		gsl::span<char const* const> enabledLayerNames,
		gsl::span<char const* const> enabledExtensionNames,
		VkPhysicalDeviceFeatures const& enabledFeatures,
		const void* pNext
		) noexcept
	{
		VkDeviceCreateInfo ret;
		ret.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
		ret.pNext = pNext;
		ret.flags = 0;
		ret.queueCreateInfoCount = static_cast<uint32_t>(queueCreateInfos.size());
		ret.pQueueCreateInfos = queueCreateInfos.size() != 0 ? &*queueCreateInfos.begin() : nullptr;
		ret.enabledLayerCount = static_cast<uint32_t>(enabledLayerNames.size());
		ret.ppEnabledLayerNames = enabledLayerNames.size() != 0 ? &*enabledLayerNames.begin() : nullptr;
		ret.enabledExtensionCount = static_cast<uint32_t>(enabledExtensionNames.size());
		ret.ppEnabledExtensionNames = enabledExtensionNames.size() != 0 ? &*enabledExtensionNames.begin() : nullptr;
		ret.pEnabledFeatures = &enabledFeatures;

		return ret;
	}

	VkDevice CreateDevice(VkPhysicalDevice physicalDevice, const VkDeviceCreateInfo& createInfo, const VkAllocationCallbacks* pAllocator)
	{
		VkDevice device;

		auto const err = vkCreateDevice(physicalDevice, &createInfo, pAllocator, &device);
		CheckError<VK_ERROR_OUT_OF_HOST_MEMORY, VK_ERROR_OUT_OF_DEVICE_MEMORY,
			VK_ERROR_INITIALIZATION_FAILED, VK_ERROR_LAYER_NOT_PRESENT,
			VK_ERROR_EXTENSION_NOT_PRESENT, VK_ERROR_FEATURE_NOT_PRESENT,
			VK_ERROR_TOO_MANY_OBJECTS, VK_ERROR_DEVICE_LOST>(err);

		return device;
	}

	void DestroyDevice(VkDevice device, const VkAllocationCallbacks* pAllocator) noexcept
	{
		vkDestroyDevice(device, pAllocator);
	}

	void DeviceWaitIdle(VkDevice device)
	{
		auto const err = vkDeviceWaitIdle(device);
		CheckError<VK_ERROR_OUT_OF_HOST_MEMORY, VK_ERROR_OUT_OF_DEVICE_MEMORY,
			VK_ERROR_DEVICE_LOST>(err);
	}

	namespace PhysicalDeviceType
	{
		namespace
		{
			std::map<VkPhysicalDeviceType, std::string> const s_sPhysicalDeviceTypes{
				{VK_PHYSICAL_DEVICE_TYPE_OTHER, "Other"},
				{VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU, "Integrated GPU"},
				{VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU, "Discrete GPU"},
				{VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU, "Virtual GPU"},
				{VK_PHYSICAL_DEVICE_TYPE_CPU, "CPU"}
			};
		}

		gsl::cstring_span<> String(VkPhysicalDeviceType e)
		{
			return s_sPhysicalDeviceTypes.at(e);
		}
	}
}

std::string to_string(VkPhysicalDeviceType e) { auto const s = vk::PhysicalDeviceType::String(e); return{ s.begin(), s.end() }; }<commit_msg>~ Forgot to commit one line in the previous commit = More readability<commit_after>#include "HE_Vulkan.h"

#include <map>
#include <string>

#include "HE_String.h"

using namespace std::string_literals;

namespace vk
{
	ResultErrorException::ResultErrorException(VkResult e)
		: m_sMessage{ "Vulkan returned error "s + to_string(e) }
	{ }

	ResultErrorException::ResultErrorException(VkResult e, gsl::cstring_span<> sContext)
		: m_sMessage{ HE::Format("Vulkan returned error {0} from: {1}", e, sContext) }
	{ }

	const char* ResultErrorException::what() const
	{
		return m_sMessage.c_str();
	}

	namespace
	{
		template<typename... String>
		void CheckErrorImpl(VkResult result, std::initializer_list<VkResult> results, String... s)
		{
			auto const pError = std::find(begin(results), end(results), result);
			if (pError != end(results))
			{
				throw ResultErrorException{ result, s... };
			}
		}

		template<VkResult... Errors>
		void CheckError(VkResult err)
		{
			if (err != VK_SUCCESS)
			{
				CheckErrorImpl(err, { Errors... });
			}
		}

		template<VkResult... Errors>
		void CheckError(VkResult err, gsl::cstring_span<> sContext)
		{
			if (err != VK_SUCCESS)
			{
				CheckErrorImpl(err, { Errors... }, sContext);
			}
		}
	}

	VkInstanceCreateInfo MakeInstanceCreateInfo(const VkApplicationInfo* pApplicationInfo,
		gsl::span<gsl::czstring<> const> enabledLayerNames,
		gsl::span<gsl::czstring<> const> enabledExtensionNames,
		const void* pNext) noexcept
	{
		VkInstanceCreateInfo ret;
		ret.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
		ret.pNext = pNext;
		ret.flags = 0;
		ret.pApplicationInfo = pApplicationInfo;
		ret.enabledLayerCount = gsl::narrow_cast<uint32_t>(enabledLayerNames.size());
		ret.ppEnabledLayerNames = enabledLayerNames.data();
		ret.enabledExtensionCount = gsl::narrow_cast<uint32_t>(enabledExtensionNames.size());
		ret.ppEnabledExtensionNames = enabledExtensionNames.data();

		return ret;
	}

	VkApplicationInfo MakeApplicationInfo(gsl::czstring<> pApplicationName, uint32_t applicationVersion, const void* pNext) noexcept
	{
		VkApplicationInfo ret;
		ret.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
		ret.pNext = pNext;
		ret.pApplicationName = pApplicationName;
		ret.applicationVersion = applicationVersion;
		ret.pEngineName = "HazelEngine";
		ret.engineVersion = VK_MAKE_VERSION(0, 0, 1);
		ret.apiVersion = VK_API_VERSION;

		return ret;
	}

	VkInstance CreateInstance(const VkInstanceCreateInfo& pCreateInfo, const VkAllocationCallbacks* pAllocator)
	{
		VkInstance instance;
		auto const err = vkCreateInstance(&pCreateInfo, pAllocator, &instance);
		CheckError<VK_ERROR_OUT_OF_HOST_MEMORY, VK_ERROR_OUT_OF_DEVICE_MEMORY,
			VK_ERROR_INITIALIZATION_FAILED, VK_ERROR_LAYER_NOT_PRESENT,
			VK_ERROR_EXTENSION_NOT_PRESENT, VK_ERROR_INCOMPATIBLE_DRIVER>(err, "CreateInstance");
		return instance;
	}

	void DestroyInstance(VkInstance instance, const VkAllocationCallbacks* pAllocator) noexcept
	{
		vkDestroyInstance(instance, pAllocator);
	}

	std::vector<VkPhysicalDevice> EnumeratePhysicalDevices(VkInstance instance)
	{
		uint32_t physicalDeviceCount;
		auto const err1 = vkEnumeratePhysicalDevices(instance, &physicalDeviceCount, nullptr);
		CheckError<VK_ERROR_OUT_OF_HOST_MEMORY, VK_ERROR_OUT_OF_DEVICE_MEMORY, VK_ERROR_INITIALIZATION_FAILED>(err1, "EnumeratePhysicalDevices");

		std::vector<VkPhysicalDevice> devices(physicalDeviceCount);
		auto const err2 = vkEnumeratePhysicalDevices(instance, &physicalDeviceCount, devices.data());
		CheckError<VK_ERROR_OUT_OF_HOST_MEMORY, VK_ERROR_OUT_OF_DEVICE_MEMORY, VK_ERROR_INITIALIZATION_FAILED>(err2, "EnumeratePhysicalDevices");

		return devices;
	}

	VkPhysicalDeviceProperties GetPhysicalDeviceProperties(VkPhysicalDevice physicalDevice) noexcept
	{
		VkPhysicalDeviceProperties props;
		vkGetPhysicalDeviceProperties(physicalDevice, &props);
		return props;
	}

	std::vector<VkQueueFamilyProperties> GetPhysicalDeviceQueueFamilyProperties(VkPhysicalDevice physicalDevice) noexcept
	{
		uint32_t physicalDeviceCount;
		vkGetPhysicalDeviceQueueFamilyProperties(physicalDevice, &physicalDeviceCount, nullptr);

		std::vector<VkQueueFamilyProperties> deviceQueueFamilyProperties(physicalDeviceCount);
		vkGetPhysicalDeviceQueueFamilyProperties(physicalDevice, &physicalDeviceCount, deviceQueueFamilyProperties.data());

		return deviceQueueFamilyProperties;
	}

	VkDeviceCreateInfo MakeDeviceCreateInfo( gsl::span<const VkDeviceQueueCreateInfo> queueCreateInfos,
		gsl::span<char const* const> enabledLayerNames,
		gsl::span<char const* const> enabledExtensionNames,
		VkPhysicalDeviceFeatures const& enabledFeatures,
		const void* pNext
		) noexcept
	{
		VkDeviceCreateInfo ret;
		ret.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
		ret.pNext = pNext;
		ret.flags = 0;
		ret.queueCreateInfoCount = gsl::narrow_cast<uint32_t>(queueCreateInfos.size());
		ret.pQueueCreateInfos = queueCreateInfos.data();
		ret.enabledLayerCount = gsl::narrow_cast<uint32_t>(enabledLayerNames.size());
		ret.ppEnabledLayerNames = enabledLayerNames.data();
		ret.enabledExtensionCount = gsl::narrow_cast<uint32_t>(enabledExtensionNames.size());
		ret.ppEnabledExtensionNames = enabledExtensionNames.data();
		ret.pEnabledFeatures = &enabledFeatures;

		return ret;
	}

	VkDevice CreateDevice(VkPhysicalDevice physicalDevice, const VkDeviceCreateInfo& createInfo, const VkAllocationCallbacks* pAllocator)
	{
		VkDevice device;

		auto const err = vkCreateDevice(physicalDevice, &createInfo, pAllocator, &device);
		CheckError<VK_ERROR_OUT_OF_HOST_MEMORY, VK_ERROR_OUT_OF_DEVICE_MEMORY,
			VK_ERROR_INITIALIZATION_FAILED, VK_ERROR_LAYER_NOT_PRESENT,
			VK_ERROR_EXTENSION_NOT_PRESENT, VK_ERROR_FEATURE_NOT_PRESENT,
			VK_ERROR_TOO_MANY_OBJECTS, VK_ERROR_DEVICE_LOST>(err);

		return device;
	}

	void DestroyDevice(VkDevice device, const VkAllocationCallbacks* pAllocator) noexcept
	{
		vkDestroyDevice(device, pAllocator);
	}

	void DeviceWaitIdle(VkDevice device)
	{
		auto const err = vkDeviceWaitIdle(device);
		CheckError<VK_ERROR_OUT_OF_HOST_MEMORY, VK_ERROR_OUT_OF_DEVICE_MEMORY,
			VK_ERROR_DEVICE_LOST>(err);
	}

	namespace PhysicalDeviceType
	{
		namespace
		{
			std::map<VkPhysicalDeviceType, std::string> const s_sPhysicalDeviceTypes{
				{VK_PHYSICAL_DEVICE_TYPE_OTHER, "Other"},
				{VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU, "Integrated GPU"},
				{VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU, "Discrete GPU"},
				{VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU, "Virtual GPU"},
				{VK_PHYSICAL_DEVICE_TYPE_CPU, "CPU"}
			};
		}

		gsl::cstring_span<> String(VkPhysicalDeviceType e)
		{
			return s_sPhysicalDeviceTypes.at(e);
		}
	}
}

std::string to_string(VkPhysicalDeviceType e) { auto const s = vk::PhysicalDeviceType::String(e); return{ s.begin(), s.end() }; }<|endoftext|>


<commit_before>#include "abstractgraph.h"

#include <QQuickWindow>
#if (QT_VERSION < QT_VERSION_CHECK(5, 6, 0))
#include <QSGSimpleTextureNode>
#endif

#include <cmath>

void TimelineAxis::acquireResHandle() {
    if (!m_numHandles) {
        xH->init();
        xL->init();
        xW->init();
    }
    m_numHandles++;
}

void TimelineAxis::freeResHandle() {
    if (!(--m_numHandles)) {
        if (xH.unique())
            xH->deinit();
        if (xL.unique())
            xL->deinit();
        if (xW.unique())
            xW->deinit();
    }
}

static int upper_bound64(int begin, int end, const std::vector<GLuint>& dataH,
                         const std::vector<GLuint>& dataL,
                         int stride, uint64_t val)
{
    int count = end - begin;
    while (count > 0) {
        int step = (count / stride ) / 2 * stride;
        uint64_t curValue = ((uint64_t)dataH[begin+step] << 32) + dataL[begin+step];
        if (!(val < curValue)) {
            begin += step + stride;
            count -= step + stride;
        } else {
            count = step;
        }
    }
    return begin;
}

void TimelineAxis::mapEvents() {
    m_dispFirstEvent = std::max(upper_bound64(m_firstEvent, m_lastEvent,
                                         xH->data, xL->data,
                                         1, m_dispStartTime) - 1, 0);
    m_dispLastEvent  = std::max(upper_bound64(m_firstEvent, m_lastEvent,
                                         xH->data, xL->data,
                                         1, m_dispEndTime) - 1, 0);
}

int TimelineAxis::findEventAtTime(qlonglong time) const {
    return upper_bound64(m_dispFirstEvent, m_dispLastEvent+1, xH->data, xL->data,
                         1, time) - 1;
}

qlonglong TimelineAxis::eventStartTime(int id) const {
     return ((uint64_t)xH->data[id] << 32) + xL->data[id];
}

qlonglong TimelineAxis::eventDurationTime(int id) const {
     return (double)xW->data[id] * 1e9;
}

void AbstractGraphData::acquireResHandle() {
    if (!m_numHandles) {
        m_dataFilter->init();
    }
    m_numHandles++;
}

void AbstractGraphData::freeResHandle() {
    if (!(--m_numHandles)) {
        if (m_dataFilter.unique())
            m_dataFilter->deinit();
    }
}

AbstractGraph::AbstractGraph(QQuickItem *parent)
    : QQuickFramebufferObject(parent),  m_renderer(0), m_filtered(true),
      m_filter(0), m_bgcolor("white"),
      m_axis(nullptr), m_data(nullptr), m_numElements(0)
{
#if (QT_VERSION >= QT_VERSION_CHECK(5, 6, 0))
    setMirrorVertically(true);
#endif
    connect(this, &AbstractGraph::numElementsChanged, this, &AbstractGraph::forceupdate);
    connect(this, &QQuickItem::heightChanged, this, &AbstractGraph::forceupdate);
}

#if (QT_VERSION < QT_VERSION_CHECK(5, 6, 0))
QSGNode* AbstractGraph::updatePaintNode(QSGNode *node, QQuickItem::UpdatePaintNodeData *nodeData)
{
    if (!node) {
        node = QQuickFramebufferObject::updatePaintNode(node, nodeData);
        QSGSimpleTextureNode *n = static_cast<QSGSimpleTextureNode *>(node);
        if (n)
            n->setTextureCoordinatesTransform(QSGSimpleTextureNode::MirrorVertically);
        return node;
    }
    return QQuickFramebufferObject::updatePaintNode(node, nodeData);
}
#endif

void AbstractGraph::forceupdate() {
    m_needsUpdating = true;
    update();
}

void AbstractGraph::setAxis(TimelineAxis* axis) {
    if (axis) {
        m_axis = axis;
        connect(m_axis, &TimelineAxis::dispStartTimeChanged, this, &AbstractGraph::forceupdate);
        connect(m_axis, &TimelineAxis::dispEndTimeChanged, this, &AbstractGraph::forceupdate);
    }
}

bool AbstractGraph::isEventFiltered(int id) const {
    return (m_filtered && m_data->dataFilter()->data[id] != m_filter);
}

uint AbstractGraph::eventFilter(int id) const {
    return (m_filtered ? m_filter : m_data->dataFilter()->data[id]);
}

AbstractGraph::range_iterator::range_iterator(AbstractGraph* bg, uint64_t begin,
                                         uint64_t duration)
    : ptr(bg), end(begin+duration)
{
    curElement = upper_bound64(ptr->m_axis->m_dispFirstEvent,
                               ptr->m_axis->m_dispLastEvent,
                               ptr->m_axis->xH->data, ptr->m_axis->xL->data,
                               1, begin) - 1;
    operator++();
	curElement = std::max(curElement, 0);
    if ( ((uint64_t)ptr->m_axis->xH->data[curElement] << 32) \
         + ptr->m_axis->xL->data[curElement] < begin) curElement = -1;
}

int AbstractGraph::range_iterator::operator++() {
    if (curElement == -1) return -1;
    do {
		if (curElement == ptr->m_axis->m_dispLastEvent) {
			curElement = -1;
			break;
		}
        ++curElement;
        uint64_t elementEnd = ((uint64_t)ptr->m_axis->xH->data[curElement] << 32) \
                              + ptr->m_axis->xL->data[curElement] \
                              + ptr->m_axis->xW->data[curElement] * (double)1e9;
        if (elementEnd > end) {
            curElement = -1;
            break;
        }
    } while (ptr->m_filtered && ptr->m_data->dataFilter()->data[curElement] != ptr->m_filter);
    return curElement;
}

AbstractGraphRenderer::AbstractGraphRenderer(AbstractGraph* item)
    : m_item(item),
      m_axisCopy(item->m_axis), m_dataCopy(item->m_data),
      m_win(item->window())
{
    if (m_axisCopy) {
        m_axisCopy->acquireResHandle();
    }
    if (m_dataCopy) {
        m_dataCopy->acquireResHandle();
    }
    item->m_needsUpdating = true;
}

AbstractGraphRenderer::~AbstractGraphRenderer() {
    m_axisCopy->freeResHandle();
    m_dataCopy->freeResHandle();
}

void AbstractGraphRenderer::synchronize(QQuickFramebufferObject* item) {
    AbstractGraph* i = static_cast<AbstractGraph*>(item);
    if (i->m_ignoreUpdates) return;
    if (!i->m_needsUpdating || !i->m_axis || !i->m_data) return;

    // Prepare texture buffers if needed
    if (m_axisCopy != i->m_axis) {
        if (m_axisCopy) m_axisCopy->freeResHandle();
        m_axisCopy = i->m_axis;
        m_axisCopy->acquireResHandle();
    }
    if (m_dataCopy != i->m_data) {
        if (m_dataCopy) m_dataCopy->freeResHandle();
        m_dataCopy = i->m_data;
        m_dataCopy->acquireResHandle();
    }

    m_width = i->width();
    m_height = i->height();

    m_filteredCopy = i->m_filtered;
    m_numElementsCopy = i->m_numElements;
    m_filterCopy = i->m_filter;
    m_bgcolorCopy = i->m_bgcolor;

    m_dispStartTimeCopy = i->m_axis->dispStartTime();
    m_dispEndTimeCopy = i->m_axis->dispEndTime();
    m_dispFirstEventCopy = i->m_axis->m_dispFirstEvent;
    m_dispLastEventCopy = i->m_axis->m_dispLastEvent;

    synchronizeAfter(item);
    m_needsUpdating = true;
    i->m_needsUpdating = false;
}
<commit_msg>Handle axis change correctly<commit_after>#include "abstractgraph.h"

#include <QQuickWindow>
#if (QT_VERSION < QT_VERSION_CHECK(5, 6, 0))
#include <QSGSimpleTextureNode>
#endif

#include <cmath>

void TimelineAxis::acquireResHandle() {
    if (!m_numHandles) {
        xH->init();
        xL->init();
        xW->init();
    }
    m_numHandles++;
}

void TimelineAxis::freeResHandle() {
    if (!(--m_numHandles)) {
        if (xH.unique())
            xH->deinit();
        if (xL.unique())
            xL->deinit();
        if (xW.unique())
            xW->deinit();
    }
}

static int upper_bound64(int begin, int end, const std::vector<GLuint>& dataH,
                         const std::vector<GLuint>& dataL,
                         int stride, uint64_t val)
{
    int count = end - begin;
    while (count > 0) {
        int step = (count / stride ) / 2 * stride;
        uint64_t curValue = ((uint64_t)dataH[begin+step] << 32) + dataL[begin+step];
        if (!(val < curValue)) {
            begin += step + stride;
            count -= step + stride;
        } else {
            count = step;
        }
    }
    return begin;
}

void TimelineAxis::mapEvents() {
    m_dispFirstEvent = std::max(upper_bound64(m_firstEvent, m_lastEvent,
                                         xH->data, xL->data,
                                         1, m_dispStartTime) - 1, 0);
    m_dispLastEvent  = std::max(upper_bound64(m_firstEvent, m_lastEvent,
                                         xH->data, xL->data,
                                         1, m_dispEndTime) - 1, 0);
}

int TimelineAxis::findEventAtTime(qlonglong time) const {
    return upper_bound64(m_dispFirstEvent, m_dispLastEvent+1, xH->data, xL->data,
                         1, time) - 1;
}

qlonglong TimelineAxis::eventStartTime(int id) const {
     return ((uint64_t)xH->data[id] << 32) + xL->data[id];
}

qlonglong TimelineAxis::eventDurationTime(int id) const {
     return (double)xW->data[id] * 1e9;
}

void AbstractGraphData::acquireResHandle() {
    if (!m_numHandles) {
        m_dataFilter->init();
    }
    m_numHandles++;
}

void AbstractGraphData::freeResHandle() {
    if (!(--m_numHandles)) {
        if (m_dataFilter.unique())
            m_dataFilter->deinit();
    }
}

AbstractGraph::AbstractGraph(QQuickItem *parent)
    : QQuickFramebufferObject(parent),  m_renderer(0), m_filtered(true),
      m_filter(0), m_bgcolor("white"),
      m_axis(nullptr), m_data(nullptr), m_numElements(0)
{
#if (QT_VERSION >= QT_VERSION_CHECK(5, 6, 0))
    setMirrorVertically(true);
#endif
    connect(this, &AbstractGraph::numElementsChanged, this, &AbstractGraph::forceupdate);
    connect(this, &QQuickItem::heightChanged, this, &AbstractGraph::forceupdate);
}

#if (QT_VERSION < QT_VERSION_CHECK(5, 6, 0))
QSGNode* AbstractGraph::updatePaintNode(QSGNode *node, QQuickItem::UpdatePaintNodeData *nodeData)
{
    if (!node) {
        node = QQuickFramebufferObject::updatePaintNode(node, nodeData);
        QSGSimpleTextureNode *n = static_cast<QSGSimpleTextureNode *>(node);
        if (n)
            n->setTextureCoordinatesTransform(QSGSimpleTextureNode::MirrorVertically);
        return node;
    }
    return QQuickFramebufferObject::updatePaintNode(node, nodeData);
}
#endif

void AbstractGraph::forceupdate() {
    m_needsUpdating = true;
    update();
}

void AbstractGraph::setAxis(TimelineAxis* axis) {
    if (axis) {
        m_axis = axis;
        connect(m_axis, &TimelineAxis::dispStartTimeChanged, this, &AbstractGraph::forceupdate);
        connect(m_axis, &TimelineAxis::dispEndTimeChanged, this, &AbstractGraph::forceupdate);
        emit axisChanged();
    }
}

bool AbstractGraph::isEventFiltered(int id) const {
    return (m_filtered && m_data->dataFilter()->data[id] != m_filter);
}

uint AbstractGraph::eventFilter(int id) const {
    return (m_filtered ? m_filter : m_data->dataFilter()->data[id]);
}

AbstractGraph::range_iterator::range_iterator(AbstractGraph* bg, uint64_t begin,
                                         uint64_t duration)
    : ptr(bg), end(begin+duration)
{
    curElement = upper_bound64(ptr->m_axis->m_dispFirstEvent,
                               ptr->m_axis->m_dispLastEvent,
                               ptr->m_axis->xH->data, ptr->m_axis->xL->data,
                               1, begin) - 1;
    operator++();
	curElement = std::max(curElement, 0);
    if ( ((uint64_t)ptr->m_axis->xH->data[curElement] << 32) \
         + ptr->m_axis->xL->data[curElement] < begin) curElement = -1;
}

int AbstractGraph::range_iterator::operator++() {
    if (curElement == -1) return -1;
    do {
		if (curElement == ptr->m_axis->m_dispLastEvent) {
			curElement = -1;
			break;
		}
        ++curElement;
        uint64_t elementEnd = ((uint64_t)ptr->m_axis->xH->data[curElement] << 32) \
                              + ptr->m_axis->xL->data[curElement] \
                              + ptr->m_axis->xW->data[curElement] * (double)1e9;
        if (elementEnd > end) {
            curElement = -1;
            break;
        }
    } while (ptr->m_filtered && ptr->m_data->dataFilter()->data[curElement] != ptr->m_filter);
    return curElement;
}

AbstractGraphRenderer::AbstractGraphRenderer(AbstractGraph* item)
    : m_item(item),
      m_axisCopy(item->m_axis), m_dataCopy(item->m_data),
      m_win(item->window())
{
    if (m_axisCopy) {
        m_axisCopy->acquireResHandle();
    }
    if (m_dataCopy) {
        m_dataCopy->acquireResHandle();
    }
    item->m_needsUpdating = true;
}

AbstractGraphRenderer::~AbstractGraphRenderer() {
    m_axisCopy->freeResHandle();
    m_dataCopy->freeResHandle();
}

void AbstractGraphRenderer::synchronize(QQuickFramebufferObject* item) {
    AbstractGraph* i = static_cast<AbstractGraph*>(item);
    if (i->m_ignoreUpdates) return;
    if (!i->m_needsUpdating || !i->m_axis || !i->m_data) return;

    // Prepare texture buffers if needed
    if (m_axisCopy != i->m_axis) {
        if (m_axisCopy) m_axisCopy->freeResHandle();
        m_axisCopy = i->m_axis;
        m_axisCopy->acquireResHandle();
    }
    if (m_dataCopy != i->m_data) {
        if (m_dataCopy) m_dataCopy->freeResHandle();
        m_dataCopy = i->m_data;
        m_dataCopy->acquireResHandle();
    }

    m_width = i->width();
    m_height = i->height();

    m_filteredCopy = i->m_filtered;
    m_numElementsCopy = i->m_numElements;
    m_filterCopy = i->m_filter;
    m_bgcolorCopy = i->m_bgcolor;

    m_dispStartTimeCopy = i->m_axis->dispStartTime();
    m_dispEndTimeCopy = i->m_axis->dispEndTime();
    m_dispFirstEventCopy = i->m_axis->m_dispFirstEvent;
    m_dispLastEventCopy = i->m_axis->m_dispLastEvent;

    synchronizeAfter(item);
    m_needsUpdating = true;
    i->m_needsUpdating = false;
}
<|endoftext|>


<commit_before>/*******************************************************************************
 * Copyright (c) 2014, 2016  IBM Corporation and others
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 *******************************************************************************/

#ifndef BasicLocalizer_hpp
#define BasicLocalizer_hpp

#include <iostream>
#include <string>

#include <boost/circular_buffer.hpp>

#include "StreamLocalizer.hpp"
#include "StreamParticleFilter.hpp"

#include "PoseRandomWalker.hpp"
#include "WeakPoseRandomWalker.hpp"

#include "GridResampler.hpp"
#include "StatusInitializerStub.hpp"
#include "StatusInitializerImpl.hpp"

#include "DataStore.hpp"
#include "DataStoreImpl.hpp"

#include "OrientationMeterAverage.hpp"
#include "PedometerWalkingState.hpp"

#include "GaussianProcessLDPLMultiModel.hpp"

// for pose random walker in building
#include "Building.hpp"
#include "RandomWalker.hpp"
#include "RandomWalkerMotion.hpp"
#include "SystemModelInBuilding.hpp"

#include "BeaconFilterChain.hpp"
#include "CleansingBeaconFilter.hpp"
#include "StrongestBeaconFilter.hpp"

#include "ObservationDependentInitializer.hpp"
#include "MetropolisSampler.hpp"

#include "SerializeUtils.hpp"
#include "LatLngConverter.hpp"

#define N_SMOOTH_MAX 10

namespace loc {

    class BasicLocalizerParameters;
    class BasicLocalizerOptions;
    class BasicLocalizer;

    typedef struct {
        BasicLocalizer* localizer;
    } UserData;

    typedef enum {
        ONESHOT,
        RANDOM_WALK,
        RANDOM_WALK_ACC,
        RANDOM_WALK_ACC_ATT,
        WEAK_POSE_RANDOM_WALKER
    } LocalizeMode;

    /*
    typedef enum {
        UNKNOWN,
        LOCATING,
        TRACKING
    } LocalizeState;
    */

    typedef enum {
        NORMAL, TDIST
    } NormalFunction;

    typedef enum {
        SMOOTH_LOCATION,
        SMOOTH_RSSI
    } SmoothType;

    typedef enum{
        RAW_AVERAGE,
        TRANSFORMED_AVERAGE
    } OrientationMeterType;

    class LocalHeadingBuffer{
    protected:
        boost::circular_buffer<LocalHeading> buffer_;
        std::mutex mtx_;
    public:
        LocalHeadingBuffer(size_t);
        ~LocalHeadingBuffer() = default;
        LocalHeadingBuffer(const LocalHeadingBuffer&);
        LocalHeadingBuffer& operator=(const LocalHeadingBuffer&);
        void push_back(const LocalHeading&);
        LocalHeading& back();
        size_t size();
    };

    struct UserDataBridge{
        UserData* userData;
        void (*functionCalledAfterUpdateWithPtr)(void*, Status*) = NULL;
        BasicLocalizer* basicLocalizer;
    };

    class BasicLocalizerParameters{
    public:
        int nStates = 1000;
        double alphaWeaken = 0.3;
        int nSmooth = 10;
        int nSmoothTracking = 1;
        SmoothType smoothType = SMOOTH_LOCATION;
        LocalizeMode localizeMode = ONESHOT;

        double effectiveSampleSizeThreshold = 1000;
        int nStrongest = 10;
        bool enablesFloorUpdate = true;

        double walkDetectSigmaThreshold = 0.6;
        double meanVelocity = 1.0;
        double stdVelocity = 0.3;
        double diffusionVelocity = 0.1;
        double minVelocity = 0.1;
        double maxVelocity = 1.5;

        double stdRssiBias = 2.0;
        double diffusionRssiBias = 0.2;
        double stdOrientation = 3.0;
        double diffusionOrientationBias = 10;

        double angularVelocityLimit = 30;
        // Parametes for PoseRandomWalker
        bool doesUpdateWhenStopping = false;

        double maxIncidenceAngle = 45;
        double weightDecayHalfLife = 5; // 0.87055056329; // this^5 = 0.5

        // Parameters for RandomWalkerMotion and WeakPoseRandomWalker
        double sigmaStop = 0.1;
        double sigmaMove = 1.0;

        // Parameters for SystemModelInBuilding
        double velocityRateFloor = 1.0;
        double velocityRateElevator = 0.5;
        double velocityRateStair = 0.5;
        double velocityRateEscalator = 0.5;
        double relativeVelocityEscalator = 0.4; // m/s

        // Parameters for WeakPoseRandomWalker
        double probabilityOrientationBiasJump = 0.1;
        double poseRandomWalkRate = 1.0;
        double randomWalkRate = 0.2;
        double probabilityBackwardMove = 0.0;

        int nBurnIn = 1000;
        int burnInRadius2D = 10;
        int burnInInterval = 1;
        InitType burnInInitType = INIT_WITH_SAMPLE_LOCATIONS;

        double mixProba = 0.000;
        double rejectDistance = 5;
        double rejectFloorDifference = 0.99;
        int nBeaconsMinimum = 3;

        Location locLB{0.5, 0.5, 1e-6, 1e-6};

        bool usesAltimeterForFloorTransCheck = false;
        double coeffDiffFloorStdev = 5.0;

        OrientationMeterType orientationMeterType = RAW_AVERAGE;

        // parameter objects
        PoseProperty::Ptr poseProperty = std::make_shared<PoseProperty>();
        StateProperty::Ptr stateProperty = std::make_shared<StateProperty>();

        StreamParticleFilter::FloorTransitionParameters::Ptr pfFloorTransParams = std::make_shared<StreamParticleFilter::FloorTransitionParameters>();
        LocationStatusMonitorParameters::Ptr locationStatusMonitorParameters = std::make_shared<LocationStatusMonitorParameters>();
        SystemModelInBuildingProperty::Ptr prwBuildingProperty = std::make_shared<SystemModelInBuildingProperty>();

    protected:
        double meanRssiBias_ = 0.0;
        double minRssiBias_ = -10;
        double maxRssiBias_ = 10;

        double headingConfidenceForOrientationInit_ = 0.0;

    public:
        template<class Archive>
        void serialize(Archive & ar, std::uint32_t const version)
        {
            if (0 <= version) {
                ar(CEREAL_NVP(nStates));
                ar(CEREAL_NVP(alphaWeaken));
                ar(CEREAL_NVP(nSmooth));
                ar(CEREAL_NVP(nSmoothTracking));

                ar(CEREAL_NVP(smoothType));
                ar(CEREAL_NVP(localizeMode));

                ar(CEREAL_NVP(effectiveSampleSizeThreshold));
                ar(CEREAL_NVP(nStrongest));
                ar(CEREAL_NVP(enablesFloorUpdate));

                ar(CEREAL_NVP(walkDetectSigmaThreshold));
                ar(CEREAL_NVP(meanVelocity));
                ar(CEREAL_NVP(stdVelocity));
                ar(CEREAL_NVP(diffusionVelocity));
                ar(CEREAL_NVP(minVelocity));
                ar(CEREAL_NVP(maxVelocity));

                ar(CEREAL_NVP(stdRssiBias));
                ar(CEREAL_NVP(diffusionRssiBias));
                ar(CEREAL_NVP(stdOrientation));
                ar(CEREAL_NVP(diffusionOrientationBias));

                ar(CEREAL_NVP(angularVelocityLimit));

                // Parametes for PoseRandomWalker
                ar(CEREAL_NVP(doesUpdateWhenStopping));
                ar(CEREAL_NVP(maxIncidenceAngle));
                ar(CEREAL_NVP(weightDecayHalfLife));

                // Parameters for RandomWalkerMotion and WeakPoseRandomWalker
                ar(CEREAL_NVP(sigmaStop));
                ar(CEREAL_NVP(sigmaMove));

                // Parameters for SystemModelInBuilding
                ar(CEREAL_NVP(velocityRateFloor));
                ar(CEREAL_NVP(velocityRateElevator));
                ar(CEREAL_NVP(velocityRateStair));
                ar(CEREAL_NVP(velocityRateEscalator));
                ar(CEREAL_NVP(relativeVelocityEscalator));

                // Parameters for WeakPoseRandomWalker
                ar(CEREAL_NVP(probabilityOrientationBiasJump));
                ar(CEREAL_NVP(poseRandomWalkRate));
                ar(CEREAL_NVP(randomWalkRate));
                ar(CEREAL_NVP(probabilityBackwardMove));

                ar(CEREAL_NVP(nBurnIn));
                ar(CEREAL_NVP(burnInRadius2D));
                ar(CEREAL_NVP(burnInInterval));
                ar(CEREAL_NVP(burnInInitType));

                ar(CEREAL_NVP(mixProba));
                ar(CEREAL_NVP(rejectDistance));
                ar(CEREAL_NVP(rejectFloorDifference));
                ar(CEREAL_NVP(nBeaconsMinimum));

                ar(CEREAL_NVP(locLB));

                ar(CEREAL_NVP(usesAltimeterForFloorTransCheck));
                ar(CEREAL_NVP(coeffDiffFloorStdev));

                ar(CEREAL_NVP(orientationMeterType));

                // parameter objects
                ar(CEREAL_NVP(*poseProperty));
                ar(CEREAL_NVP(*stateProperty));

                ar(CEREAL_NVP(*pfFloorTransParams));
                ar(CEREAL_NVP(*locationStatusMonitorParameters));
                ar(CEREAL_NVP(*prwBuildingProperty));

                // protected
                ar(CEREAL_NVP(meanRssiBias_));
                ar(CEREAL_NVP(minRssiBias_));
                ar(CEREAL_NVP(maxRssiBias_));
                ar(CEREAL_NVP(headingConfidenceForOrientationInit_));
            }
        }

    };

    class BasicLocalizerOptions{
    public:
        GPType gpType = GPNORMAL;
    };

    class BasicLocalizer: public StreamLocalizer, public BasicLocalizerParameters{

    private:
        std::shared_ptr<StreamParticleFilter> mLocalizer;
        std::shared_ptr<GaussianProcessLDPLMultiModel<State, Beacons>> deserializedModel;
        UserData userData;
        double isReady = false;

        void (*mFunctionCalledAfterUpdate)(Status*) = NULL;
        void (*mFunctionCalledAfterUpdate2)(void*, Status*) = NULL;
        void (*mFunctionCalledToLog)(void*, std::string) = NULL;
        void *mUserData = NULL;
        void *mUserDataToLog = NULL;

        UserDataBridge userDataBridge;
        void *mUserDataBridge = NULL;

        //std::shared_ptr<loc::Status> mResult;
        std::shared_ptr<Status> mTrackedStatus;

        std::vector<loc::State> status_list[N_SMOOTH_MAX];
        std::vector<loc::Beacon> beacons_list[N_SMOOTH_MAX];

        int smooth_count = 0;
        double mEstimatedRssiBias = 0;

        bool isTrackingLocalizer() {
            switch(localizeMode) {
                case ONESHOT:
                    return false;
                case RANDOM_WALK:
                case RANDOM_WALK_ACC:
                case RANDOM_WALK_ACC_ATT:
                case WEAK_POSE_RANDOM_WALKER:
                default:
                    return true;
            }
        };

        void updateStateProperty();

        Anchor anchor;
        LatLngConverter::Ptr latLngConverter_ = LatLngConverter::Ptr(new LatLngConverter());

        LocalHeadingBuffer mLocalHeadingBuffer = LocalHeadingBuffer(10); // buffer size 10 is not important.

        Status::LocationStatus mLocationStatus = Status::UNKNOWN;

    public:
        BasicLocalizer();
        ~BasicLocalizer();

        BasicLocalizer(const BasicLocalizerParameters& params): BasicLocalizerParameters(params){
            this->meanRssiBias(meanRssiBias_);
            this->minRssiBias(minRssiBias_);
            this->maxRssiBias(maxRssiBias_);
        }

        bool isVerboseLocalizer = false;

        std::shared_ptr<DataStoreImpl> dataStore;

        void normalFunction(NormalFunction type, double option);
        void meanRssiBias(double b);
        void maxRssiBias(double b);
        void minRssiBias(double b);
        /*
         void angularVelocityLimit(double a);
         */
        double estimatedRssiBias();

        bool forceTraining = false;
        BasicLocalizerOptions basicLocalizerOptions;

        OrientationMeterAverageParameters orientationMeterAverageParameters;
        std::shared_ptr<OrientationMeter> orientationMeter;

        PedometerWalkingStateParameters pedometerWSParams;
        std::shared_ptr<Pedometer> pedometer;

        // parameter objects
        PoseRandomWalkerProperty::Ptr poseRandomWalkerProperty = std::make_shared<PoseRandomWalkerProperty>();
        WeakPoseRandomWalkerProperty::Ptr wPRWproperty = std::make_shared<WeakPoseRandomWalkerProperty>();

        // system models
        std::shared_ptr<RandomWalker<State, SystemModelInput>>randomWalker;
        std::shared_ptr<PoseRandomWalker>poseRandomWalker;
        std::shared_ptr<PoseRandomWalkerInBuilding> poseRandomWalkerInBuilding;

        std::shared_ptr<Resampler<State>> resampler;

        std::shared_ptr<StatusInitializerImpl> statusInitializer;

        std::shared_ptr<StrongestBeaconFilter> beaconFilter;

        loc::Pose stdevPose;

        std::shared_ptr<MetropolisSampler<State, Beacons>> obsDepInitializer;

        MetropolisSampler<State, Beacons>::Parameters msParams;

        LatLngConverter::Ptr latLngConverter();

        StreamLocalizer& updateHandler(void (*functionCalledAfterUpdate)(Status*)) override;
        StreamLocalizer& updateHandler(void (*functionCalledAfterUpdate)(void*, Status*), void* inUserData) override;

        StreamLocalizer& logHandler(void (*functionCalledToLog)(void*, std::string), void* inUserData);

        StreamLocalizer& putAttitude(const Attitude attitude) override;
        StreamLocalizer& putAcceleration(const Acceleration acceleration) override;
        StreamLocalizer& putBeacons(const Beacons beacons) override;
        // StreamLocalizer& putWiFiAPs(const WiFiAPs wifiaps) override;
        StreamLocalizer& putLocalHeading(const LocalHeading heading) override;
        StreamLocalizer& putHeading(const Heading heading);
        StreamLocalizer& putAltimeter(const Altimeter altimeter) override;
        Status* getStatus() override;

        bool resetStatus() override;
        bool resetStatus(Pose pose) override;
        bool resetStatus(Pose meanPose, Pose stdevPose) override;
        bool resetStatus(Pose meanPose, Pose stdevPose, double rateContami) override;
        bool resetStatus(const Beacons& beacons) override;
        bool resetStatus(const Location& location, const Beacons& beacons) override;

        BasicLocalizer& setModel(std::string modelPath, std::string workingDir);

        bool tracksOrientation(){
            switch(localizeMode) {
                case ONESHOT:
                case RANDOM_WALK:
                case RANDOM_WALK_ACC:
                    return false;
                case RANDOM_WALK_ACC_ATT:
                case WEAK_POSE_RANDOM_WALKER:
                    return true;
                default:
                    return false;
            }
        };

        std::shared_ptr<GaussianProcessLDPLMultiModel<State, Beacons>> observationModel() const{
            return deserializedModel;
        };

        // for orientation initialization
        void headingConfidenceForOrientationInit(double confidence);

        void updateLocationStatus(Status*);
        void overwriteLocationStatus(Status::LocationStatus);

    };
}

// assign version
CEREAL_CLASS_VERSION(loc::BasicLocalizerParameters, 0);
#endif /* BasicLocalizerBuilder_hpp */
<commit_msg>specify enum and int for localization mode<commit_after>/*******************************************************************************
 * Copyright (c) 2014, 2016  IBM Corporation and others
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 *******************************************************************************/

#ifndef BasicLocalizer_hpp
#define BasicLocalizer_hpp

#include <iostream>
#include <string>

#include <boost/circular_buffer.hpp>

#include "StreamLocalizer.hpp"
#include "StreamParticleFilter.hpp"

#include "PoseRandomWalker.hpp"
#include "WeakPoseRandomWalker.hpp"

#include "GridResampler.hpp"
#include "StatusInitializerStub.hpp"
#include "StatusInitializerImpl.hpp"

#include "DataStore.hpp"
#include "DataStoreImpl.hpp"

#include "OrientationMeterAverage.hpp"
#include "PedometerWalkingState.hpp"

#include "GaussianProcessLDPLMultiModel.hpp"

// for pose random walker in building
#include "Building.hpp"
#include "RandomWalker.hpp"
#include "RandomWalkerMotion.hpp"
#include "SystemModelInBuilding.hpp"

#include "BeaconFilterChain.hpp"
#include "CleansingBeaconFilter.hpp"
#include "StrongestBeaconFilter.hpp"

#include "ObservationDependentInitializer.hpp"
#include "MetropolisSampler.hpp"

#include "SerializeUtils.hpp"
#include "LatLngConverter.hpp"

#define N_SMOOTH_MAX 10

namespace loc {

    class BasicLocalizerParameters;
    class BasicLocalizerOptions;
    class BasicLocalizer;

    typedef struct {
        BasicLocalizer* localizer;
    } UserData;

    typedef enum {
        ONESHOT = 0,
        RANDOM_WALK = 1,
        RANDOM_WALK_ACC = 2,
        RANDOM_WALK_ACC_ATT = 3,
        WEAK_POSE_RANDOM_WALKER = 4
    } LocalizeMode;

    /*
    typedef enum {
        UNKNOWN,
        LOCATING,
        TRACKING
    } LocalizeState;
    */

    typedef enum {
        NORMAL, TDIST
    } NormalFunction;

    typedef enum {
        SMOOTH_LOCATION,
        SMOOTH_RSSI
    } SmoothType;

    typedef enum{
        RAW_AVERAGE,
        TRANSFORMED_AVERAGE
    } OrientationMeterType;

    class LocalHeadingBuffer{
    protected:
        boost::circular_buffer<LocalHeading> buffer_;
        std::mutex mtx_;
    public:
        LocalHeadingBuffer(size_t);
        ~LocalHeadingBuffer() = default;
        LocalHeadingBuffer(const LocalHeadingBuffer&);
        LocalHeadingBuffer& operator=(const LocalHeadingBuffer&);
        void push_back(const LocalHeading&);
        LocalHeading& back();
        size_t size();
    };

    struct UserDataBridge{
        UserData* userData;
        void (*functionCalledAfterUpdateWithPtr)(void*, Status*) = NULL;
        BasicLocalizer* basicLocalizer;
    };

    class BasicLocalizerParameters{
    public:
        int nStates = 1000;
        double alphaWeaken = 0.3;
        int nSmooth = 10;
        int nSmoothTracking = 1;
        SmoothType smoothType = SMOOTH_LOCATION;
        LocalizeMode localizeMode = ONESHOT;

        double effectiveSampleSizeThreshold = 1000;
        int nStrongest = 10;
        bool enablesFloorUpdate = true;

        double walkDetectSigmaThreshold = 0.6;
        double meanVelocity = 1.0;
        double stdVelocity = 0.3;
        double diffusionVelocity = 0.1;
        double minVelocity = 0.1;
        double maxVelocity = 1.5;

        double stdRssiBias = 2.0;
        double diffusionRssiBias = 0.2;
        double stdOrientation = 3.0;
        double diffusionOrientationBias = 10;

        double angularVelocityLimit = 30;
        // Parametes for PoseRandomWalker
        bool doesUpdateWhenStopping = false;

        double maxIncidenceAngle = 45;
        double weightDecayHalfLife = 5; // 0.87055056329; // this^5 = 0.5

        // Parameters for RandomWalkerMotion and WeakPoseRandomWalker
        double sigmaStop = 0.1;
        double sigmaMove = 1.0;

        // Parameters for SystemModelInBuilding
        double velocityRateFloor = 1.0;
        double velocityRateElevator = 0.5;
        double velocityRateStair = 0.5;
        double velocityRateEscalator = 0.5;
        double relativeVelocityEscalator = 0.4; // m/s

        // Parameters for WeakPoseRandomWalker
        double probabilityOrientationBiasJump = 0.1;
        double poseRandomWalkRate = 1.0;
        double randomWalkRate = 0.2;
        double probabilityBackwardMove = 0.0;

        int nBurnIn = 1000;
        int burnInRadius2D = 10;
        int burnInInterval = 1;
        InitType burnInInitType = INIT_WITH_SAMPLE_LOCATIONS;

        double mixProba = 0.000;
        double rejectDistance = 5;
        double rejectFloorDifference = 0.99;
        int nBeaconsMinimum = 3;

        Location locLB{0.5, 0.5, 1e-6, 1e-6};

        bool usesAltimeterForFloorTransCheck = false;
        double coeffDiffFloorStdev = 5.0;

        OrientationMeterType orientationMeterType = RAW_AVERAGE;

        // parameter objects
        PoseProperty::Ptr poseProperty = std::make_shared<PoseProperty>();
        StateProperty::Ptr stateProperty = std::make_shared<StateProperty>();

        StreamParticleFilter::FloorTransitionParameters::Ptr pfFloorTransParams = std::make_shared<StreamParticleFilter::FloorTransitionParameters>();
        LocationStatusMonitorParameters::Ptr locationStatusMonitorParameters = std::make_shared<LocationStatusMonitorParameters>();
        SystemModelInBuildingProperty::Ptr prwBuildingProperty = std::make_shared<SystemModelInBuildingProperty>();

    protected:
        double meanRssiBias_ = 0.0;
        double minRssiBias_ = -10;
        double maxRssiBias_ = 10;

        double headingConfidenceForOrientationInit_ = 0.0;

    public:
        template<class Archive>
        void serialize(Archive & ar, std::uint32_t const version)
        {
            if (0 <= version) {
                ar(CEREAL_NVP(nStates));
                ar(CEREAL_NVP(alphaWeaken));
                ar(CEREAL_NVP(nSmooth));
                ar(CEREAL_NVP(nSmoothTracking));

                ar(CEREAL_NVP(smoothType));
                ar(CEREAL_NVP(localizeMode));

                ar(CEREAL_NVP(effectiveSampleSizeThreshold));
                ar(CEREAL_NVP(nStrongest));
                ar(CEREAL_NVP(enablesFloorUpdate));

                ar(CEREAL_NVP(walkDetectSigmaThreshold));
                ar(CEREAL_NVP(meanVelocity));
                ar(CEREAL_NVP(stdVelocity));
                ar(CEREAL_NVP(diffusionVelocity));
                ar(CEREAL_NVP(minVelocity));
                ar(CEREAL_NVP(maxVelocity));

                ar(CEREAL_NVP(stdRssiBias));
                ar(CEREAL_NVP(diffusionRssiBias));
                ar(CEREAL_NVP(stdOrientation));
                ar(CEREAL_NVP(diffusionOrientationBias));

                ar(CEREAL_NVP(angularVelocityLimit));

                // Parametes for PoseRandomWalker
                ar(CEREAL_NVP(doesUpdateWhenStopping));
                ar(CEREAL_NVP(maxIncidenceAngle));
                ar(CEREAL_NVP(weightDecayHalfLife));

                // Parameters for RandomWalkerMotion and WeakPoseRandomWalker
                ar(CEREAL_NVP(sigmaStop));
                ar(CEREAL_NVP(sigmaMove));

                // Parameters for SystemModelInBuilding
                ar(CEREAL_NVP(velocityRateFloor));
                ar(CEREAL_NVP(velocityRateElevator));
                ar(CEREAL_NVP(velocityRateStair));
                ar(CEREAL_NVP(velocityRateEscalator));
                ar(CEREAL_NVP(relativeVelocityEscalator));

                // Parameters for WeakPoseRandomWalker
                ar(CEREAL_NVP(probabilityOrientationBiasJump));
                ar(CEREAL_NVP(poseRandomWalkRate));
                ar(CEREAL_NVP(randomWalkRate));
                ar(CEREAL_NVP(probabilityBackwardMove));

                ar(CEREAL_NVP(nBurnIn));
                ar(CEREAL_NVP(burnInRadius2D));
                ar(CEREAL_NVP(burnInInterval));
                ar(CEREAL_NVP(burnInInitType));

                ar(CEREAL_NVP(mixProba));
                ar(CEREAL_NVP(rejectDistance));
                ar(CEREAL_NVP(rejectFloorDifference));
                ar(CEREAL_NVP(nBeaconsMinimum));

                ar(CEREAL_NVP(locLB));

                ar(CEREAL_NVP(usesAltimeterForFloorTransCheck));
                ar(CEREAL_NVP(coeffDiffFloorStdev));

                ar(CEREAL_NVP(orientationMeterType));

                // parameter objects
                ar(CEREAL_NVP(*poseProperty));
                ar(CEREAL_NVP(*stateProperty));

                ar(CEREAL_NVP(*pfFloorTransParams));
                ar(CEREAL_NVP(*locationStatusMonitorParameters));
                ar(CEREAL_NVP(*prwBuildingProperty));

                // protected
                ar(CEREAL_NVP(meanRssiBias_));
                ar(CEREAL_NVP(minRssiBias_));
                ar(CEREAL_NVP(maxRssiBias_));
                ar(CEREAL_NVP(headingConfidenceForOrientationInit_));
            }
        }

    };

    class BasicLocalizerOptions{
    public:
        GPType gpType = GPNORMAL;
    };

    class BasicLocalizer: public StreamLocalizer, public BasicLocalizerParameters{

    private:
        std::shared_ptr<StreamParticleFilter> mLocalizer;
        std::shared_ptr<GaussianProcessLDPLMultiModel<State, Beacons>> deserializedModel;
        UserData userData;
        double isReady = false;

        void (*mFunctionCalledAfterUpdate)(Status*) = NULL;
        void (*mFunctionCalledAfterUpdate2)(void*, Status*) = NULL;
        void (*mFunctionCalledToLog)(void*, std::string) = NULL;
        void *mUserData = NULL;
        void *mUserDataToLog = NULL;

        UserDataBridge userDataBridge;
        void *mUserDataBridge = NULL;

        //std::shared_ptr<loc::Status> mResult;
        std::shared_ptr<Status> mTrackedStatus;

        std::vector<loc::State> status_list[N_SMOOTH_MAX];
        std::vector<loc::Beacon> beacons_list[N_SMOOTH_MAX];

        int smooth_count = 0;
        double mEstimatedRssiBias = 0;

        bool isTrackingLocalizer() {
            switch(localizeMode) {
                case ONESHOT:
                    return false;
                case RANDOM_WALK:
                case RANDOM_WALK_ACC:
                case RANDOM_WALK_ACC_ATT:
                case WEAK_POSE_RANDOM_WALKER:
                default:
                    return true;
            }
        };

        void updateStateProperty();

        Anchor anchor;
        LatLngConverter::Ptr latLngConverter_ = LatLngConverter::Ptr(new LatLngConverter());

        LocalHeadingBuffer mLocalHeadingBuffer = LocalHeadingBuffer(10); // buffer size 10 is not important.

        Status::LocationStatus mLocationStatus = Status::UNKNOWN;

    public:
        BasicLocalizer();
        ~BasicLocalizer();

        BasicLocalizer(const BasicLocalizerParameters& params): BasicLocalizerParameters(params){
            this->meanRssiBias(meanRssiBias_);
            this->minRssiBias(minRssiBias_);
            this->maxRssiBias(maxRssiBias_);
        }

        bool isVerboseLocalizer = false;

        std::shared_ptr<DataStoreImpl> dataStore;

        void normalFunction(NormalFunction type, double option);
        void meanRssiBias(double b);
        void maxRssiBias(double b);
        void minRssiBias(double b);
        /*
         void angularVelocityLimit(double a);
         */
        double estimatedRssiBias();

        bool forceTraining = false;
        BasicLocalizerOptions basicLocalizerOptions;

        OrientationMeterAverageParameters orientationMeterAverageParameters;
        std::shared_ptr<OrientationMeter> orientationMeter;

        PedometerWalkingStateParameters pedometerWSParams;
        std::shared_ptr<Pedometer> pedometer;

        // parameter objects
        PoseRandomWalkerProperty::Ptr poseRandomWalkerProperty = std::make_shared<PoseRandomWalkerProperty>();
        WeakPoseRandomWalkerProperty::Ptr wPRWproperty = std::make_shared<WeakPoseRandomWalkerProperty>();

        // system models
        std::shared_ptr<RandomWalker<State, SystemModelInput>>randomWalker;
        std::shared_ptr<PoseRandomWalker>poseRandomWalker;
        std::shared_ptr<PoseRandomWalkerInBuilding> poseRandomWalkerInBuilding;

        std::shared_ptr<Resampler<State>> resampler;

        std::shared_ptr<StatusInitializerImpl> statusInitializer;

        std::shared_ptr<StrongestBeaconFilter> beaconFilter;

        loc::Pose stdevPose;

        std::shared_ptr<MetropolisSampler<State, Beacons>> obsDepInitializer;

        MetropolisSampler<State, Beacons>::Parameters msParams;

        LatLngConverter::Ptr latLngConverter();

        StreamLocalizer& updateHandler(void (*functionCalledAfterUpdate)(Status*)) override;
        StreamLocalizer& updateHandler(void (*functionCalledAfterUpdate)(void*, Status*), void* inUserData) override;

        StreamLocalizer& logHandler(void (*functionCalledToLog)(void*, std::string), void* inUserData);

        StreamLocalizer& putAttitude(const Attitude attitude) override;
        StreamLocalizer& putAcceleration(const Acceleration acceleration) override;
        StreamLocalizer& putBeacons(const Beacons beacons) override;
        // StreamLocalizer& putWiFiAPs(const WiFiAPs wifiaps) override;
        StreamLocalizer& putLocalHeading(const LocalHeading heading) override;
        StreamLocalizer& putHeading(const Heading heading);
        StreamLocalizer& putAltimeter(const Altimeter altimeter) override;
        Status* getStatus() override;

        bool resetStatus() override;
        bool resetStatus(Pose pose) override;
        bool resetStatus(Pose meanPose, Pose stdevPose) override;
        bool resetStatus(Pose meanPose, Pose stdevPose, double rateContami) override;
        bool resetStatus(const Beacons& beacons) override;
        bool resetStatus(const Location& location, const Beacons& beacons) override;

        BasicLocalizer& setModel(std::string modelPath, std::string workingDir);

        bool tracksOrientation(){
            switch(localizeMode) {
                case ONESHOT:
                case RANDOM_WALK:
                case RANDOM_WALK_ACC:
                    return false;
                case RANDOM_WALK_ACC_ATT:
                case WEAK_POSE_RANDOM_WALKER:
                    return true;
                default:
                    return false;
            }
        };

        std::shared_ptr<GaussianProcessLDPLMultiModel<State, Beacons>> observationModel() const{
            return deserializedModel;
        };

        // for orientation initialization
        void headingConfidenceForOrientationInit(double confidence);

        void updateLocationStatus(Status*);
        void overwriteLocationStatus(Status::LocationStatus);

    };
}

// assign version
CEREAL_CLASS_VERSION(loc::BasicLocalizerParameters, 0);
#endif /* BasicLocalizerBuilder_hpp */
<|endoftext|>