LAR Library: State-machine

LAR Library

State-machine

Data Structures

struct  stepAction_t
 Each action in the step machine. More...
 

Typedefs

typedef struct step_t step_t
 Opaque type of a handle to a step-machine.
 
typedef int(* stepFunction_t) (step_t *s, stepAction_t *a, void *c)
 Type signature of the function associated with each action on the step machine. More...
 

Functions

step_tstepCreate (stepAction_t *actions, int nactions)
 Create a new step machine. More...
 
int stepRun (step_t *s, void *c)
 Execute the step machine. More...
 
int stepGotoLabel (step_t *s, int label)
 Change the next action to be executed. More...
 
void stepDestroy (step_t *s)
 Release the resources associated with a step-machine. More...
 

Detailed Description

Rationale

Most of the POS financial applications have the same overall structure: each transaction is broken into distinct "steps", each one should be executed in turn, and some steps may be shared between different transactions.

Introduction

This module provides a framework to implement a sub-set of state-machines, here called step-machines. A step-machine is formed by a sequence of states (steps), which are executed in sequence, except explicit change of execution flow (such as a goto).

Each step is defined by the contents of a stepAction_t structure. Each action has an associated label, a numeric identifier that is useful if this action must be target for a goto; The function that executes the actual behavior associated with this action; And a opaque parameter that is meant to be used by the associated function.

An action may have a NULL function, in this case it is considered that the function has returned BASE_ERR_OK. This may be useful to insert "dummy" actions with only a valid label field, meant as goto targets.

Unless a stepGotoLabel() call is made, execution follows the steps in the order that they are given to stepCreate(), this is considered the default execution sequence.

Example

This example is a loop that prints all numbers in the range [0..9]. Even though this is an unrealistic use of the step-machine module, it demonstrates all its features.

enum {
// label for 'print' step
LABEL_PRINT = 1
};
// print the int pointed by c
static int print(step_t *s, stepAction_t *a, void *c)
{
printf(a->param, * (int *) c);
return BASE_ERR_OK;
}
// increment the value of the integer pointed by c
static int incr(step_t *s, stepAction_t *a, void *c)
{
int *n = (int *) c;
(*n) ++;
return BASE_ERR_OK;
}
// goto LABEL_PRINT if the integer pointed by 'c' is < 10
static int loop(step_t *s, stepAction_t *a, void *c)
{
int *n = (int *) c;
if (*n < 10) {
// loop back to 'print' action
return stepGotoLabel(s, LABEL_PRINT);
}
else {
// continue to next step in default sequence
return BASE_ERR_OK;
}
}
static int stepExample(void)
{
stepAction_t actions[] = {
LABEL_PRINT, &print, "The number is %d\n",
0, &incr, NULL,
0, &loop, NULL,
};
step_t *s = stepCreate(actions, BASE_LENGTH(actions));
if (s) {
int n = 0;
int err = stepRun(s, &n);
return err;
}
else {
}
}

Typedef Documentation

typedef int(* stepFunction_t) (step_t *s, stepAction_t *a, void *c)

Type signature of the function associated with each action on the step machine.

Parameters
sHandle to controlling step machine.
aPointer to action associated with this step.
cOverall context parameter passed as parameter to stepRun().
Returns
BASE_ERR_OK on success. Any other value will stop the execution of the step machine immediately and return this value to the caller of stepRun().

Function Documentation

step_t* stepCreate ( stepAction_t actions,
int  nactions 
)

Create a new step machine.

The list of actions defined by actions will be copied to an internal, dynamically allocated, array.

This makes safe to create a step from an array on the stack and returning this value:

1 step_t *CreateMyStep(void)
2 {
3  stepAction_t actions[] = {
4  1, GetAmount, "###.###.##0,00",
5  0, CheckAmount, NULL,
6  2, GetCardData, "Passe ou insira o cartao",
7  0, CheckCardData, NULL,
8  3, DoTransaction, "Pedindo autorizacao",
9  0, CheckResult, NULL,
10  4, TransFail, "Transacao Falhou",
11  5, TransOk, "Transacao foi OK"
12  }
13  return stepCreate(actions, BASE_LENGTH(actions));
14 }
Parameters
actionsList of actions associated with this step machine.
nactionsNumber of elements in actions.
Returns
A pointer to a new step-machine or NULL on error.
See also
stepRun
stepDestroy
void stepDestroy ( step_t s)

Release the resources associated with a step-machine.

Parameters
sHandle to step-machine.
int stepGotoLabel ( step_t s,
int  label 
)

Change the next action to be executed.

Note that this call only marks an indicator of "next action to run", it does not cause the flow to change immediately. Multiple calls will override each other, the last one prevailing.

If more than one action of the given step-machine have the same label, the first one (the one with the smallest index) is selected.

One common idiom for using this call is associated with the return keyword:

1 int myActionFunction(step_t *s, stepAction_t *a, void *c)
2 {
3  // ... processing ...
4  return stepGotoLabel(s, LABEL_MY_OTHER_ACTION);
5 }

This has the side-effect of aborting the execution if LABEL_MY_OTHER_ACTION label is not found in the step-machine s.

Parameters
sHandle to step-machine.
labelLabel of target action, see stepAction_t::label.
Returns
BASE_ERR_OK if next action to execute was changed.
BASE_ERR_DATA_NOT_FOUND if label was not found.
See also
stepRun
int stepRun ( step_t s,
void *  c 
)

Execute the step machine.

Parameters
sHandle to step-machine to run.
cOpaque value that is passed to the action functions.
Returns
BASE_ERR_OK if the machine was executed to the end.
BASE_ERR_INVALID_HANDLE if s is invalid.
The return from the first step that didn't return BASE_ERR_OK.
See also
stepGotoLabel
Generated on Mon Mar 27 2017 15:42:53 for LAR Library by   doxygen 1.8.9.1