Skip to content

Commit

Permalink
validated flag for state machine
Browse files Browse the repository at this point in the history
  • Loading branch information
mgonzs13 committed Nov 4, 2024
1 parent d5d998e commit e27d5cb
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 14 deletions.
38 changes: 24 additions & 14 deletions yasmin/include/yasmin/state_machine.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#ifndef YASMIN_STATE_MACHINE_HPP
#define YASMIN_STATE_MACHINE_HPP

#include <atomic>
#include <functional>
#include <map>
#include <memory>
Expand All @@ -40,14 +41,16 @@ namespace yasmin {
*/
class StateMachine : public State {

// Type definitions for callback functions
/// Alias for a callback function executed before running the state machine.
using StartCallbackType = std::function<void(
std::shared_ptr<yasmin::blackboard::Blackboard>, const std::string &,
const std::vector<std::string> &)>;
/// Alias for a callback function executed before changing the state.
using TransitionCallbackType = std::function<void(
std::shared_ptr<yasmin::blackboard::Blackboard>, const std::string &,
const std::string &, const std::string &,
const std::vector<std::string> &)>;
/// Alias for a callback function executed after running the state machine.
using EndCallbackType = std::function<void(
std::shared_ptr<yasmin::blackboard::Blackboard>, const std::string &,
const std::vector<std::string> &)>;
Expand Down Expand Up @@ -225,20 +228,27 @@ class StateMachine : public State {
std::string to_string();

private:
std::map<std::string, std::shared_ptr<State>> states; ///< Map of states
std::map<std::string, std::map<std::string, std::string>>
transitions; ///< Map of transitions
std::string start_state; ///< Name of the start state
std::string current_state; ///< Name of the current state
std::unique_ptr<std::mutex>
current_state_mutex; ///< Mutex for current state access

std::vector<std::pair<StartCallbackType, std::vector<std::string>>>
start_cbs; ///< Start callbacks
/// Map of states
std::map<std::string, std::shared_ptr<State>> states;
/// Map of transitions
std::map<std::string, std::map<std::string, std::string>> transitions;
/// Name of the start state
std::string start_state;
/// Name of the current state
std::string current_state;
/// Mutex for current state access
std::unique_ptr<std::mutex> current_state_mutex;

/// Flag to indicate if the state machine has been validated
std::atomic_bool validated{false};

/// Start callbacks executed before the state machine
std::vector<std::pair<StartCallbackType, std::vector<std::string>>> start_cbs;
/// Transition callbacks executed before changing the state
std::vector<std::pair<TransitionCallbackType, std::vector<std::string>>>
transition_cbs; ///< Transition callbacks
std::vector<std::pair<EndCallbackType, std::vector<std::string>>>
end_cbs; ///< End callbacks
transition_cbs;
/// End callbacks executed before the state machine
std::vector<std::pair<EndCallbackType, std::vector<std::string>>> end_cbs;
};

} // namespace yasmin
Expand Down
11 changes: 11 additions & 0 deletions yasmin/src/yasmin/state_machine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,9 @@ void StateMachine::add_state(std::string name, std::shared_ptr<State> state,
if (this->start_state.empty()) {
this->set_start_state(name);
}

// Mark state machine as no validated
this->validated.store(false);
}

void StateMachine::add_state(std::string name, std::shared_ptr<State> state) {
Expand Down Expand Up @@ -194,6 +197,11 @@ void StateMachine::validate() {

YASMIN_LOG_DEBUG("Validating state machine '%s'", this->to_string().c_str());

if (this->validated.load()) {
YASMIN_LOG_DEBUG("State machine '%s' has already been validated",
this->to_string().c_str());
}

// Check initial state
if (this->start_state.empty()) {
throw std::runtime_error("No initial state set");
Expand Down Expand Up @@ -260,6 +268,9 @@ void StateMachine::validate() {
"' not registered as outcome or state");
}
}

// State machine has been validated
this->validated.store(true);
}

std::string
Expand Down
13 changes: 13 additions & 0 deletions yasmin/yasmin/state_machine.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,10 @@ def __init__(self, outcomes: Set[str]) -> None:
self.__current_state: str = None
## A threading lock to manage access to the current state.
self.__current_state_lock: Lock = Lock()

## A flag indicating whether the state machine has been validated.
self._validated: bool = False

## A list of callbacks to call when the state machine starts.
self.__start_cbs: List[
Tuple[Callable[[Blackboard, str, List[Any]], None], List[Any]]
Expand Down Expand Up @@ -119,6 +123,9 @@ def add_state(
if not self._start_state:
self.set_start_state(name)

## Mark state machine as no validated
self._validated = False

def set_start_state(self, state_name: str) -> None:
"""
Sets the initial state for the state machine.
Expand Down Expand Up @@ -276,6 +283,9 @@ def validate(self) -> None:
"""
yasmin.YASMIN_LOG_DEBUG(f"Validating state machine '{self}'")

if self._validated:
yasmin.YASMIN_LOG_DEBUG("State machine '{self}' has already been validated")

# terminal outcomes
terminal_outcomes = []

Expand Down Expand Up @@ -323,6 +333,9 @@ def validate(self) -> None:
f"State machine outcome '{o}' not registered as outcome neither state"
)

# State machine has been validated
self._validated = True

def execute(self, blackboard: Blackboard) -> str:
"""
Executes the state machine starting from the initial state.
Expand Down

0 comments on commit e27d5cb

Please sign in to comment.