/**
 * @file
 * @brief Finite State Machine class
 */

#pragma once
#include "cex.h"

typedef struct fsm_c fsm_c;             // forward declaration
typedef struct fsm_event_s fsm_event_s; // forward declaration

typedef Exception (*FsmStateHandler_f)(fsm_c* self, const fsm_event_s* e);

typedef struct fsm_c
{
    unsigned int _fsm_type;
    FsmStateHandler_f _handler;
    FsmStateHandler_f _handler_super;
} fsm_c;


typedef enum EFsmSignal_e
{
    FsmSignal__na,
    FsmSignal__entry,
    FsmSignal__exit,
    FsmSignal__user, // Used specific signals starts with this one
} EFsmSignal_e;


typedef struct fsm_event_s
{
    unsigned int sig;
} fsm_event_s;

static const fsm_event_s fsm_event_exit = { .sig = FsmSignal__exit };
static const fsm_event_s fsm_event_entry = { .sig = FsmSignal__entry };

struct __cex_namespace__fsm {
    // Autogenerated by CEX
    // clang-format off

    /// Initialize new Finite State Machine class
    Exception       (*create)(fsm_c* self, unsigned int fsm_type, FsmStateHandler_f initial_handler, FsmStateHandler_f super_handler);
    Exception       (*dispatch)(fsm_c* self, const fsm_event_s* e);
    Exception       (*init)(fsm_c* self);
    Exception       (*super)(fsm_c* self, const fsm_event_s* e);
    Exception       (*trans)(fsm_c* self, FsmStateHandler_f new_state);

    // clang-format on
};
CEX_NAMESPACE struct __cex_namespace__fsm fsm;

