Skip to content

Commit

Permalink
Release #2
Browse files Browse the repository at this point in the history
  • Loading branch information
VPavlusha committed May 17, 2023
1 parent 0a948c0 commit fde2529
Show file tree
Hide file tree
Showing 7 changed files with 178 additions and 87 deletions.
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Build results
build/

# VSCode
.vscode
11 changes: 9 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,22 @@ else()
add_compile_options(-Wall -Wextra -pedantic -Werror)
endif()

set (SRC_DIR ${CMAKE_CURRENT_SOURCE_DIR}/src)
set (INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/include)
set (EXAMPLES_DIR ${CMAKE_CURRENT_SOURCE_DIR}/examples)

project(fsm_example_c)
set(CMAKE_CXX_STANDARD 98)
add_executable(${PROJECT_NAME} ${EXAMPLES_DIR}/example.c ${INCLUDE_DIR}/finite_state_machine.h)
add_executable(${PROJECT_NAME}
${SRC_DIR}/finite_state_machine.c
${EXAMPLES_DIR}/example.c
)
target_include_directories(${PROJECT_NAME} PUBLIC ${INCLUDE_DIR})

project(fsm_example_cpp)
set(CMAKE_CXX_STANDARD 11)
add_executable(${PROJECT_NAME} ${EXAMPLES_DIR}/example.cpp ${INCLUDE_DIR}/finite_state_machine.hpp)
add_executable(${PROJECT_NAME}
${SRC_DIR}/finite_state_machine.cpp
${EXAMPLES_DIR}/example.cpp
)
target_include_directories(${PROJECT_NAME} PUBLIC ${INCLUDE_DIR})
68 changes: 43 additions & 25 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@
[![CMake](https://github.com/VPavlusha/FSM/actions/workflows/cmake.yml/badge.svg)](https://github.com/VPavlusha/FSM/actions/workflows/cmake.yml)
[![cpp-linter](https://github.com/VPavlusha/FSM/actions/workflows/cpp-linter.yml/badge.svg)](https://github.com/VPavlusha/FSM/actions/workflows/cpp-linter.yml)
[![GitHub release (latest by date)](https://img.shields.io/github/v/release/VPavlusha/FSM?label=Release&logo=github)](https://github.com/VPavlusha/FSM/releases)
[![Stand With Ukraine](https://raw.githubusercontent.com/vshymanskyy/StandWithUkraine/main/badges/StandWithUkraine.svg)](https://stand-with-ukraine.pp.ua)
[![Made in Ukraine](https://img.shields.io/badge/Made_in-Ukraine-ffd700.svg?labelColor=0057b7)](https://stand-with-ukraine.pp.ua)
---

# FSM - Finite State Machine
A static (no dynamic allocations) Finite State Machine (FSM) header-only C/C++ library.<br/>
A static (no dynamic allocations) Finite State Machine (FSM) C/C++ library.<br/>
Based on: https://github.com/AstarLight/FSM-framework

#### Table of Contents
Expand All @@ -14,16 +16,16 @@ Based on: https://github.com/AstarLight/FSM-framework
&emsp;[3. Basic Usage in C](#3-basic-usage-in-c)
&emsp;[4. Basic Usage in C++](#4-basic-usage-in-c)
&emsp;[5. Examples](#5-examples)
&emsp;[6. Installation](#6-installation)
&emsp;[7. Requirement](#7-requirement)
&emsp;[8. Build Procedure](#8-build-procedure)
&emsp;[9. License](#9-license)
&emsp;[6. Requirement](#6-requirement)
&emsp;[7. Build Procedure by CMake (Unix)](#7-build-procedure-by-cmake-unix)
&emsp;[8. Build Procedure by CMake (Windows)](#8-build-procedure-by-cmake-windows)
&emsp;[9. Contributing](#9-contributing)
&emsp;[10. License](#10-license)

## 1. Features
- **Permissive** MIT License.
- **C and C++ languages** – state machine is written both in C and C++ languages.
- **Compact** – consumes a minimum amount of resources.
- **Header-only library** – no special installation steps are needed.
- **Fully static** – no dynamic memory allocations.
- **Objects** – support multiple FSM instantiations of a single state machine type.
- **Transition table** – transition table precisely controls state transition behavior.
Expand All @@ -32,7 +34,6 @@ Based on: https://github.com/AstarLight/FSM-framework
- **Error checking** – runtime checks catch mistakes early.

## 2. State Transition Table

<img src="./doc/img/fsm_diagram.svg" alt="Finite State Machine" width="550"/>

The state diagram shown in the figure can be described via a state transition table. This table has four columns and as many rows as needed. Each row describes a transition from the **Present State** to the **Next State**. The transition is triggered by the **Event** (a combination of one or more event flags). The **Action** describes all the actions associated with the transition.
Expand Down Expand Up @@ -100,7 +101,7 @@ int main()
#include "finite_state_machine.hpp"
// 2. Create enumeration for FSM states:
enum FSM_States : int {
enum FSM_States: int {
STATE_0,
STATE_1,
STATE_2,
Expand Down Expand Up @@ -146,32 +147,49 @@ int main()
```

## 5. Examples
This project includes several [`examples`](https://github.com/VPavlusha/FSM/tree/main/examples) that showcase the functionality of the FSM library. These examples provide a practical demonstration of how to use the FSM API to implement finite state machines in your own applications.
This project includes several [examples](https://github.com/VPavlusha/FSM/tree/main/examples) that showcase the functionality of the FSM library. These examples provide a practical demonstration of how to use the FSM API to implement finite state machines in your own applications.

## 6. Requirement
For the build process:
- **cmake**
- **make**
- **gcc**

## 6. Installation
FSM is a header-only library, no special installation steps are needed. Just point your compiler to the [`include`](https://github.com/VPavlusha/FSM/tree/main/include) directory.
For the documentation generation:
- **doxygen**

## 7. Requirement
For the build process :
- cmake
- make
- gcc
## 7. Build Procedure by CMake (Unix)
```
git clone https://github.com/VPavlusha/FSM.git
cd fsm
mkdir build && cd build
cmake .. # Default to Unix Makefiles
make
```
Once this completes, everything will be under **`build/`**:
- **fsm_example_c**
- **fsm_example_cpp**

For the documentation generation :
- doxygen
Run these files to try how FSM works.

## 8. Build Procedure
## 8. Build Procedure by CMake (Windows)
```
git clone https://github.com/VPavlusha/FSM.git
cd fsm
mkdir build && cd build
cmake .. -G "Unix Makefiles" && make
cmake .. -G "Unix Makefiles" # Or use any generator you want to use. Run cmake --help for a list
make
```
Once this completes, everything will be under **`build/`**:
- **fsm_example_c.exe**
- **fsm_example_cpp.exe**

Run these files to try how FSM works.

## 9. License
FSM is the [Open Source] software. It may be used for any purpose,
including commercial purposes, at absolutely no cost. It is
distributed under the terms of the [MIT license].
## 9. Contributing
Contributions to the FSM project are welcome. If you find a bug or have a feature request, please submit an issue on the project's GitHub page. If you'd like to contribute code, please submit a pull request.

[Open Source]: http://www.opensource.org/docs/definition.html
## 10. License
The FSM project is licensed under the MIT License. See the [MIT license] file for more information.

[MIT license]: http://www.opensource.org/licenses/mit-license.html
26 changes: 2 additions & 24 deletions include/finite_state_machine.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
*/

#include <stdbool.h>
#include <stdio.h>
#include <stddef.h>

typedef bool (*FSM_Event_t)(void);
typedef void (*FSM_Action_t)(void);
Expand Down Expand Up @@ -76,28 +76,6 @@ typedef struct {
* \return FSM_SUCCESS On success.
* \return FSM_ARGUMENT_NOT_VALID If an argument is a NULL pointer.
*/
FSM_ReturnCode_t FSM_Kernel(FSM_t *const fsm)
{
if (fsm == NULL) {
return FSM_ARGUMENT_NOT_VALID;
}

for (size_t row = 0; row < fsm->fsm_table_size / sizeof(FSM_TableRow_t); ++row) {
if (fsm->fsm_table[row].present_state == fsm->current_state) {
if (fsm->fsm_table[row].event != NULL) {
if (fsm->fsm_table[row].event()) {
if (fsm->fsm_table[row].action != NULL) {
fsm->fsm_table[row].action();
}
fsm->current_state = fsm->fsm_table[row].next_state;
break;
}
} else {
return FSM_ARGUMENT_NOT_VALID;
}
}
}
return FSM_SUCCESS;
}
FSM_ReturnCode_t FSM_Kernel(FSM_t *const fsm);

Check warning on line 79 in include/finite_state_machine.h

View workflow job for this annotation

GitHub Actions / cpp-linter

/include/finite_state_machine.h:79:29 [readability-avoid-const-params-in-decls]

parameter 'fsm' is const-qualified in the function declaration; const-qualification of parameters only has an effect in function definitions

Check warning on line 79 in include/finite_state_machine.h

View workflow job for this annotation

GitHub Actions / cpp-linter

/include/finite_state_machine.h:79:29 [readability-avoid-const-params-in-decls]

parameter 'fsm' is const-qualified in the function declaration; const-qualification of parameters only has an effect in function definitions

#endif // FINITE_STATE_MACHINE_H_
48 changes: 12 additions & 36 deletions include/finite_state_machine.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,19 @@ class FSM {
FSM &operator=(FSM &&) = delete;

Check warning on line 81 in include/finite_state_machine.hpp

View workflow job for this annotation

GitHub Actions / cpp-linter

/include/finite_state_machine.hpp:81:10 [modernize-use-trailing-return-type]

use a trailing return type for this function

Check warning on line 81 in include/finite_state_machine.hpp

View workflow job for this annotation

GitHub Actions / cpp-linter

/include/finite_state_machine.hpp:81:10 [modernize-use-trailing-return-type]

use a trailing return type for this function
~FSM() = default;

/**
* \brief Get FSM current state.
*
* \return FSM_State_t The FSM current state.
*/
FSM_State_t FSM_GetCurrentState() const noexcept;

Check warning on line 89 in include/finite_state_machine.hpp

View workflow job for this annotation

GitHub Actions / cpp-linter

/include/finite_state_machine.hpp:89:17 [modernize-use-trailing-return-type]

use a trailing return type for this function

Check warning on line 89 in include/finite_state_machine.hpp

View workflow job for this annotation

GitHub Actions / cpp-linter

/include/finite_state_machine.hpp:89:17 [modernize-use-trailing-return-type]

use a trailing return type for this function

/**
* \brief FSM kernel task running on background.
*
* \return FSM_SUCCESS On success.
* \return FSM_ARGUMENT_NOT_VALID If an argument is a nullptr pointer.
*/
FSM_ReturnCode_t FSM_Kernel() noexcept;

Check warning on line 97 in include/finite_state_machine.hpp

View workflow job for this annotation

GitHub Actions / cpp-linter

/include/finite_state_machine.hpp:97:22 [modernize-use-trailing-return-type]

use a trailing return type for this function

Check warning on line 97 in include/finite_state_machine.hpp

View workflow job for this annotation

GitHub Actions / cpp-linter

/include/finite_state_machine.hpp:97:22 [modernize-use-trailing-return-type]

use a trailing return type for this function

private:
Expand All @@ -90,42 +102,6 @@ class FSM {
FSM_State_t current_state_;
};

/**
* \brief Get FSM current state.
*
* \return FSM_State_t The FSM current state.
*/
FSM_State_t FSM::FSM_GetCurrentState() const noexcept
{
return current_state_;
}

/**
* \brief FSM kernel task running on background.
*
* \return FSM_SUCCESS On success.
* \return FSM_ARGUMENT_NOT_VALID If an argument is a nullptr pointer.
*/
FSM_ReturnCode_t FSM::FSM_Kernel() noexcept
{
for (size_t row = 0; row < fsm_table_size_ / sizeof(FSM_TableRow_t); ++row) {
if (fsm_table_[row].present_state == current_state_) {
if (fsm_table_[row].event != nullptr) {
if (fsm_table_[row].event()) {
if (fsm_table_[row].action != nullptr) {
fsm_table_[row].action();
}
current_state_ = fsm_table_[row].next_state;
break;
}
} else {
return FSM_ReturnCode_t::FSM_ARGUMENT_NOT_VALID;
}
}
}
return FSM_ReturnCode_t::FSM_SUCCESS;
}

} // namespace fsm

#endif // FINITE_STATE_MACHINE_HPP_
51 changes: 51 additions & 0 deletions src/finite_state_machine.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/*

Check notice on line 1 in src/finite_state_machine.c

View workflow job for this annotation

GitHub Actions / cpp-linter

Run clang-format on src/finite_state_machine.c

File src/finite_state_machine.c does not conform to Custom style guidelines. (lines 3, 5, 12, 13, 15, 29, 30, 31, 32, 33, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49)

Check notice on line 1 in src/finite_state_machine.c

View workflow job for this annotation

GitHub Actions / cpp-linter

Run clang-format on src/finite_state_machine.c

File src/finite_state_machine.c does not conform to Custom style guidelines. (lines 3, 5, 12, 13, 15, 29, 30, 31, 32, 33, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49)
* MIT License
*
* Copyright (c) 2022 Volodymyr Pavlusha
*
* 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.
*/

#include "finite_state_machine.h"

Check failure on line 25 in src/finite_state_machine.c

View workflow job for this annotation

GitHub Actions / cpp-linter

/src/finite_state_machine.c:25:10 [clang-diagnostic-error]

'finite_state_machine.h' file not found

Check failure on line 25 in src/finite_state_machine.c

View workflow job for this annotation

GitHub Actions / cpp-linter

/src/finite_state_machine.c:25:10 [clang-diagnostic-error]

'finite_state_machine.h' file not found

#include <stddef.h>

FSM_ReturnCode_t FSM_Kernel(FSM_t *const fsm)
{
if (fsm == NULL) {
return FSM_ARGUMENT_NOT_VALID;
}

for (size_t row = 0; row < fsm->fsm_table_size / sizeof(FSM_TableRow_t); ++row) {
if (fsm->fsm_table[row].present_state == fsm->current_state) {
if (fsm->fsm_table[row].event != NULL) {
if (fsm->fsm_table[row].event()) {
if (fsm->fsm_table[row].action != NULL) {
fsm->fsm_table[row].action();
}
fsm->current_state = fsm->fsm_table[row].next_state;
break;
}
} else {
return FSM_ARGUMENT_NOT_VALID;
}
}
}
return FSM_SUCCESS;
}
56 changes: 56 additions & 0 deletions src/finite_state_machine.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/*

Check notice on line 1 in src/finite_state_machine.cpp

View workflow job for this annotation

GitHub Actions / cpp-linter

Run clang-format on src/finite_state_machine.cpp

File src/finite_state_machine.cpp does not conform to Custom style guidelines. (lines 3, 5, 12, 13, 15, 31, 32, 33, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 56)

Check notice on line 1 in src/finite_state_machine.cpp

View workflow job for this annotation

GitHub Actions / cpp-linter

Run clang-format on src/finite_state_machine.cpp

File src/finite_state_machine.cpp does not conform to Custom style guidelines. (lines 3, 5, 12, 13, 15, 31, 32, 33, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 56)
* MIT License
*
* Copyright (c) 2022 Volodymyr Pavlusha
*
* 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.
*/

#include <finite_state_machine.hpp>

Check failure on line 25 in src/finite_state_machine.cpp

View workflow job for this annotation

GitHub Actions / cpp-linter

/src/finite_state_machine.cpp:25:10 [clang-diagnostic-error]

'finite_state_machine.hpp' file not found

Check failure on line 25 in src/finite_state_machine.cpp

View workflow job for this annotation

GitHub Actions / cpp-linter

/src/finite_state_machine.cpp:25:10 [clang-diagnostic-error]

'finite_state_machine.hpp' file not found

#include <cstddef>

namespace fsm {

FSM_State_t FSM::FSM_GetCurrentState() const noexcept
{
return current_state_;
}

FSM_ReturnCode_t FSM::FSM_Kernel() noexcept
{
for (size_t row = 0; row < fsm_table_size_ / sizeof(FSM_TableRow_t); ++row) {
if (fsm_table_[row].present_state == current_state_) {
if (fsm_table_[row].event != nullptr) {
if (fsm_table_[row].event()) {
if (fsm_table_[row].action != nullptr) {
fsm_table_[row].action();
}
current_state_ = fsm_table_[row].next_state;
break;
}
} else {
return FSM_ReturnCode_t::FSM_ARGUMENT_NOT_VALID;
}
}
}
return FSM_ReturnCode_t::FSM_SUCCESS;
}

} // namespace fsm

0 comments on commit fde2529

Please sign in to comment.