Zusammenfluss von Transitionen

Mit dem Zusammenfluss von Transitionen ist es möglich, für mehrere Transitionen gemeinsame Wegabschnitte zu definieren, die gleichermaßen durchlaufen werden.

Zustandsdiagramm

Modell

Beschreibung

Im Gegensatz zu den bisher vorgestellten Konstrukten einer Zustandsmaschine bietet der Zusammenfluss von Transitionen (Joining) keine neunen Möglichkeiten, Verhalten zu modellieren. Er bietet aber eine elegante Möglichkeit, die Modellierung zu vereinfachen und mehr Übersicht und Konsistenz zu schaffen.

Durch die Verwendung von Joinings können Transitionen in unterschiedliche Abschnitte gegliedert werden, wobei jedem Abschnitt seine eigenen Actions zugeordnet werden können.

Die eigenständigen Abschnitte einer Transitionen können dann auch von anderen Transitionen gemeinsam genutzt und damit Wegabschnitte gemeinsam durchlaufen werden. Die Actions an den gemeinsamen Abschnitten werden dann von allen beteiligten Transitionen gleichermaßen ausgeführt.

Ebenso wie bei Choices gilt auch für Joinings der allgemeine Grundsatz für Zustandsmaschinen, dass diese nach der Verarbeitung eines Events einen stabilen Zustand angenommen haben müssen. Daher ist es bei den ausgehenden Transitionen von Joinings auch nicht möglich, zusätzliche Bedingungen anzugeben.

Generierte Datei: demo_sm.h

#ifndef DEMO_SM_H
#define DEMO_SM_H



/*###########################################################################################################################################################*/
//      Type declarations
/*###########################################################################################################################################################*/


typedef enum DemoSm_StatesTag DemoSm_States;

enum DemoSm_StatesTag
{
    DemoSm_States_INVALID,
    DemoSm_States_IN_TRANSITION,
    DemoSm_States_ALPHA
};


typedef enum DemoSm_EventTag DemoSm_Event;

enum DemoSm_EventTag
{
    DemoSm_Event_INVALID,
    DemoSm_Event_TICK,
    DemoSm_Event_TACK
};



/*###########################################################################################################################################################*/
//      Function declarations
/*###########################################################################################################################################################*/


/*===========================================================================================================================================================*/
extern void DemoSm_init(void);


/*===========================================================================================================================================================*/
extern void DemoSm_executeWithDemoSmEvent( const DemoSm_Event demoSmEvent );


/*===========================================================================================================================================================*/
extern void DemoSm_raiseFatalError(void);


/*===========================================================================================================================================================*/
extern void DemoSm_commonAction(void);


/*===========================================================================================================================================================*/
extern void DemoSm_tickAction(void);


/*===========================================================================================================================================================*/
extern void DemoSm_tackAction(void);


#endif // DEMO_SM_H

Generierte Datei: demo_sm.c

/*###########################################################################################################################################################*/
//      Includes
/*###########################################################################################################################################################*/
#include "demo_sm.h"
#include <stdbool.h>
#include <stddef.h>



/*###########################################################################################################################################################*/
//      Type declarations
/*###########################################################################################################################################################*/


typedef enum DemoSm_EvTypeTag DemoSm_EvType;

enum DemoSm_EvTypeTag
{
    DemoSm_EvType_DEMO_SM_EVENT
};


typedef struct DemoSm_EvObjTag DemoSm_EvObj;

struct DemoSm_EvObjTag
{
    DemoSm_EvType evType;
    DemoSm_Event  demoSmEvent;
};



/*###########################################################################################################################################################*/
//      Variables
/*###########################################################################################################################################################*/


static DemoSm_States DemoSm_currentState = DemoSm_States_INVALID;
static bool DemoSm_executionInProgress = false;



/*###########################################################################################################################################################*/
//      Internal function declarations
/*###########################################################################################################################################################*/


/*===========================================================================================================================================================*/
static void DemoSm_setState( const DemoSm_States newState );


/*===========================================================================================================================================================*/
static void DemoSm_execute( DemoSm_EvObj* const evObj );


/*===========================================================================================================================================================*/
static void DemoSm_executeStatemachine( DemoSm_EvObj* const evObj );


