Skip to content
StateMachine.cpp 7.46 KiB
Newer Older
#include "StateMachine.h"

#include "QGCLoggingCategory.h"

#include <QDebug>

const QLoggingCategory &WimaPlanerLog();

namespace wima_planer_detail {

template <typename T>
constexpr typename std::underlying_type<T>::type integral(T value) {
  return static_cast<typename std::underlying_type<T>::type>(value);
}

StateMachine::StateMachine(QObject *parent)
    : QObject(parent), _state(STATE::NEEDS_INIT) {}

STATE StateMachine::state() { return this->_state; }

void StateMachine::updateState(EVENT e) {
  qCDebug(WimaPlanerLog) << "StateMachine::updateState(): event:" << e;
  switch (this->_state) {
  case STATE::NEEDS_INIT:
    switch (e) {
    case EVENT::INIT_DONE:
      setState(STATE::NEEDS_J_AREA_UPDATE);
      break;
    case EVENT::M_AREA_PATH_CHANGED:
    case EVENT::S_AREA_PATH_CHANGED:
    case EVENT::CORRIDOR_PATH_CHANGED:
    case EVENT::M_AREA_TILES_CHANGED:
    case EVENT::M_AREA_PROGRESS_CHANGED:
    case EVENT::J_AREA_UPDATED:
    case EVENT::DEPOT_CHANGED:
    case EVENT::SURVEY_DESTROYED:
    case EVENT::SURVEY_UPDATE_TRIGGERED:
    case EVENT::SURVEY_UPDATED:
    case EVENT::PATH_UPDATED:
      break;
    default:
      qCCritical(WimaPlanerLog)
          << "StateMachine::updateState: Unknown event: " << e;
      Q_ASSERT(false);
      break;
    }
    break; // STATE::NEEDS_INIT
  case STATE::NEEDS_J_AREA_UPDATE:
    switch (e) {
    case EVENT::INIT_DONE:
    case EVENT::M_AREA_PATH_CHANGED:
    case EVENT::S_AREA_PATH_CHANGED:
    case EVENT::CORRIDOR_PATH_CHANGED:
    case EVENT::M_AREA_TILES_CHANGED:
    case EVENT::M_AREA_PROGRESS_CHANGED:
      break;
    case EVENT::J_AREA_UPDATED:
      setState(STATE::NEEDS_SURVEY_UPDATE);
    case EVENT::DEPOT_CHANGED:
    case EVENT::SURVEY_DESTROYED:
    case EVENT::SURVEY_UPDATE_TRIGGERED:
    case EVENT::SURVEY_UPDATED:
    case EVENT::PATH_UPDATED:
      break;
    default:
      qCCritical(WimaPlanerLog)
          << "StateMachine::updateState: Unknown event: " << e;
      Q_ASSERT(false);
      break;
    }
    break; // STATE::NEEDS_J_AREA_UPDATE
  case STATE::NEEDS_SURVEY_UPDATE:
    switch (e) {
    case EVENT::INIT_DONE:
    case EVENT::M_AREA_PATH_CHANGED:
    case EVENT::S_AREA_PATH_CHANGED:
    case EVENT::CORRIDOR_PATH_CHANGED:
      setState(STATE::NEEDS_J_AREA_UPDATE);
      break;
    case EVENT::M_AREA_TILES_CHANGED:
    case EVENT::M_AREA_PROGRESS_CHANGED:
    case EVENT::J_AREA_UPDATED:
    case EVENT::DEPOT_CHANGED:
    case EVENT::SURVEY_DESTROYED:
      break;
    case EVENT::SURVEY_UPDATE_TRIGGERED:
      setState(STATE::WAITING_FOR_SURVEY_UPDATE);
      break;
    case EVENT::SURVEY_UPDATED:
    case EVENT::PATH_UPDATED:
      break;
    default:
      qCCritical(WimaPlanerLog)
          << "StateMachine::updateState: Unknown event: " << e;
      Q_ASSERT(false);
      break;
    }
    break; // STATE::NEEDS_SURVEY_UPDATE
  case STATE::WAITING_FOR_SURVEY_UPDATE:
    switch (e) {
    case EVENT::INIT_DONE:
    case EVENT::M_AREA_PATH_CHANGED:
    case EVENT::S_AREA_PATH_CHANGED:
    case EVENT::CORRIDOR_PATH_CHANGED:
      setState(STATE::NEEDS_J_AREA_UPDATE);
      break;
    case EVENT::M_AREA_TILES_CHANGED:
    case EVENT::M_AREA_PROGRESS_CHANGED:
    case EVENT::J_AREA_UPDATED:
    case EVENT::DEPOT_CHANGED:
    case EVENT::SURVEY_DESTROYED:
      setState(STATE::NEEDS_SURVEY_UPDATE);
      break;
    case EVENT::SURVEY_UPDATE_TRIGGERED:
      break;
    case EVENT::SURVEY_UPDATED:
      setState(STATE::NEEDS_PATH_UPDATE);
    case EVENT::PATH_UPDATED:
      break;
    default:
      qCCritical(WimaPlanerLog)
          << "StateMachine::updateState: Unknown event: " << e;
      Q_ASSERT(false);
      break;
    }
    break; // STATE::WAYTING_FOR_SURVEY_UPDATE
  case STATE::NEEDS_PATH_UPDATE:
    switch (e) {
    case EVENT::INIT_DONE:
    case EVENT::M_AREA_PATH_CHANGED:
    case EVENT::S_AREA_PATH_CHANGED:
    case EVENT::CORRIDOR_PATH_CHANGED:
      setState(STATE::NEEDS_J_AREA_UPDATE);
      break;
    case EVENT::M_AREA_TILES_CHANGED:
    case EVENT::M_AREA_PROGRESS_CHANGED:
    case EVENT::J_AREA_UPDATED:
    case EVENT::DEPOT_CHANGED:
    case EVENT::SURVEY_DESTROYED:
      setState(STATE::NEEDS_SURVEY_UPDATE);
      break;
    case EVENT::SURVEY_UPDATE_TRIGGERED:
      setState(STATE::WAITING_FOR_SURVEY_UPDATE);
      break;
    case EVENT::SURVEY_UPDATED:
      break;
    case EVENT::PATH_UPDATED:
      setState(STATE::UP_TO_DATE);
      break;
    default:
      qCCritical(WimaPlanerLog)
          << "StateMachine::updateState: Unknown event: " << e;
      Q_ASSERT(false);
      break;
    }
    break; // STATE::NEEDS_PATH_UPDATE
  case STATE::UP_TO_DATE:
    switch (e) {
    case EVENT::INIT_DONE:
    case EVENT::M_AREA_PATH_CHANGED:
    case EVENT::S_AREA_PATH_CHANGED:
    case EVENT::CORRIDOR_PATH_CHANGED:
      setState(STATE::NEEDS_J_AREA_UPDATE);
      break;
    case EVENT::M_AREA_TILES_CHANGED:
    case EVENT::M_AREA_PROGRESS_CHANGED:
    case EVENT::J_AREA_UPDATED:
    case EVENT::DEPOT_CHANGED:
    case EVENT::SURVEY_DESTROYED:
      setState(STATE::NEEDS_SURVEY_UPDATE);
      break;
    case EVENT::SURVEY_UPDATE_TRIGGERED:
      setState(STATE::WAITING_FOR_SURVEY_UPDATE);
      break;
    case EVENT::SURVEY_UPDATED:
      setState(STATE::NEEDS_PATH_UPDATE);
      break;
    case EVENT::PATH_UPDATED:
      break;
    default:
      qCCritical(WimaPlanerLog)
          << "StateMachine::updateState: Unknown event: " << e;
      Q_ASSERT(false);
      break;
    }
    break; // STATE::UP_TO_DATE
  default:
    qCCritical(WimaPlanerLog)
        << "StateMachine::updateState: Unknown state: " << this->_state;
    Q_ASSERT(false);
    break;
  }
}

bool StateMachine::upToDate() { return this->_state == STATE::UP_TO_DATE; }

void StateMachine::setState(STATE s) {
  if (this->_state != s) {
    auto oldState = this->_state;
    this->_state = s;
    emit stateChanged();
    if (oldState == STATE::UP_TO_DATE || s == STATE::UP_TO_DATE) {
      emit upToDateChanged();
    }
    qCDebug(WimaPlanerLog) << "StateMachine::setState():" << oldState << "->"
                           << s;
  }
}

QDebug &operator<<(QDebug &ds, STATE s) {
  switch (s) {

  case STATE::NEEDS_INIT:
    ds << "NEEDS_INIT";
    break;
  case STATE::NEEDS_J_AREA_UPDATE:
    ds << "NEEDS_J_AREA_UPDATE";
    break;
  case STATE::NEEDS_SURVEY_UPDATE:
    ds << "NEEDS_SURVEY_UPDATE";
    break;
  case STATE::WAITING_FOR_SURVEY_UPDATE:
    ds << "WAITING_FOR_SURVEY_UPDATE";
    break;
  case STATE::NEEDS_PATH_UPDATE:
    ds << "NEEDS_PATH_UPDATE";
    break;
  case STATE::UP_TO_DATE:
    ds << "UP_TO_DATE";
    break;
  }
  return ds;
}

QDebug &operator<<(QDebug &ds, EVENT s) {
  switch (s) {
  case EVENT::INIT_DONE:
    ds << "INIT_DONE";
    break;
  case EVENT::M_AREA_PATH_CHANGED:
    ds << "M_AREA_PATH_CHANGED";
    break;
  case EVENT::S_AREA_PATH_CHANGED:
    ds << "S_AREA_PATH_CHANGED";
    break;
  case EVENT::CORRIDOR_PATH_CHANGED:
    ds << "CORRIDOR_PATH_CHANGED";
    break;
  case EVENT::M_AREA_TILES_CHANGED:
    ds << "M_AREA_TILES_CHANGED";
    break;
  case EVENT::M_AREA_PROGRESS_CHANGED:
    ds << "M_AREA_PROGRESS_CHANGED";
    break;
  case EVENT::J_AREA_UPDATED:
    ds << "J_AREA_UPDATED";
    break;
  case EVENT::DEPOT_CHANGED:
    ds << "DEPOT_CHANGED";
    break;
  case EVENT::SURVEY_DESTROYED:
    ds << "SURVEY_DESTROYED";
    break;
  case EVENT::SURVEY_UPDATE_TRIGGERED:
    ds << "SURVEY_UPDATE_TRIGGERED";
    break;
  case EVENT::SURVEY_UPDATED:
    ds << "SURVEY_UPDATED";
    break;
  case EVENT::PATH_UPDATED:
    ds << "PATH_UPDATED";
    break;
  }
  return ds;
}

} // namespace wima_planer_detail