gem-graph-client/include/fsm.h

254 lines
9.9 KiB
C

/**
* @file
* FSM (Finite State Machine) header of the Gem-graph client.
*
* @see readme.docs and this text below.
*
* ---
*
* The two log structures and the two enums needed by the logs are defined in
* the fsm header.
*
* All log functions are in dedicated files.
*
* The most important function: fsm_add_log() is in the file:
* /src/fsm/log/manager.c
*
* This file contains the declaration of the log with the **static** attribute,
* which forces all the functions that read or write it to be in it.
* Forcing all functions that read or write to the log to be grouped together
* helps to prevent uncontrolled operations.
*
* All events sent to the log must pass through this function, which allows them
* to be filtered before being published in the log.
*
* ---
*
* Here's how the procedure works.
* A message is send to the fsm_add_log() function for each documented event.
* If there are too many events, this is the only function that allows you to
* apply one or more filters before publication. This allows you to select the
* events of interest, which can vary depending on the type of session.
* These filters can operate on any the following five parameters:
* severity, source, file_source, function_source, string_value.
* They can be combined using any logical operators and parentheses.
*
* 'severity' is one of the following pre-defined values:
* FATAL - ERROR - WARN - INFO - DEBUG - TRACE
*
* 'source' is a pre-defined value (typically a name of a structure) that can be
* associated to each event. It can be set to 'NULL'.
*
* file_source, function_source and string_value are three strings.
*
* ---
*
* The four mandatory executive functions that the log needs to init, add and
* publish are in the dedicated file: /src/fsm/log/oper.c:
*
* NB: fsm_clear_log() is designed to close what was initiated by fsm_init_log().
* As, in this commit, fsm_publish_log() is the last instruction and no memory
* leaks are detected, the use of fsm_clear_log() is not required.
*
* - fsm_init_log()
* - fsm_publish_log()
* - fsm_clear_log()
* - fsm_add_log_event()
* .
*
* A typical list would also feature the following three functions
* but in the case of a log, their usefulness remains to be demonstrated.
* These functions are therefore apart in the file /src/fsm/log/appendix.c
*
* - fsm_get_log_length()
* - fsm_seek_log()
* - fsm_remove_log()
* .
*
*
* @cond LICENSE
* This file is part of Gem-graph.
*
* Copyright © 2021 Libre en Communs <contact@a-lec.org>
* Copyright © 2021-2024 Adrien Bourmault <neox@a-lec.org>
* Copyright © 2021-2024 Jean Sirmai <jean@a-lec.org>
*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU Affero General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
* details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* @endcond
*/
#pragma once
/******************************************************************************/
/* L O G / J O U R N A L */
/******************************************************************************/
/**
* The 'severity' enum conforms to canonical log levels:
* FATAL, ERROR, WARN, INFO, DEBUG, TRACE
*
* https://betterstack.com/community/guides/logging/logging-best-practices/
* https://en.wikipedia.org/wiki/Syslog
*
* All logs must contain at least one item from this enum and only one.
* This item can NOT be set to NULL.
*
* @see fsm_add_log()
*/
enum fsm_enum_log_severity {
FATAL, /**< (or CRITICAL) an unrecoverable failure that prevents the whole
application from doing any further useful work 🕳️☠️ */
ERROR, /**< an irremediable situation that hinders the execution of a
specific operation within the application 👀️😮️! */
WARN, /**< something unexpected has occurred, but the application can
continue to function normally for the time being 😅️ */
INFO, /**< (or MESSAGE) a significant event occurs while the system is
operating normally 📜️👌️ */
DEBUG, /**< a description of system states in sufficient detail to give
developers clues as to the cause of an error 🪳️🧐️ */
TRACE /**< provides a systematic overview of code execution but comes at
a cost in terms of performance 🥱️ */
};
/**
* A list of structures or states that may be involved in program events.
*
* All logs must contain at least one item from this list or the value NULL.
*
* Only some main items of this list are commented on today. Further comments
* will depend on its usage and structure which are just beginning to evolve.
*
* NB about PAGE: user_tree and selected_rule are two vertical panes which it
* is a good idea to place next to each other on the rules page so that you can
* switch between them more easily or have a parallel view of the two.
*
* @see fsm_add_log()
*/
enum fsm_enum_log_source {
AUTO_NOTIFICATION, /**< (not a source) */
DESTINATION, /**< SOURCE, TARGET */ SOURCE, TARGET,
FSM_CONTENT, /**< LOG, FSM, PREFER */ LOG, FSM, PREFER,
SRC_CONTENT, /**< MAIN, APP, WIDGETS, SIGNAL */ MAIN, APP, WIDGETS, SIGNAL,
WINDOW, /**< MAIN, DIALOG, MODAL, TEXT */
MAIN_WINDOW, DIALOG_WINDOW, MODAL_WINDOW, TEXT_WINDOW,
HEADER_BAR, /**< LEFT, CENTER, RIGHT */ HEADER_BAR_LEFT, HEADER_BAR_CENTER,
HEADER_BAR_RIGHT,
PAGE, /**< SYNTH, STATE, RULES, [USER TREE], [SELECTED_RULE], MEASURES, RESULTS */
SYNTH_PAGE, STATE_PAGE, RULES_PAGE, MEASURES_PAGE, RESULTS_PAGE,
SYNTHESIS, /**< GLAREA, CAMERA, CONTROLS, RESULTS (duplicates from other pages) */
SYNTH_GLAREA, SYNTH_CAMERA, SYNTH_CONTROLS, SYNTH_RESULTS,
SYNTH_DATA, /**< SYNTH_TIME_DEP_RESULTS, SYNTH_TIME_INDEP_RESULTS */
SYNTH_TIME_DEP_RESULTS, SYNTH_TIME_INDEP_RESULTS,
STATE_VIEW, /**< TOP, BOTTOM, GLAREA, CAMERA */
STATE_TOP, STATE_BOTTOM, STATE_GLAREA, STATE_CAMERA,
SINGLE_RULE, /**< RULE_GEOMETRY, RULE_ALGEBRA */
RULE_GEOMETRY, /**< VIEW_BEFORE, VIEW_AFTER, RULE_GLAREA, RULE_CAMERA */
VIEW_BEFORE, VIEW_AFTER, RULE_GLAREA, RULE_CAMERA,
RULE_ALGEBRA, /**< LIST_CONDITIONS, LIST_ASSIGNMENTS, IDENTITY */
RULE_LIST_CONDITION, RULE_LIST_ASSIGNMENTS, RULE_IDENTITY,
TREE_RULES, /**< TREE, COMPARE, USE */
RULES_TREE, RULES_COMPARE, RULES_USE,
MEASURES, /**< TOOLS, ACTIVITY, DISPLAY */
MEASURES_TOOLS, MEASURES_ACTIVITY, MEASURES_DISPLAY,
RESULTS, /**< TIME_DEPPENDENT, TIME_INDEPENDENT */
TIME_DEP_RESULTS, TIME_INDEP_RESULTS,
GTK_WIDGETS, /**< LABEL, BUTTON, SCROLL, GLAREA, SLIDER, EXPANDER,...
* (non limitative) */
WIDGET, BUTTON, SCROLL, GLAREA, TEXT, LABEL, TREE, SLIDER, EXPANDER,
ENTRY, SLIDER_X, SLIDER_Y, SLIDER_Z, SLIDER_A, SLIDER_B, SLIDER_C,
OTHERS, /**< fsm possible states: [EXEC / EDIT], [STATE / RULES / DATA],
* (non limitative) */
ON_SWITCH_EXEC_EDIT, ON_SWITCH_STATE_RULES_DATA,
};
//-----------------------------------------------------------------------------
#define FILE_SOURCE_NAME_SIZE 40
#define FUNCTION_SOURCE_NAME_SIZE 30
#define STRING_VALUE_SIZE 50
#define LOG_MAX_LENGTH \
FILE_SOURCE_NAME_SIZE+FUNCTION_SOURCE_NAME_SIZE+STRING_VALUE_SIZE
/**
* A log unit must include the followings:
*
* @see fsm_log_t
*/
struct fsm_log_unit_t
{
long yy_dd_mm; /**< * date of the event reported in the log */
long usec; /**< * with microseconds precision */
char *restrict file_source; /**< * emitter file */
char *restrict function_source; /**< * emitter function */
char *restrict string_value; /**< * any event descriptors */
struct fsm_log_unit_t *prev; /**< * chained list */
struct fsm_log_unit_t *next; /**< * chained list */
};
/**
* Log is a double-chained list. Two links towards the previous and the next unit
* are required to initialize and manage it.
*
* @see fsm_log_t_unit
*
* @see fsm_init_log()
* @see fsm_publish_log()
* @see fsm_clear_log()
* @see fsm_add_log_event()
* @see fsm_get_log_length()
* @see fsm_seek_log()
* @see fsm_remove_log()
*/
struct fsm_log_t
{
struct fsm_log_unit_t *oldest; /**< * required */
struct fsm_log_unit_t *latest; /**< * required */
};
//-----------------------------------------------------------------------------
void fsm_init_log (struct fsm_log_t *);
void fsm_publish_log (struct fsm_log_t *);
void fsm_clear_log (struct fsm_log_t *);
void fsm_clear_log_unit(struct fsm_log_unit_t *);
void fsm_add_log_event (struct fsm_log_t *gg_logs,
const char *restrict file_source,
const char *restrict function_source,
const char *restrict string_value);
int fsm_get_log_length(struct fsm_log_t *);
void fsm_seek_log (struct fsm_log_t *gg_logs,
long usec,
const char *restrict file_source,
const char *restrict function_source,
const char *restrict string_value);
long fsm_remove_log (struct fsm_log_t *);
void fsm_add_log (int severity,
const char *restrict file_source,
const char *restrict function_source,
const char *restrict string_value);
#define FSM_ADD_LOG(severity,string_value) \
fsm_add_log(severity,__FILE__,__func__,string_value)
void fsm_relay_init_log();
void fsm_relay_close_log();
void fsm_init();
void fsm_close();