/*===========================================================================================================================================================*/
static void DemoSm_enterAlpha(void);


/*===========================================================================================================================================================*/
static void DemoSm_executeAlpha( DemoSm_EvObj* const evObj );


/*===========================================================================================================================================================*/
static void DemoSm_leaveAlpha(void);



/*###########################################################################################################################################################*/
//      Internal function implementations
/*###########################################################################################################################################################*/


/*===========================================================================================================================================================*/
static void DemoSm_setState( const DemoSm_States newState )
/*===========================================================================================================================================================*/
{
    DemoSm_currentState = newState;
}



/*===========================================================================================================================================================*/
static void DemoSm_execute( DemoSm_EvObj* const evObj )
/*===========================================================================================================================================================*/
{
    if ( !DemoSm_executionInProgress )
    {
        DemoSm_executeStatemachine( evObj );
    }
    else
    {
        // recursion error
        
        DemoSm_raiseFatalError();
    }
}



/*===========================================================================================================================================================*/
static void DemoSm_executeStatemachine( DemoSm_EvObj* const evObj )
/*===========================================================================================================================================================*/
{
    DemoSm_executionInProgress = true;
    
    switch ( DemoSm_currentState )
    {
        case DemoSm_States_ALPHA:
            DemoSm_executeAlpha( evObj );
            break;
        
        
        default:
            DemoSm_raiseFatalError();
            break;
    }
    
    DemoSm_executionInProgress = false;
}



/*===========================================================================================================================================================*/
static void DemoSm_enterAlpha(void)
/*===========================================================================================================================================================*/
{
    DemoSm_setState( DemoSm_States_ALPHA );
}



/*===========================================================================================================================================================*/
static void DemoSm_executeAlpha( DemoSm_EvObj* const evObj )
/*===========================================================================================================================================================*/
{
    if ( evObj != NULL )
    {
        if ( evObj->evType == DemoSm_EvType_DEMO_SM_EVENT )
        {
            switch ( evObj->demoSmEvent )
            {
                case DemoSm_Event_TICK:
                    DemoSm_leaveAlpha();
                    
                    DemoSm_tickAction();
                    
                    DemoSm_commonAction();
                    
                    DemoSm_enterAlpha();
                    break;
                
                
                case DemoSm_Event_TACK:
                    DemoSm_leaveAlpha();
                    
                    DemoSm_tackAction();
                    
                    DemoSm_commonAction();
                    
                    DemoSm_enterAlpha();
                    break;
                
                
                default:
                    break;
            }
        }
    }
    else
    {
        // no untriggered transitions available
    }
}



/*===========================================================================================================================================================*/
static void DemoSm_leaveAlpha(void)
/*===========================================================================================================================================================*/
{
    DemoSm_setState( DemoSm_States_IN_TRANSITION );
}



/*###########################################################################################################################################################*/
//      External function implementations
/*###########################################################################################################################################################*/


/*===========================================================================================================================================================*/
extern void DemoSm_init(void)
/*===========================================================================================================================================================*/
{
    DemoSm_enterAlpha();
}



/*===========================================================================================================================================================*/
extern void DemoSm_executeWithDemoSmEvent( const DemoSm_Event demoSmEvent )
/*===========================================================================================================================================================*/
{
    DemoSm_EvObj evObj;


    evObj.evType = DemoSm_EvType_DEMO_SM_EVENT;
    evObj.demoSmEvent = demoSmEvent;
    
    DemoSm_execute( &evObj );
}



/*===========================================================================================================================================================*/
extern void DemoSm_raiseFatalError(void)
/*===========================================================================================================================================================*/
{
    // add your action implementation code here
}



/*===========================================================================================================================================================*/
extern void DemoSm_commonAction(void)
/*===========================================================================================================================================================*/
{
    // add your action implementation code here
}



/*===========================================================================================================================================================*/
extern void DemoSm_tickAction(void)
/*===========================================================================================================================================================*/
{
    // add your action implementation code here
}



/*===========================================================================================================================================================*/
extern void DemoSm_tackAction(void)
/*===========================================================================================================================================================*/
{
    // add your action implementation code here
}