LibJuno 1.0.4
LibJuno is a lightweight C11 library designed specifically for embedded systems.
Loading...
Searching...
No Matches
sm_api.h
Go to the documentation of this file.
1/*
2 MIT License
3
4 Copyright (c) 2025 Robin A. Onsay
5
6 Permission is hereby granted, free of charge, to any person obtaining
7 a copy of this software and associated documentation files
8 (the "Software"), to deal in the Software without restriction,
9 including without limitation the rights to use, copy, modify, merge,
10 publish, distribute, sublicense, and/or sell copies of the Software,
11 and to permit persons to whom the Software is furnished to do so,
12 subject to the following conditions:
13
14 The above copyright notice and this permission notice shall be
15 included in all copies or substantial portions of the Software.
16*/
17
32#ifndef JUNO_SM_API_H
33#define JUNO_SM_API_H
34#include "juno/macros.h"
35#include "juno/status.h"
36#include "juno/module.h"
37#include "juno/types.h"
38#include <stdbool.h>
39#include <stddef.h>
40#ifdef __cplusplus
41extern "C"
42{
43#endif
44
45typedef struct JUNO_SM_ROOT_TAG JUNO_SM_ROOT_T;
47
48typedef struct JUNO_SM_STATE_ROOT_TAG JUNO_SM_STATE_ROOT_T;
49
51JUNO_MODULE_RESULT(JUNO_SM_RESULT_STATE_ROOT_T, JUNO_SM_STATE_ROOT_T *);
52JUNO_MODULE_RESULT(JUNO_SM_RESULT_STATE_T, JUNO_SM_STATE_ROOT_T *);
53JUNO_MODULE_OPTION(JUNO_SM_OPTION_STATE_ROOT_T, JUNO_SM_STATE_ROOT_T *);
54JUNO_MODULE_OPTION(JUNO_SM_OPTION_STATE_T, JUNO_SM_STATE_ROOT_T *);
55JUNO_MODULE_RESULT(JUNO_SM_RESULT_OPTION_STATE_ROOT_T, JUNO_SM_OPTION_STATE_ROOT_T);
56JUNO_MODULE_RESULT(JUNO_SM_RESULT_OPTION_STATE_T, JUNO_SM_OPTION_STATE_T);
57
59// @{"req": ["REQ-SM-002"]}
60struct JUNO_SM_STATE_ROOT_TAG JUNO_MODULE_ROOT(JUNO_SM_STATE_API_T,
61 JUNO_SM_ROOT_T *ptSm;
62 JUNO_SM_OPTION_STATE_T tOptionNextState;
63);
64
65// @{"req": ["REQ-SM-003"]}
75
76// @{"req": ["REQ-SM-001"]}
77struct JUNO_SM_ROOT_TAG JUNO_MODULE_ROOT(void,
79 JUNO_SM_STATE_ROOT_T *ptCurrentState;
80);
81
83// @{"req": ["REQ-SM-009"]}
85{
86 JUNO_ASSERT_EXISTS(ptSmRoot);
87 JUNO_ASSERT_EXISTS(ptSmRoot->ptCurrentState);
89}
90
91// @{"req": ["REQ-SM-010", "REQ-SM-011"]}
93{
94 JUNO_ASSERT_EXISTS(ptSmState);
95 JUNO_ASSERT_EXISTS(ptSmState->ptApi && ptSmState->ptSm);
96 if(ptSmState->tOptionNextState.bIsSome)
97 {
98 JUNO_ASSERT_EXISTS(ptSmState->tOptionNextState.tSome);
99 }
100 return JUNO_STATUS_SUCCESS;
101}
102
104// @{"req": ["REQ-SM-005"]}
105static inline JUNO_STATUS_T JunoSm_StateInit(JUNO_SM_ROOT_T *ptSm, JUNO_SM_STATE_ROOT_T *ptStateRoot, JUNO_SM_STATE_ROOT_T *ptNextState, const JUNO_SM_STATE_API_T *ptStateApi, JUNO_FAILURE_HANDLER_T pfcnFailureHandler, JUNO_USER_DATA_T *pvFailureUserData)
106{
107 JUNO_ASSERT_EXISTS(ptStateRoot && ptStateApi && ptSm);
108 ptStateRoot->ptSm = (JUNO_SM_ROOT_T *) ptSm;
109 ptStateRoot->_pfcnFailureHandler = pfcnFailureHandler;
110 ptStateRoot->_pvFailureUserData = pvFailureUserData;
111 ptStateRoot->ptApi = ptStateApi;
112 if(ptNextState)
113 {
114 ptStateRoot->tOptionNextState.bIsSome = true;
115 ptStateRoot->tOptionNextState.tSome = (JUNO_SM_STATE_ROOT_T *) ptNextState;
116 }
117 else
118 {
119 ptStateRoot->tOptionNextState.bIsSome = false;
120 ptStateRoot->tOptionNextState.tSome = NULL;
121 }
122 return JunoSm_StateVerify(ptStateRoot);
123}
124
126// @{"req": ["REQ-SM-004"]}
127static inline JUNO_STATUS_T JunoSm_Init(JUNO_SM_ROOT_T *ptSmRoot, JUNO_SM_STATE_ROOT_T *ptStartState, JUNO_FAILURE_HANDLER_T pfcnFailureHandler, JUNO_USER_DATA_T *pvFailureUserData)
128{
129 JUNO_ASSERT_EXISTS(ptSmRoot);
130 ptSmRoot->ptCurrentState = (JUNO_SM_STATE_ROOT_T *) ptStartState;
131 ptSmRoot->_pfcnFailureHandler = pfcnFailureHandler;
132 ptSmRoot->_pvFailureUserData = pvFailureUserData;
133 JUNO_STATUS_T tStatus = JunoSm_Verify(ptSmRoot);
134 JUNO_ASSERT_SUCCESS(tStatus, return tStatus);
135 return tStatus;
136}
137
139// @{"req": ["REQ-SM-006"]}
140static inline JUNO_SM_RESULT_STATE_T JunoSm_GetCurrentState(JUNO_SM_ROOT_T *ptSmRoot)
141{
142 JUNO_SM_RESULT_STATE_T tResult = {JUNO_STATUS_ERR, NULL};
143 tResult.tStatus = JunoSm_Verify(ptSmRoot);
144 JUNO_ASSERT_SUCCESS(tResult.tStatus, return tResult);
145 tResult.tStatus = JUNO_STATUS_SUCCESS;
146 tResult.tOk = ptSmRoot->ptCurrentState;
147 return tResult;
148}
149
151// @{"req": ["REQ-SM-007", "REQ-SM-008"]}
152static inline JUNO_SM_RESULT_OPTION_STATE_T JunoSm_TransitionState(JUNO_SM_ROOT_T *ptSmRoot)
153{
154 JUNO_SM_RESULT_OPTION_STATE_T tResult = JUNO_ERR_RESULT(JUNO_STATUS_ERR,
155 JUNO_NONE_OPTION(NULL)
156 );
157 tResult.tStatus = JunoSm_Verify(ptSmRoot);
158 JUNO_ASSERT_SUCCESS(tResult.tStatus, return tResult);
159 tResult.tStatus = JUNO_STATUS_SUCCESS;
160 JUNO_SM_STATE_ROOT_T *ptCurrentStateRoot = (JUNO_SM_STATE_ROOT_T*) ptSmRoot->ptCurrentState;
161 if(ptCurrentStateRoot->tOptionNextState.bIsSome)
162 {
163 ptSmRoot->ptCurrentState = ptCurrentStateRoot->tOptionNextState.tSome;
164 tResult.tOk.bIsSome = true;
165 tResult.tOk.tSome = ptSmRoot->ptCurrentState;
166 }
167 else
168 {
169 tResult.tOk.bIsSome = false;
170 tResult.tOk.tSome = NULL;
171 }
172 return tResult;
173}
174
175#ifdef __cplusplus
176}
177#endif
178#endif // JUNO_SM_API_H
#define JUNO_ASSERT_EXISTS(ptr)
Returns JUNO_STATUS_NULLPTR_ERROR if the expression is falsy.
Definition macros.h:51
#define JUNO_ASSERT_SUCCESS(tStatus,...)
Execute the provided failure operation(s) if status is not success.
Definition macros.h:89
#define JUNO_ERR_RESULT(err, value)
Construct a result indicating error with a payload (may be default-initialized).
Definition module.h:230
#define JUNO_NONE_OPTION(default_value)
Construct an option in the empty state, carrying a default payload.
Definition module.h:276
#define JUNO_MODULE_RESULT(NAME_T, OK_T)
Define a result type combining a status and a success payload.
Definition module.h:198
#define JUNO_MODULE_ROOT(API_T,...)
Implement a module root struct containing ptApi and failure fields.
Definition module.h:129
#define JUNO_MODULE_OPTION(NAME_T, SOME_T)
Define an option type combining a presence flag and a payload.
Definition module.h:242
#define JUNO_STATUS_ERR
Unspecified error.
Definition status.h:61
#define JUNO_STATUS_SUCCESS
Operation completed successfully.
Definition status.h:59
void(* JUNO_FAILURE_HANDLER_T)(JUNO_STATUS_T tStatus, const char *pcCustomMessage, JUNO_USER_DATA_T *pvUserData)
Failure handler callback signature.
Definition status.h:110
int32_t JUNO_STATUS_T
Canonical status type for LibJuno functions.
Definition status.h:51
void JUNO_USER_DATA_T
Opaque user data type for failure callbacks.
Definition status.h:101
Common assertion and helper macros for LibJuno modules.
Module system and dependency injection primitives for LibJuno.
static JUNO_STATUS_T JunoSm_StateVerify(JUNO_SM_STATE_ROOT_T *ptSmState)
Definition sm_api.h:92
static JUNO_STATUS_T JunoSm_Init(JUNO_SM_ROOT_T *ptSmRoot, JUNO_SM_STATE_ROOT_T *ptStartState, JUNO_FAILURE_HANDLER_T pfcnFailureHandler, JUNO_USER_DATA_T *pvFailureUserData)
Initialize the state machine with a start state.
Definition sm_api.h:127
struct JUNO_SM_STATE_ROOT_TAG JUNO_SM_STATE_ROOT_T
Definition sm_api.h:48
static JUNO_STATUS_T JunoSm_StateInit(JUNO_SM_ROOT_T *ptSm, JUNO_SM_STATE_ROOT_T *ptStateRoot, JUNO_SM_STATE_ROOT_T *ptNextState, const JUNO_SM_STATE_API_T *ptStateApi, JUNO_FAILURE_HANDLER_T pfcnFailureHandler, JUNO_USER_DATA_T *pvFailureUserData)
Initialize a state, linking it to the SM and optional next state.
Definition sm_api.h:105
static JUNO_SM_RESULT_OPTION_STATE_T JunoSm_TransitionState(JUNO_SM_ROOT_T *ptSmRoot)
Transition to the next state if present; return the new state option.
Definition sm_api.h:152
static JUNO_STATUS_T JunoSm_Verify(JUNO_SM_ROOT_T *ptSmRoot)
Verify if this is a valid state machine.
Definition sm_api.h:84
static JUNO_SM_RESULT_STATE_T JunoSm_GetCurrentState(JUNO_SM_ROOT_T *ptSmRoot)
Get the current state pointer.
Definition sm_api.h:140
struct JUNO_SM_ROOT_TAG JUNO_SM_ROOT_T
Definition sm_api.h:45
Status codes and failure-handling helpers for LibJuno.
Definition sm_api.h:67
JUNO_STATUS_T(* StateAction)(JUNO_SM_STATE_ROOT_T *ptJunoSm)
Action executed while in this state.
Definition sm_api.h:69
JUNO_STATUS_T(* ResetState)(JUNO_SM_STATE_ROOT_T *ptJunoSm)
Reset any state-local data.
Definition sm_api.h:73
JUNO_RESULT_BOOL_T(* ShouldExit)(JUNO_SM_STATE_ROOT_T *ptJunoSm)
Return whether the current state should exit.
Definition sm_api.h:71
Common module result type aliases used throughout LibJuno.