Skip to content

Commit

Permalink
FSM: rename to more correct names
Browse files Browse the repository at this point in the history
  • Loading branch information
polesskiy-dev committed Oct 18, 2023
1 parent a78e7fc commit ad1a4d9
Show file tree
Hide file tree
Showing 5 changed files with 30 additions and 34 deletions.
2 changes: 1 addition & 1 deletion examples/elevator-fsm/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ int main() {
printf("Pressing UP button, target floor %d\n", 3);

// Use the FSM function
myElevator.state = Elevator_FSM_ProcessEventToNextState(&myElevator, event, transitionTable);
myElevator.state = Elevator_FSM_ProcessEventToNextStateFromTransitionTable(&myElevator, event, transitionTable);

printf("Elevator state: %s\n", STATES_STRINGS[myElevator.state]);

Expand Down
2 changes: 1 addition & 1 deletion examples/request-fsm/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ void runTasks() {
};

REQUEST_STATE processEventToNextState(REQUEST_AO *const activeObject, REQUEST_EVENT event) {
REQUEST_STATE nextState = REQUEST_AO_FSM_ProcessEventToNextState(activeObject, event, requestTransitionTable);
REQUEST_STATE nextState = REQUEST_AO_FSM_ProcessEventToNextStateFromTransitionTable(activeObject, event, requestTransitionTable);

return nextState;
};
Expand Down
8 changes: 3 additions & 5 deletions src/fsm/fsm.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,19 +12,17 @@ inline bool FSM_IsValidState(const TState *const state) {
return EMPTY_STATE.name != state->name && INVALID_STATE.name != state->name;
};

const TState *FSM_ProcessEventToNextState(
const TState *FSM_ProcessEventToNextStateFromTransitionTable(
TActiveObject *const activeObject,
TEvent event,
uint32_t statesMax,
uint32_t eventsMax,
const TState statesList[statesMax],
const TEventHandler transitionTable[statesMax][eventsMax]) {

/* Validate input args */

// Validate Active object
if (NULL == activeObject
|| NULL == statesList
|| NULL == transitionTable)
return &invalidState; // Handle null pointers as needed

Expand All @@ -51,14 +49,14 @@ const TState *FSM_ProcessEventToNextState(
};

// Execute a state hook and return its status.
bool _executeHook(TStateHook hook, TActiveObject *activeObject) {
static bool _executeHook(TStateHook hook, TActiveObject *activeObject) {
if (hook) {
return hook(activeObject, NULL);
}
return true; // No hook to execute, so consider it successful
}

bool FSM_TraverseNextState(
bool FSM_TraverseAOToNextState(
TActiveObject *const activeObject,
const TState *const nextState) {
// Null args checks
Expand Down
10 changes: 4 additions & 6 deletions src/fsm/fsm.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,29 +19,27 @@ typedef const TState* (*TEventHandler)(TActiveObject *const activeObject, TEvent

/**
* @brief Processes an incoming event
* @details Invoke state handler f from transitions table by current state and event: [currState][event] => f(event): nextState
* @details Invoke state handler f from transition table by current state and event: [currState][event] => f(event): nextState
*
* @param[in] activeObject The active object.
* @param[in] event The incoming event.
* @param[in] statesMax The maximum number of states.
* @param[in] eventsMax The maximum number of events.
* @param[in] statesList The list of states.
* @param[in] transitionTable The transition table for state-event pairs.
*
* @return A pointer to the next state
* @returns 0 (EMPTY_STATE) in case of state handler lack in transitionTable
* @returns -1 (INVALID_STATE) in case of invalid input args
*/
const TState *FSM_ProcessEventToNextState(
const TState *FSM_ProcessEventToNextStateFromTransitionTable(
TActiveObject *const activeObject, /**< The active object. */
TEvent event, /**< The incoming event. */
uint32_t statesMax, /**< The maximum number of states. */
uint32_t eventsMax, /**< The maximum number of events. */
const TState statesList[statesMax], /**< The list of states. */
const TEventHandler transitionTable[statesMax][eventsMax]); /**< The transition table for state-event. */

/**
* @brief Transitions the active object to the next state
* @brief Transitions the Active Object to the next state
* @details Invokes state hooks (onEnter, onTraverse, onExit)
* of the current and next states appropriately.
* Returns false on any hook failure (false return).
Expand All @@ -51,7 +49,7 @@ const TState *FSM_ProcessEventToNextState(
*
* @return True if the transition is successful, false otherwise.
*/
bool FSM_TraverseNextState(
bool FSM_TraverseAOToNextState(
TActiveObject *const activeObject,
const TState *const nextState);

Expand Down
42 changes: 21 additions & 21 deletions test/fsm/fsm.test.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,69 +45,69 @@ void tearDown(void) {
}

// NO_STATE -> EMPTY_HOOKS_ST
void test_FSM_TraverseNextState_from_NO_STATE_Successfully(void) {
void test_FSM_TraverseAOToNextState_from_NO_STATE_Successfully(void) {
activeObject.state = &statesList[NO_STATE];

bool result = FSM_TraverseNextState(&activeObject, &statesList[EMPTY_HOOKS_ST]);
bool result = FSM_TraverseAOToNextState(&activeObject, &statesList[EMPTY_HOOKS_ST]);

TEST_ASSERT_TRUE(result);
TEST_ASSERT_EQUAL_PTR(&statesList[EMPTY_HOOKS_ST], activeObject.state);
}

// EMPTY_HOOKS_ST -> SUCCESS_HOOKS_ST
void test_FSM_TraverseNextState_EmptyHooks_Should_ReturnTrue(void) {
void test_FSM_TraverseAOToNextState_EmptyHooks_Should_ReturnTrue(void) {
activeObject.state = &statesList[EMPTY_HOOKS_ST];

bool result = FSM_TraverseNextState(&activeObject, &statesList[SUCCESS_HOOKS_ST]);
bool result = FSM_TraverseAOToNextState(&activeObject, &statesList[SUCCESS_HOOKS_ST]);

TEST_ASSERT_TRUE(result);
TEST_ASSERT_EQUAL_PTR(&statesList[SUCCESS_HOOKS_ST], activeObject.state);
}

// SUCCESS_HOOKS_ST -> SUCCESS_HOOKS_ST
void test_FSM_TraverseNextState_Self_SuccessHooks_Should_ReturnTrue(void) {
void test_FSM_TraverseAOToNextState_Self_SuccessHooks_Should_ReturnTrue(void) {
activeObject.state = &statesList[SUCCESS_HOOKS_ST];

bool result = FSM_TraverseNextState(&activeObject, &statesList[SUCCESS_HOOKS_ST]);
bool result = FSM_TraverseAOToNextState(&activeObject, &statesList[SUCCESS_HOOKS_ST]);

TEST_ASSERT_TRUE(result);
TEST_ASSERT_EQUAL_PTR(&statesList[SUCCESS_HOOKS_ST], activeObject.state);
}

// SUCCESS_HOOKS_ST -> FAILURE_HOOKS_ST (success onExist, failure onEmtry, state changes)
void test_FSM_TraverseNextState_FailureHooks_Should_ReturnFalse(void) {
void test_FSM_TraverseAOToNextState_FailureHooks_Should_ReturnFalse(void) {
activeObject.state = &statesList[SUCCESS_HOOKS_ST];

bool result = FSM_TraverseNextState(&activeObject, &statesList[FAILURE_HOOKS_ST]);
bool result = FSM_TraverseAOToNextState(&activeObject, &statesList[FAILURE_HOOKS_ST]);

TEST_ASSERT_FALSE(result);
TEST_ASSERT_EQUAL_PTR(&statesList[FAILURE_HOOKS_ST], activeObject.state);
}

// FAILURE_HOOKS_ST -> SUCCESS_HOOKS_ST (traverse is not conducted)
void test_FSM_TraverseNextState_from_FailureHooks_Fails(void) {
void test_FSM_TraverseAOToNextState_from_FailureHooks_Fails(void) {
activeObject.state = &statesList[FAILURE_HOOKS_ST];

bool result = FSM_TraverseNextState(&activeObject, &statesList[SUCCESS_HOOKS_ST]);
bool result = FSM_TraverseAOToNextState(&activeObject, &statesList[SUCCESS_HOOKS_ST]);

TEST_ASSERT_FALSE(result);
TEST_ASSERT_EQUAL_PTR(&statesList[FAILURE_HOOKS_ST], activeObject.state);
}

void test_FSM_ProcessEventToNextState_Should_TransitionState(void) {
void test_FSM_ProcessEventToNextStateFromTransitionTable_Should_TransitionState(void) {
activeObject.state = &statesList[EMPTY_HOOKS_ST];
TEvent event = { .sig = GO_SUCCESS_HOOKS_ST };

const TState *nextState = FSM_ProcessEventToNextState(&activeObject, event, STATES_MAX, EVENTS_MAX, statesList, transitionTable);
const TState *nextState = FSM_ProcessEventToNextStateFromTransitionTable(&activeObject, event, STATES_MAX, EVENTS_MAX, statesList);

TEST_ASSERT_EQUAL_PTR(&statesList[SUCCESS_HOOKS_ST], nextState);
}

void test_FSM_ProcessEventToNextState_Should_NotTransitionState_WithGuard(void) {
void test_FSM_ProcessEventToNextStateFromTransitionTable_Should_NotTransitionState_WithGuard(void) {
activeObject.state = &statesList[SUCCESS_HOOKS_ST];
TEvent event = { .sig = GO_FAILURE_HOOKS_ST };

const TState *nextState = FSM_ProcessEventToNextState(&activeObject, event, STATES_MAX, EVENTS_MAX, statesList, transitionTable);
const TState *nextState = FSM_ProcessEventToNextStateFromTransitionTable(&activeObject, event, STATES_MAX, EVENTS_MAX, statesList);

TEST_ASSERT_EQUAL_PTR(&statesList[FAILURE_HOOKS_ST], nextState);
}
Expand All @@ -116,15 +116,15 @@ int main(void) {
UNITY_BEGIN();

// TraverseNextState
RUN_TEST(test_FSM_TraverseNextState_from_NO_STATE_Successfully);
RUN_TEST(test_FSM_TraverseNextState_EmptyHooks_Should_ReturnTrue);
RUN_TEST(test_FSM_TraverseNextState_Self_SuccessHooks_Should_ReturnTrue);
RUN_TEST(test_FSM_TraverseNextState_FailureHooks_Should_ReturnFalse);
RUN_TEST(test_FSM_TraverseNextState_from_FailureHooks_Fails);
RUN_TEST(test_FSM_TraverseAOToNextState_from_NO_STATE_Successfully);
RUN_TEST(test_FSM_TraverseAOToNextState_EmptyHooks_Should_ReturnTrue);
RUN_TEST(test_FSM_TraverseAOToNextState_Self_SuccessHooks_Should_ReturnTrue);
RUN_TEST(test_FSM_TraverseAOToNextState_FailureHooks_Should_ReturnFalse);
RUN_TEST(test_FSM_TraverseAOToNextState_from_FailureHooks_Fails);

// ProcessEventToNextState
RUN_TEST(test_FSM_ProcessEventToNextState_Should_TransitionState);
RUN_TEST(test_FSM_ProcessEventToNextState_Should_NotTransitionState_WithGuard);
RUN_TEST(test_FSM_ProcessEventToNextStateFromTransitionTable_Should_TransitionState);
RUN_TEST(test_FSM_ProcessEventToNextStateFromTransitionTable_Should_NotTransitionState_WithGuard);
UNITY_END();

return 0;
Expand Down

0 comments on commit ad1a4d9

Please sign in to comment.