// SPDX-License-Identifier: Apache-2.0 // Copyright 2023 - 2023 Pionix GmbH and Contributors to EVerest #include "fsm_controller.hpp" #include FSMController::FSMController(slac::fsm::ev::Context& context) : ctx(context){}; void FSMController::signal_new_slac_message(slac::messages::HomeplugMessage& msg) { if (running == false) { return; } { const std::lock_guard feed_lck(feed_mtx); ctx.slac_message = msg; fsm.handle_event(slac::fsm::ev::Event::SLAC_MESSAGE); } new_event = true; new_event_cv.notify_all(); } void FSMController::signal_reset() { signal_simple_event(slac::fsm::ev::Event::RESET); } void FSMController::signal_trigger_matching() { signal_simple_event(slac::fsm::ev::Event::TRIGGER_MATCHING); } bool FSMController::signal_simple_event(slac::fsm::ev::Event ev) { const std::lock_guard feed_lck(feed_mtx); auto event_result = fsm.handle_event(ev); new_event = true; new_event_cv.notify_all(); return event_result == fsm::HandleEventResult::SUCCESS; } void FSMController::run() { ctx.log_info("Starting the SLAC state machine"); fsm.reset(ctx); std::unique_lock feed_lck(feed_mtx); running = true; while (true) { auto feed_result = fsm.feed(); if (feed_result.transition()) { // call immediately again continue; } else if (feed_result.internal_error() || feed_result.unhandled_event()) { // FIXME (aw): would need to log here! } else if (feed_result.has_value() == true) { const auto timeout = *feed_result; if (timeout == 0) { // call feed directly again continue; } new_event_cv.wait_for(feed_lck, std::chrono::milliseconds(timeout), [this] { return new_event; }); } else { // nothing happened, no return value -> wait for new event new_event_cv.wait(feed_lck, [this] { return new_event; }); } if (new_event) { // we got a new event, reset it and let run feed again new_event = false; } } }