parent
3f547ed50c
commit
c1762801e2
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -0,0 +1,31 @@
|
|||||||
|
//
|
||||||
|
// counter.c
|
||||||
|
//
|
||||||
|
// implements an up/down-Counter
|
||||||
|
//
|
||||||
|
// (C) R. Bonderer, HSR Hochschule Rapperswil, Okt. 2019
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "counter.h"
|
||||||
|
|
||||||
|
static int countValue;
|
||||||
|
|
||||||
|
void cnt_init(int val)
|
||||||
|
{
|
||||||
|
countValue = val;
|
||||||
|
}
|
||||||
|
|
||||||
|
void cnt_count(int step)
|
||||||
|
{
|
||||||
|
countValue += step;
|
||||||
|
}
|
||||||
|
|
||||||
|
int cnt_getCounter()
|
||||||
|
{
|
||||||
|
return countValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
void cnt_setCounter(int val)
|
||||||
|
{
|
||||||
|
countValue = val;
|
||||||
|
}
|
@ -0,0 +1,24 @@
|
|||||||
|
//
|
||||||
|
// counter.h
|
||||||
|
//
|
||||||
|
// implements an up/down-Counter
|
||||||
|
//
|
||||||
|
// (C) R. Bonderer, HSR Hochschule Rapperswil, Okt. 2019
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef COUNTER_H__
|
||||||
|
#define COUNTER_H__
|
||||||
|
|
||||||
|
void cnt_init(int val);
|
||||||
|
// initializes counter to val
|
||||||
|
|
||||||
|
void cnt_count(int step);
|
||||||
|
// counts the counter up (step>0) or down (step<0) by step
|
||||||
|
|
||||||
|
int cnt_getCounter();
|
||||||
|
// returns the counter value
|
||||||
|
|
||||||
|
void cnt_setCounter(int val);
|
||||||
|
// sets the counter to val
|
||||||
|
|
||||||
|
#endif
|
@ -0,0 +1,91 @@
|
|||||||
|
//
|
||||||
|
// counterCtrl.c
|
||||||
|
//
|
||||||
|
// implements the Finite State Machine (FSM) of an up/down-Counter
|
||||||
|
//
|
||||||
|
// (C) R. Bonderer, HSR Hochschule Rapperswil, Okt. 2019
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "counterCtrl.h"
|
||||||
|
#include "counter.h"
|
||||||
|
|
||||||
|
typedef enum {idleState, // idle state
|
||||||
|
countUpState, // counting up at each count event
|
||||||
|
countDownState} // counting down at each count event
|
||||||
|
State;
|
||||||
|
|
||||||
|
static State currentState = idleState; // holds the current state of the FSM
|
||||||
|
|
||||||
|
void cnt_ctrlInit(int initValue)
|
||||||
|
{
|
||||||
|
currentState = idleState;
|
||||||
|
cnt_init(initValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void cnt_ctrlProcess(cnt_Event e)
|
||||||
|
{
|
||||||
|
switch (currentState)
|
||||||
|
{
|
||||||
|
case idleState:
|
||||||
|
printf("State: idleState\n");
|
||||||
|
if (cnt_evUp == e)
|
||||||
|
{
|
||||||
|
// actions
|
||||||
|
printf("State: idleState, counter = %d\n", cnt_getCounter());
|
||||||
|
// state transition
|
||||||
|
printf("Changing to State: countUpState\n");
|
||||||
|
currentState = countUpState;
|
||||||
|
}
|
||||||
|
else if (cnt_evDown == e)
|
||||||
|
{
|
||||||
|
// actions
|
||||||
|
printf("State: idleState, counter = %d\n", cnt_getCounter());
|
||||||
|
// state transition
|
||||||
|
printf("Changing to State: countDownState\n");
|
||||||
|
currentState = countDownState;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case countUpState:
|
||||||
|
printf("State: countUpState\n");
|
||||||
|
if (cnt_evCount == e)
|
||||||
|
{
|
||||||
|
// actions
|
||||||
|
cnt_count(1);
|
||||||
|
printf("State: countUpState, counter = %d\n", cnt_getCounter());
|
||||||
|
// state transition
|
||||||
|
}
|
||||||
|
else if (cnt_evStop == e)
|
||||||
|
{
|
||||||
|
// actions
|
||||||
|
// state transition
|
||||||
|
printf("Changing to State: idleState\n");
|
||||||
|
currentState = idleState;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case countDownState:
|
||||||
|
printf("State: countDownState\n");
|
||||||
|
if (cnt_evCount == e)
|
||||||
|
{
|
||||||
|
// actions
|
||||||
|
cnt_count(-1);
|
||||||
|
printf("State: countDownState, counter = %d\n", cnt_getCounter());
|
||||||
|
// state transition
|
||||||
|
}
|
||||||
|
else if (cnt_evStop == e)
|
||||||
|
{
|
||||||
|
// actions
|
||||||
|
// state transition
|
||||||
|
printf("Changing to State: idleState\n");
|
||||||
|
currentState = idleState;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,25 @@
|
|||||||
|
//
|
||||||
|
// counterCtrl.h
|
||||||
|
//
|
||||||
|
// implements the Finite State Machine (FSM) of an up/down-Counter
|
||||||
|
//
|
||||||
|
// (C) R. Bonderer, HSR Hochschule Rapperswil, Oct. 2019
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef COUNTERCTRL_H__
|
||||||
|
#define COUNTERCTRL_H__
|
||||||
|
|
||||||
|
typedef enum {cnt_evUp, // count upwards
|
||||||
|
cnt_evDown, // count downwards
|
||||||
|
cnt_evCount, // count (up or down)
|
||||||
|
cnt_evStop} // stop counting
|
||||||
|
cnt_Event;
|
||||||
|
|
||||||
|
void cnt_ctrlInit(int initValue);
|
||||||
|
// initializes counter FSM
|
||||||
|
|
||||||
|
void cnt_ctrlProcess(cnt_Event e);
|
||||||
|
// changes the state of the FSM based on the event 'e'
|
||||||
|
// starts the actions
|
||||||
|
|
||||||
|
#endif
|
Binary file not shown.
@ -0,0 +1,53 @@
|
|||||||
|
//
|
||||||
|
// counterTest.c
|
||||||
|
//
|
||||||
|
// Test program for the Finite State Machine (FSM) of an up/down-Counter
|
||||||
|
//
|
||||||
|
// (C) R. Bonderer, HSR Hochschule Rapperswil, Oct. 2019
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "counterCtrl.h"
|
||||||
|
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
char answer;
|
||||||
|
|
||||||
|
cnt_ctrlInit(0);
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
printf("\n-------------------------------------------\n");
|
||||||
|
printf(" u Count up\n");
|
||||||
|
printf(" d Count down\n");
|
||||||
|
printf(" c Count\n");
|
||||||
|
printf(" s Stop counting\n");
|
||||||
|
printf(" q Quit\n");
|
||||||
|
|
||||||
|
printf("\nPlease press key: ");
|
||||||
|
scanf("%c", &answer);
|
||||||
|
getchar(); // nach scanf() ist noch ein '\n' im Inputbuffer: auslesen und wegwerfen
|
||||||
|
printf("\n");
|
||||||
|
|
||||||
|
switch (answer)
|
||||||
|
{
|
||||||
|
case 'u':
|
||||||
|
cnt_ctrlProcess(cnt_evUp);
|
||||||
|
break;
|
||||||
|
case 'd':
|
||||||
|
cnt_ctrlProcess(cnt_evDown);
|
||||||
|
break;
|
||||||
|
case 'c':
|
||||||
|
cnt_ctrlProcess(cnt_evCount);
|
||||||
|
break;
|
||||||
|
case 's':
|
||||||
|
cnt_ctrlProcess(cnt_evStop);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} while (answer != 'q');
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,53 @@
|
|||||||
|
//
|
||||||
|
// counterTest.c
|
||||||
|
//
|
||||||
|
// Test program for the Finite State Machine (FSM) of an up/down-Counter
|
||||||
|
//
|
||||||
|
// (C) R. Bonderer, HSR Hochschule Rapperswil, Oct. 2014
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "counterCtrl.h"
|
||||||
|
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
char answer;
|
||||||
|
|
||||||
|
cntCtrlInit(0);
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
printf("\n-------------------------------------------\n");
|
||||||
|
printf(" u Count up\n");
|
||||||
|
printf(" d Count down\n");
|
||||||
|
printf(" c Count\n");
|
||||||
|
printf(" s Stop counting\n");
|
||||||
|
printf(" q Quit\n");
|
||||||
|
|
||||||
|
printf("\nPlease press key: ");
|
||||||
|
scanf("%c", &answer);
|
||||||
|
// getchar(); // nach scanf() ist noch ein '\n' im Inputbuffer: auslesen und wegwerfen
|
||||||
|
printf("\n");
|
||||||
|
|
||||||
|
switch (answer)
|
||||||
|
{
|
||||||
|
case 'u':
|
||||||
|
cntCtrlProcess(cntEvUp);
|
||||||
|
break;
|
||||||
|
case 'd':
|
||||||
|
cntCtrlProcess(cntEvDown);
|
||||||
|
break;
|
||||||
|
case 'c':
|
||||||
|
cntCtrlProcess(cntEvCount);
|
||||||
|
break;
|
||||||
|
case 's':
|
||||||
|
cntCtrlProcess(cntEvStop);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} while (answer != 'q');
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,29 @@
|
|||||||
|
#
|
||||||
|
# Makefile fuer Counter-Programm
|
||||||
|
# File: makefile
|
||||||
|
# Reto Bonderer, 24.11.2010
|
||||||
|
#
|
||||||
|
CC = gcc
|
||||||
|
LINK = gcc
|
||||||
|
# '-pedantic' sorgt dafuer, dass gcc streng arbeitet
|
||||||
|
#CFLAGS = -c -pedantic
|
||||||
|
#LFLAGS = -pedantic
|
||||||
|
CFLAGS = -c -Wall
|
||||||
|
LFLAGS = -Wall
|
||||||
|
OBJS = counter.o counterCtrl.o counterTest.o
|
||||||
|
EXE = counterTest
|
||||||
|
|
||||||
|
$(EXE): $(OBJS)
|
||||||
|
$(LINK) $(LFLAGS) -o $(EXE) $(OBJS)
|
||||||
|
|
||||||
|
counterTest.o: counterTest.c counterCtrl.h
|
||||||
|
$(CC) $(CFLAGS) counterTest.c
|
||||||
|
|
||||||
|
counter.o: counter.c counter.h
|
||||||
|
$(CC) $(CFLAGS) counter.c
|
||||||
|
|
||||||
|
counterCtrl.o: counterCtrl.c counterCtrl.h counter.h
|
||||||
|
$(CC) $(CFLAGS) counterCtrl.c
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f $(EXE) $(OBJS)
|
@ -0,0 +1,28 @@
|
|||||||
|
//
|
||||||
|
// Counter.cpp
|
||||||
|
//
|
||||||
|
// implements an up/down-Counter
|
||||||
|
//
|
||||||
|
// (C) R. Bonderer, HSR Hochschule Rapperswil, Okt. 2017
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "Counter.h"
|
||||||
|
|
||||||
|
Counter::Counter(int val): countValue(val)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void Counter::count(int step)
|
||||||
|
{
|
||||||
|
countValue += step;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Counter::getCounter() const
|
||||||
|
{
|
||||||
|
return countValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Counter::setCounter(int val)
|
||||||
|
{
|
||||||
|
countValue = val;
|
||||||
|
}
|
@ -0,0 +1,29 @@
|
|||||||
|
//
|
||||||
|
// Counter.h
|
||||||
|
//
|
||||||
|
// implements an up/down-Counter
|
||||||
|
//
|
||||||
|
// (C) R. Bonderer, HSR Hochschule Rapperswil, Okt. 2017
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef COUNTER_H__
|
||||||
|
#define COUNTER_H__
|
||||||
|
|
||||||
|
class Counter
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Counter(int val = 0);
|
||||||
|
|
||||||
|
void count(int step);
|
||||||
|
// counts the counter up (step>0) or down (step<0) by step
|
||||||
|
|
||||||
|
int getCounter() const;
|
||||||
|
// returns the counter value
|
||||||
|
|
||||||
|
void setCounter(int val);
|
||||||
|
// sets the counter to val
|
||||||
|
private:
|
||||||
|
int countValue;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
@ -0,0 +1,84 @@
|
|||||||
|
//
|
||||||
|
// CounterCtrl.cpp
|
||||||
|
//
|
||||||
|
// implements the Finite State Machine (FSM) of an up/down-Counter
|
||||||
|
//
|
||||||
|
// (C) R. Bonderer, HSR Hochschule Rapperswil, Okt. 2017
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include "CounterCtrl.h"
|
||||||
|
#include "Counter.h"
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
CounterCtrl::CounterCtrl(int initValue) :
|
||||||
|
currentState(idleState),
|
||||||
|
myCounter(initValue)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void CounterCtrl::process(Event e)
|
||||||
|
{
|
||||||
|
switch (currentState)
|
||||||
|
{
|
||||||
|
case idleState:
|
||||||
|
cout << "State: idleState" << endl;
|
||||||
|
if (evUp == e)
|
||||||
|
{
|
||||||
|
// actions
|
||||||
|
cout << "State: idleState, counter = " << myCounter.getCounter() << endl;
|
||||||
|
// state transition
|
||||||
|
cout << "Changing to State: countUpState" << endl;
|
||||||
|
currentState = countUpState;
|
||||||
|
}
|
||||||
|
else if (evDown == e)
|
||||||
|
{
|
||||||
|
// actions
|
||||||
|
cout << "State: idleState, counter = " << myCounter.getCounter() << endl;
|
||||||
|
// state transition
|
||||||
|
cout << "Changing to State: countDownState" << endl;
|
||||||
|
currentState = countDownState;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case countUpState:
|
||||||
|
cout << "State: countUpState" << endl;
|
||||||
|
if (evCount == e)
|
||||||
|
{
|
||||||
|
// actions
|
||||||
|
myCounter.count(1);
|
||||||
|
cout << "State: countUpState, counter = " << myCounter.getCounter() << endl;
|
||||||
|
// state transition
|
||||||
|
}
|
||||||
|
else if (evStop == e)
|
||||||
|
{
|
||||||
|
// actions
|
||||||
|
// state transition
|
||||||
|
cout << "Changing to State: idleState" << endl;
|
||||||
|
currentState = idleState;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case countDownState:
|
||||||
|
cout << "State: countDownState" << endl;
|
||||||
|
if (evCount == e)
|
||||||
|
{
|
||||||
|
// actions
|
||||||
|
myCounter.count(-1);
|
||||||
|
cout << "State: countDownState, counter = " << myCounter.getCounter() << endl;
|
||||||
|
// state transition
|
||||||
|
}
|
||||||
|
else if (evStop == e)
|
||||||
|
{
|
||||||
|
// actions
|
||||||
|
// state transition
|
||||||
|
cout << "Changing to State: idleState" << endl;
|
||||||
|
currentState = idleState;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,33 @@
|
|||||||
|
//
|
||||||
|
// CounterCtrl.h
|
||||||
|
//
|
||||||
|
// implements the Finite State Machine (FSM) of an up/down-Counter
|
||||||
|
//
|
||||||
|
// (C) R. Bonderer, HSR Hochschule Rapperswil, Okt. 2017
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef COUNTERCTRL_H__
|
||||||
|
#define COUNTERCTRL_H__
|
||||||
|
#include "Counter.h"
|
||||||
|
|
||||||
|
class CounterCtrl
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
enum Event{evUp, // count upwards
|
||||||
|
evDown, // count downwards
|
||||||
|
evCount, // count (up or down)
|
||||||
|
evStop}; // stop counting
|
||||||
|
CounterCtrl(int initValue = 0);
|
||||||
|
void process(Event e);
|
||||||
|
// changes the state of the FSM based on the event 'e'
|
||||||
|
// starts the actions
|
||||||
|
|
||||||
|
private:
|
||||||
|
enum State{idleState, // idle state
|
||||||
|
countUpState, // counting up at each count event
|
||||||
|
countDownState}; // counting down at each count event
|
||||||
|
|
||||||
|
State currentState; // holds the current state of the FSM
|
||||||
|
Counter myCounter;
|
||||||
|
};
|
||||||
|
#endif
|
Binary file not shown.
@ -0,0 +1,52 @@
|
|||||||
|
//
|
||||||
|
// counterTest.cpp
|
||||||
|
//
|
||||||
|
// Test program for the Finite State Machine (FSM) of an up/down-Counter
|
||||||
|
//
|
||||||
|
// (C) R. Bonderer, HSR Hochschule Rapperswil, Oct. 2017
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include "CounterCtrl.h"
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
char answer;
|
||||||
|
CounterCtrl myFsm(0); // initValue of counter == 0
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
cout << endl << "-------------------------------------------" << endl;
|
||||||
|
cout << " u Count up" << endl;
|
||||||
|
cout << " d Count down" << endl;
|
||||||
|
cout << " c Count" << endl;
|
||||||
|
cout << " s Stop counting" << endl;
|
||||||
|
cout << " q Quit" << endl;
|
||||||
|
|
||||||
|
cout << endl << "Please press key: ";
|
||||||
|
cin >> answer;
|
||||||
|
cout << endl;
|
||||||
|
|
||||||
|
switch (answer)
|
||||||
|
{
|
||||||
|
case 'u':
|
||||||
|
myFsm.process(CounterCtrl::evUp);
|
||||||
|
break;
|
||||||
|
case 'd':
|
||||||
|
myFsm.process(CounterCtrl::evDown);
|
||||||
|
break;
|
||||||
|
case 'c':
|
||||||
|
myFsm.process(CounterCtrl::evCount);
|
||||||
|
break;
|
||||||
|
case 's':
|
||||||
|
myFsm.process(CounterCtrl::evStop);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} while (answer != 'q');
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
Binary file not shown.
@ -0,0 +1,26 @@
|
|||||||
|
#
|
||||||
|
# Makefile fuer Counter-Programm
|
||||||
|
# File: makefile
|
||||||
|
# Reto Bonderer, 23.10.2018
|
||||||
|
#
|
||||||
|
CC = g++
|
||||||
|
LINK = g++
|
||||||
|
CFLAGS = -c -Wall
|
||||||
|
LFLAGS = -Wall
|
||||||
|
OBJS = Counter.o CounterCtrl.o counterTest.o
|
||||||
|
EXE = counterTest
|
||||||
|
|
||||||
|
$(EXE): $(OBJS)
|
||||||
|
$(LINK) $(LFLAGS) -o $(EXE) $(OBJS)
|
||||||
|
|
||||||
|
counterTest.o: counterTest.cpp CounterCtrl.h
|
||||||
|
$(CC) $(CFLAGS) counterTest.cpp
|
||||||
|
|
||||||
|
Counter.o: Counter.cpp Counter.h
|
||||||
|
$(CC) $(CFLAGS) Counter.cpp
|
||||||
|
|
||||||
|
CounterCtrl.o: CounterCtrl.cpp CounterCtrl.h Counter.h
|
||||||
|
$(CC) $(CFLAGS) CounterCtrl.cpp
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f $(EXE) $(OBJS)
|
@ -0,0 +1,28 @@
|
|||||||
|
//
|
||||||
|
// Counter.cpp
|
||||||
|
//
|
||||||
|
// implements an up/down-Counter
|
||||||
|
//
|
||||||
|
// (C) R. Bonderer, HSR Hochschule Rapperswil, Okt. 2017
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "Counter.h"
|
||||||
|
|
||||||
|
Counter::Counter(int val): countValue(val)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void Counter::count(int step)
|
||||||
|
{
|
||||||
|
countValue += step;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Counter::getCounter() const
|
||||||
|
{
|
||||||
|
return countValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Counter::setCounter(int val)
|
||||||
|
{
|
||||||
|
countValue = val;
|
||||||
|
}
|
@ -0,0 +1,29 @@
|
|||||||
|
//
|
||||||
|
// Counter.h
|
||||||
|
//
|
||||||
|
// implements an up/down-Counter
|
||||||
|
//
|
||||||
|
// (C) R. Bonderer, HSR Hochschule Rapperswil, Okt. 2017
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef COUNTER_H__
|
||||||
|
#define COUNTER_H__
|
||||||
|
|
||||||
|
class Counter
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Counter(int val=0);
|
||||||
|
|
||||||
|
void count(int step);
|
||||||
|
// counts the counter up (step>0) or down (step<0) by step
|
||||||
|
|
||||||
|
int getCounter() const;
|
||||||
|
// returns the counter value
|
||||||
|
|
||||||
|
void setCounter(int val);
|
||||||
|
// sets the counter to val
|
||||||
|
private:
|
||||||
|
int countValue;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
@ -0,0 +1,22 @@
|
|||||||
|
//
|
||||||
|
// CounterCtrl.cpp
|
||||||
|
//
|
||||||
|
// implements the Finite State Machine (FSM) of an up/down-Counter
|
||||||
|
// CounterCtrl is the Context class in the State pattern
|
||||||
|
//
|
||||||
|
// (C) R. Bonderer, HSR Hochschule Rapperswil, Oct. 2017
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "CounterCtrl.h"
|
||||||
|
#include "CounterState.h"
|
||||||
|
|
||||||
|
CounterCtrl::CounterCtrl(int initValue):
|
||||||
|
entity(initValue),
|
||||||
|
pState(IdleState::getInstance()) // initial state
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void CounterCtrl::process(Event e)
|
||||||
|
{ // delegates all requests to CounterState
|
||||||
|
pState = pState->handle(entity, e);
|
||||||
|
}
|
@ -0,0 +1,31 @@
|
|||||||
|
//
|
||||||
|
// CounterCtrl.h
|
||||||
|
//
|
||||||
|
// implements the Finite State Machine (FSM) of an up/down-Counter
|
||||||
|
//
|
||||||
|
// (C) R. Bonderer, HSR Hochschule Rapperswil, Oct. 2017
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef COUNTERCTRL_H__
|
||||||
|
#define COUNTERCTRL_H__
|
||||||
|
#include "Counter.h"
|
||||||
|
|
||||||
|
class CounterState; // forward declaration
|
||||||
|
|
||||||
|
class CounterCtrl
|
||||||
|
// this is the 'Context' class of the State pattern
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
enum Event{evUp, // count upwards
|
||||||
|
evDown, // count downwards
|
||||||
|
evCount, // count (up or down)
|
||||||
|
evStop}; // stop counting
|
||||||
|
CounterCtrl(int initValue = 0);
|
||||||
|
void process(Event e);
|
||||||
|
// changes the state of the FSM based on the event 'e'
|
||||||
|
|
||||||
|
private:
|
||||||
|
Counter entity;
|
||||||
|
CounterState* pState; // holds the current state
|
||||||
|
};
|
||||||
|
#endif
|
@ -0,0 +1,102 @@
|
|||||||
|
//
|
||||||
|
// CounterState.cpp
|
||||||
|
//
|
||||||
|
// implements all states of an up/down-Counter
|
||||||
|
// this file contains all classes of the state machine.
|
||||||
|
// it may make sense to have separate files for each state
|
||||||
|
//
|
||||||
|
// (C) R. Bonderer, HSR Hochschule Rapperswil, Oct. 2017
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include "CounterState.h"
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
|
||||||
|
// class CounterState
|
||||||
|
CounterState* CounterState::changeState(Counter& entity, CounterState* pnewState)
|
||||||
|
{
|
||||||
|
return pnewState;
|
||||||
|
}
|
||||||
|
|
||||||
|
// class IdleState
|
||||||
|
IdleState IdleState::instance;
|
||||||
|
IdleState* IdleState::getInstance()
|
||||||
|
{
|
||||||
|
return &instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
CounterState* IdleState::handle(Counter& entity, CounterCtrl::Event e)
|
||||||
|
{
|
||||||
|
cout << "State: idleState" << endl;
|
||||||
|
if (CounterCtrl::evUp == e)
|
||||||
|
{
|
||||||
|
// transition actions
|
||||||
|
cout << "counter = " << entity.getCounter() << endl;
|
||||||
|
// state transition
|
||||||
|
return changeState(entity, CountUpState::getInstance());
|
||||||
|
}
|
||||||
|
else if (CounterCtrl::evDown == e)
|
||||||
|
{
|
||||||
|
// transition actions
|
||||||
|
cout << "counter = " << entity.getCounter() << endl;
|
||||||
|
// state transition
|
||||||
|
return changeState(entity, CountDownState::getInstance());
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
// class CountUpState
|
||||||
|
CountUpState CountUpState::instance;
|
||||||
|
CountUpState* CountUpState::getInstance()
|
||||||
|
{
|
||||||
|
return &instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
CounterState* CountUpState::handle(Counter& entity, CounterCtrl::Event e)
|
||||||
|
{
|
||||||
|
cout << "State: countUpState" << endl;
|
||||||
|
if (CounterCtrl::evCount == e)
|
||||||
|
{
|
||||||
|
// transition actions
|
||||||
|
entity.count(1);
|
||||||
|
cout << "counter = " << entity.getCounter() << endl;
|
||||||
|
// state transition
|
||||||
|
return changeState(entity, CountUpState::getInstance());
|
||||||
|
}
|
||||||
|
else if (CounterCtrl::evStop == e)
|
||||||
|
{
|
||||||
|
// transition actions
|
||||||
|
// state transition
|
||||||
|
return changeState(entity, IdleState::getInstance());
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// class CountDownState
|
||||||
|
CountDownState CountDownState::instance;
|
||||||
|
CountDownState* CountDownState::getInstance()
|
||||||
|
{
|
||||||
|
return &instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
CounterState* CountDownState::handle(Counter& entity, CounterCtrl::Event e)
|
||||||
|
{
|
||||||
|
cout << "State: countDownState" << endl;
|
||||||
|
if (CounterCtrl::evCount == e)
|
||||||
|
{
|
||||||
|
// transition actions
|
||||||
|
entity.count(-1);
|
||||||
|
cout << "counter = " << entity.getCounter() << endl;
|
||||||
|
// state transition
|
||||||
|
return changeState(entity, CountDownState::getInstance());
|
||||||
|
}
|
||||||
|
else if (CounterCtrl::evStop == e)
|
||||||
|
{
|
||||||
|
// transition actions
|
||||||
|
// state transition
|
||||||
|
return changeState(entity, IdleState::getInstance());
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
@ -0,0 +1,53 @@
|
|||||||
|
//
|
||||||
|
// CounterState.h
|
||||||
|
//
|
||||||
|
// implements an up/down-Counter
|
||||||
|
// this file contains all classes of the state machine
|
||||||
|
// it may make sense to have separate files for each state
|
||||||
|
//
|
||||||
|
// (C) R. Bonderer, HSR Hochschule Rapperswil, 21.10.2017
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef COUNTERSTATE_H__
|
||||||
|
#define COUNTERSTATE_H__
|
||||||
|
#include "CounterCtrl.h" // Events are defined here
|
||||||
|
|
||||||
|
class CounterState // abstract base class
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual CounterState* handle(Counter& entity, CounterCtrl::Event e) = 0;
|
||||||
|
// returns new state
|
||||||
|
protected: // only inherited classes may use these member functions
|
||||||
|
CounterState* changeState(Counter& entity, CounterState* pnewState);
|
||||||
|
};
|
||||||
|
|
||||||
|
class IdleState : public CounterState // it's a singleton
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static IdleState* getInstance();
|
||||||
|
virtual CounterState* handle(Counter& entity, CounterCtrl::Event e);
|
||||||
|
private:
|
||||||
|
IdleState() {};
|
||||||
|
static IdleState instance;
|
||||||
|
};
|
||||||
|
|
||||||
|
class CountUpState : public CounterState // it's a singleton
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static CountUpState* getInstance();
|
||||||
|
virtual CounterState* handle(Counter& entity, CounterCtrl::Event e);
|
||||||
|
private:
|
||||||
|
CountUpState() {};
|
||||||
|
static CountUpState instance;
|
||||||
|
};
|
||||||
|
|
||||||
|
class CountDownState : public CounterState // it's a singleton
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static CountDownState* getInstance();
|
||||||
|
virtual CounterState* handle(Counter& entity, CounterCtrl::Event e);
|
||||||
|
private:
|
||||||
|
CountDownState() {};
|
||||||
|
static CountDownState instance;
|
||||||
|
};
|
||||||
|
#endif
|
@ -0,0 +1,52 @@
|
|||||||
|
//
|
||||||
|
// counterTest.cpp
|
||||||
|
//
|
||||||
|
// Test program for the Finite State Machine (FSM) of an up/down-Counter
|
||||||
|
//
|
||||||
|
// (C) R. Bonderer, HSR Hochschule Rapperswil, Okt. 2017
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include "CounterCtrl.h"
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
char answer;
|
||||||
|
CounterCtrl myFsm;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
cout << endl << "-------------------------------------------" << endl;
|
||||||
|
cout << " u Count up" << endl;
|
||||||
|
cout << " d Count down" << endl;
|
||||||
|
cout << " c Count" << endl;
|
||||||
|
cout << " s Stop counting" << endl;
|
||||||
|
cout << " q Quit" << endl;
|
||||||
|
|
||||||
|
cout << endl << "Please press key: ";
|
||||||
|
cin >> answer;
|
||||||
|
cout << endl;
|
||||||
|
|
||||||
|
switch (answer)
|
||||||
|
{
|
||||||
|
case 'u':
|
||||||
|
myFsm.process(CounterCtrl::evUp);
|
||||||
|
break;
|
||||||
|
case 'd':
|
||||||
|
myFsm.process(CounterCtrl::evDown);
|
||||||
|
break;
|
||||||
|
case 'c':
|
||||||
|
myFsm.process(CounterCtrl::evCount);
|
||||||
|
break;
|
||||||
|
case 's':
|
||||||
|
myFsm.process(CounterCtrl::evStop);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} while (answer != 'q');
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
Binary file not shown.
@ -0,0 +1,29 @@
|
|||||||
|
#
|
||||||
|
# Makefile fuer Counter-Programm
|
||||||
|
# File: makefile
|
||||||
|
# Reto Bonderer, 21.10.2017
|
||||||
|
#
|
||||||
|
CC = g++
|
||||||
|
LINK = g++
|
||||||
|
# '-pedantic' sorgt dafuer, dass gcc streng arbeitet
|
||||||
|
CFLAGS = -c -pedantic -Wall
|
||||||
|
LFLAGS = -pedantic
|
||||||
|
OBJS = Counter.o CounterCtrl.o CounterState.o counterTest.o
|
||||||
|
|
||||||
|
counterTest: $(OBJS)
|
||||||
|
$(LINK) $(LFLAGS) -o counterTest $(OBJS)
|
||||||
|
|
||||||
|
counterTest.o: counterTest.cpp CounterCtrl.h
|
||||||
|
$(CC) $(CFLAGS) counterTest.cpp
|
||||||
|
|
||||||
|
Counter.o: Counter.cpp Counter.h
|
||||||
|
$(CC) $(CFLAGS) Counter.cpp
|
||||||
|
|
||||||
|
CounterCtrl.o: CounterCtrl.cpp CounterCtrl.h CounterState.h
|
||||||
|
$(CC) $(CFLAGS) CounterCtrl.cpp
|
||||||
|
|
||||||
|
CounterState.o: CounterState.cpp CounterState.h Counter.h CounterCtrl.h
|
||||||
|
$(CC) $(CFLAGS) CounterState.cpp
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f counterTest $(OBJS)
|
@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"files.associations": {
|
||||||
|
"xmemory": "cpp",
|
||||||
|
"xstring": "cpp"
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,28 @@
|
|||||||
|
//
|
||||||
|
// Counter.cpp
|
||||||
|
//
|
||||||
|
// implements an up/down-Counter
|
||||||
|
//
|
||||||
|
// (C) R. Bonderer, HSR Hochschule Rapperswil, Oct. 2017
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "Counter.h"
|
||||||
|
|
||||||
|
Counter::Counter(int val): countValue(val)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void Counter::count(int step)
|
||||||
|
{
|
||||||
|
countValue += step;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Counter::getCounter() const
|
||||||
|
{
|
||||||
|
return countValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Counter::setCounter(int val)
|
||||||
|
{
|
||||||
|
countValue = val;
|
||||||
|
}
|
@ -0,0 +1,29 @@
|
|||||||
|
//
|
||||||
|
// Counter.h
|
||||||
|
//
|
||||||
|
// implements an up/down-Counter
|
||||||
|
//
|
||||||
|
// (C) R. Bonderer, HSR Hochschule Rapperswil, Oct. 2017
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef COUNTER_H__
|
||||||
|
#define COUNTER_H__
|
||||||
|
|
||||||
|
class Counter
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Counter(int val=0);
|
||||||
|
|
||||||
|
void count(int step);
|
||||||
|
// counts the counter up (step>0) or down (step<0) by step
|
||||||
|
|
||||||
|
int getCounter() const;
|
||||||
|
// returns the counter value
|
||||||
|
|
||||||
|
void setCounter(int val);
|
||||||
|
// sets the counter to val
|
||||||
|
private:
|
||||||
|
int countValue;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
@ -0,0 +1,23 @@
|
|||||||
|
//
|
||||||
|
// CounterCtrl.cpp
|
||||||
|
//
|
||||||
|
// implements the Finite State Machine (FSM) of an up/down-Counter
|
||||||
|
// CounterCtrl is the Context class in the State pattern
|
||||||
|
//
|
||||||
|
// (C) R. Bonderer, HSR Hochschule Rapperswil, Oct. 2018
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "Counter.h"
|
||||||
|
#include "CounterState.h"
|
||||||
|
#include "CounterCtrl.h"
|
||||||
|
|
||||||
|
CounterCtrl::CounterCtrl(int initValue) :
|
||||||
|
entity(initValue),
|
||||||
|
pState(CounterState::init(entity)) // initial state
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void CounterCtrl::process(Event e)
|
||||||
|
{ // delegates all requests to CounterState
|
||||||
|
pState = pState->handle(entity, e); // entity: reference to entity class object
|
||||||
|
}
|
@ -0,0 +1,30 @@
|
|||||||
|
//
|
||||||
|
// CounterCtrl.h
|
||||||
|
//
|
||||||
|
// implements the Finite State Machine (FSM) of an up/down-Counter
|
||||||
|
//
|
||||||
|
// (C) R. Bonderer, HSR Hochschule Rapperswil, Oct. 2017
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef COUNTERCTRL_H__
|
||||||
|
#define COUNTERCTRL_H__
|
||||||
|
#include "Counter.h"
|
||||||
|
|
||||||
|
class CounterState; // forward declaration
|
||||||
|
|
||||||
|
class CounterCtrl
|
||||||
|
// this is the 'Context' class of the State pattern
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
enum Event{evUp, // count upwards
|
||||||
|
evDown, // count downwards
|
||||||
|
evCount, // count (up or down)
|
||||||
|
evStop}; // stop counting
|
||||||
|
CounterCtrl(int initValue = 0);
|
||||||
|
void process(Event e);
|
||||||
|
// changes the state of the FSM based on the event 'e'
|
||||||
|
private:
|
||||||
|
Counter entity; // entity class
|
||||||
|
CounterState* pState; // holds the current state
|
||||||
|
};
|
||||||
|
#endif
|
@ -0,0 +1,150 @@
|
|||||||
|
//
|
||||||
|
// CounterState.cpp
|
||||||
|
//
|
||||||
|
// implements all states of an up/down-Counter
|
||||||
|
// this file contains all classes of the state machine.
|
||||||
|
// it may make sense to have separate files for each state
|
||||||
|
//
|
||||||
|
// (C) R. Bonderer, HSR Hochschule Rapperswil, Oct. 2018
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include "CounterState.h"
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
|
||||||
|
//class CounterState
|
||||||
|
CounterState* CounterState::init(Counter& entity) // is static
|
||||||
|
{
|
||||||
|
CounterState* initState = IdleState::getInstance();
|
||||||
|
initState->entryAction(entity); // executes entry action into init state
|
||||||
|
return initState;
|
||||||
|
}
|
||||||
|
|
||||||
|
CounterState* CounterState::changeState(Counter& entity,
|
||||||
|
Action ptransAction,
|
||||||
|
CounterState* pnewState)
|
||||||
|
{
|
||||||
|
exitAction(entity); // polymorphic call of exit action
|
||||||
|
(this->*ptransAction)(entity); // call of transition action
|
||||||
|
pnewState->entryAction(entity); // polymorphic call of entry action
|
||||||
|
return pnewState;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CounterState::showCounter(Counter& entity)
|
||||||
|
{
|
||||||
|
cout << "counter = " << entity.getCounter() << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CounterState::countUp(Counter& entity)
|
||||||
|
{
|
||||||
|
entity.count(1);
|
||||||
|
cout << "counter = " << entity.getCounter() << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CounterState::countDown(Counter& entity)
|
||||||
|
{
|
||||||
|
entity.count(-1);
|
||||||
|
cout << "counter = " << entity.getCounter() << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// class IdleState
|
||||||
|
IdleState IdleState::instance;
|
||||||
|
IdleState* IdleState::getInstance()
|
||||||
|
{
|
||||||
|
return &instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
CounterState* IdleState::handle(Counter& entity, CounterCtrl::Event e)
|
||||||
|
{
|
||||||
|
cout << "State: idleState" << endl;
|
||||||
|
if (CounterCtrl::evUp == e)
|
||||||
|
{
|
||||||
|
// state transition
|
||||||
|
return changeState(entity, &IdleState::showCounter, CountUpState::getInstance());
|
||||||
|
}
|
||||||
|
else if (CounterCtrl::evDown == e)
|
||||||
|
{
|
||||||
|
// state transition
|
||||||
|
return changeState(entity, &IdleState::showCounter, CountDownState::getInstance());
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
void IdleState::entryAction(Counter& entity)
|
||||||
|
{
|
||||||
|
cout << "Entering idleState" << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
void IdleState::exitAction(Counter& entity)
|
||||||
|
{
|
||||||
|
cout << "Exiting from idleState" << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// class CountUpState
|
||||||
|
CountUpState CountUpState::instance;
|
||||||
|
CountUpState* CountUpState::getInstance()
|
||||||
|
{
|
||||||
|
return &instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
CounterState* CountUpState::handle(Counter& entity, CounterCtrl::Event e)
|
||||||
|
{
|
||||||
|
cout << "State: countUpState" << endl;
|
||||||
|
if (CounterCtrl::evCount == e)
|
||||||
|
{
|
||||||
|
// state transition
|
||||||
|
return changeState(entity, &CountUpState::countUp, CountUpState::getInstance());
|
||||||
|
}
|
||||||
|
else if (CounterCtrl::evStop == e)
|
||||||
|
{
|
||||||
|
// state transition
|
||||||
|
return changeState(entity, &CountUpState::emptyAction, IdleState::getInstance());
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CountUpState::entryAction(Counter& entity)
|
||||||
|
{
|
||||||
|
cout << "Entering countUpState" << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CountUpState::exitAction(Counter& entity)
|
||||||
|
{
|
||||||
|
cout << "Exiting from countUpState" << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
// class CountDownState
|
||||||
|
CountDownState CountDownState::instance;
|
||||||
|
CountDownState* CountDownState::getInstance()
|
||||||
|
{
|
||||||
|
return &instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
CounterState* CountDownState::handle(Counter& entity, CounterCtrl::Event e)
|
||||||
|
{
|
||||||
|
cout << "State: countDownState" << endl;
|
||||||
|
if (CounterCtrl::evCount == e)
|
||||||
|
{
|
||||||
|
// state transition
|
||||||
|
return changeState(entity, &CountDownState::countDown, CountDownState::getInstance());
|
||||||
|
}
|
||||||
|
else if (CounterCtrl::evStop == e)
|
||||||
|
{
|
||||||
|
// state transition
|
||||||
|
return changeState(entity, &CountDownState::emptyAction, IdleState::getInstance());
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CountDownState::entryAction(Counter& entity)
|
||||||
|
{
|
||||||
|
cout << "Entering countDownState" << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CountDownState::exitAction(Counter& entity)
|
||||||
|
{
|
||||||
|
cout << "Exiting from countDownState" << endl;
|
||||||
|
}
|
@ -0,0 +1,73 @@
|
|||||||
|
//
|
||||||
|
// CounterState.h
|
||||||
|
//
|
||||||
|
// implements an up/down-Counter
|
||||||
|
// this file contains all classes of the state machine
|
||||||
|
// it may make sense to have separate files for each state
|
||||||
|
//
|
||||||
|
// (C) R. Bonderer, HSR Hochschule Rapperswil, Oct. 2018
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef COUNTERSTATE_H__
|
||||||
|
#define COUNTERSTATE_H__
|
||||||
|
#include "CounterCtrl.h"
|
||||||
|
|
||||||
|
class CounterState // abstract base class
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static CounterState* init(Counter& entity);
|
||||||
|
// should be called first, returns new state
|
||||||
|
virtual CounterState* handle(Counter& entity, CounterCtrl::Event e) = 0;
|
||||||
|
// returns new state
|
||||||
|
protected:
|
||||||
|
virtual void entryAction(Counter& entity) {};
|
||||||
|
virtual void exitAction(Counter& entity) {};
|
||||||
|
typedef void (CounterState::*Action)(Counter& entity); // ptr to action function
|
||||||
|
CounterState* changeState(Counter& entity, Action ptransAction, CounterState* pnewState);
|
||||||
|
|
||||||
|
// transition actions
|
||||||
|
void emptyAction(Counter& entity) {};
|
||||||
|
void showCounter(Counter& entity);
|
||||||
|
void countUp(Counter& entity);
|
||||||
|
void countDown(Counter& entity);
|
||||||
|
};
|
||||||
|
|
||||||
|
class IdleState : public CounterState // it's a singleton
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static IdleState* getInstance();
|
||||||
|
virtual CounterState* handle(Counter& entity, CounterCtrl::Event e);
|
||||||
|
protected:
|
||||||
|
virtual void entryAction(Counter& entity);
|
||||||
|
virtual void exitAction(Counter& entity);
|
||||||
|
private:
|
||||||
|
IdleState() {};
|
||||||
|
static IdleState instance;
|
||||||
|
};
|
||||||
|
|
||||||
|
class CountUpState : public CounterState // it's a singleton
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static CountUpState* getInstance();
|
||||||
|
virtual CounterState* handle(Counter& entity, CounterCtrl::Event e);
|
||||||
|
protected:
|
||||||
|
virtual void entryAction(Counter& entity);
|
||||||
|
virtual void exitAction(Counter& entity);
|
||||||
|
private:
|
||||||
|
CountUpState() {};
|
||||||
|
static CountUpState instance;
|
||||||
|
};
|
||||||
|
|
||||||
|
class CountDownState : public CounterState // it's a singleton
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static CountDownState* getInstance();
|
||||||
|
virtual CounterState* handle(Counter& entity, CounterCtrl::Event e);
|
||||||
|
protected:
|
||||||
|
virtual void entryAction(Counter& entity);
|
||||||
|
virtual void exitAction(Counter& entity);
|
||||||
|
private:
|
||||||
|
CountDownState() {};
|
||||||
|
static CountDownState instance;
|
||||||
|
};
|
||||||
|
#endif
|
@ -0,0 +1,52 @@
|
|||||||
|
//
|
||||||
|
// counterTest.cpp
|
||||||
|
//
|
||||||
|
// Test program for the Finite State Machine (FSM) of an up/down-Counter
|
||||||
|
//
|
||||||
|
// (C) R. Bonderer, HSR Hochschule Rapperswil, Nov. 2017
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include "CounterCtrl.h"
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
char answer;
|
||||||
|
CounterCtrl myFsm;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
cout << endl << "-------------------------------------------" << endl;
|
||||||
|
cout << " u Count up" << endl;
|
||||||
|
cout << " d Count down" << endl;
|
||||||
|
cout << " c Count" << endl;
|
||||||
|
cout << " s Stop counting" << endl;
|
||||||
|
cout << " q Quit" << endl;
|
||||||
|
|
||||||
|
cout << endl << "Please press key: ";
|
||||||
|
cin >> answer;
|
||||||
|
cout << endl;
|
||||||
|
|
||||||
|
switch (answer)
|
||||||
|
{
|
||||||
|
case 'u':
|
||||||
|
myFsm.process(CounterCtrl::evUp);
|
||||||
|
break;
|
||||||
|
case 'd':
|
||||||
|
myFsm.process(CounterCtrl::evDown);
|
||||||
|
break;
|
||||||
|
case 'c':
|
||||||
|
myFsm.process(CounterCtrl::evCount);
|
||||||
|
break;
|
||||||
|
case 's':
|
||||||
|
myFsm.process(CounterCtrl::evStop);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} while (answer != 'q');
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,30 @@
|
|||||||
|
#
|
||||||
|
# Makefile fuer Counter-Programm
|
||||||
|
# File: makefile
|
||||||
|
# Reto Bonderer, 21.10.2017
|
||||||
|
#
|
||||||
|
CC = g++
|
||||||
|
LINK = g++
|
||||||
|
# '-pedantic' sorgt dafuer, dass g++ streng arbeitet
|
||||||
|
CFLAGS = -c -pedantic -Wall
|
||||||
|
LFLAGS = -pedantic
|
||||||
|
OBJS = Counter.o CounterCtrl.o CounterState.o counterTest.o
|
||||||
|
EXE = counterTest
|
||||||
|
|
||||||
|
$(EXE): $(OBJS)
|
||||||
|
$(LINK) $(LFLAGS) -o $(EXE) $(OBJS)
|
||||||
|
|
||||||
|
counterTest.o: counterTest.cpp CounterCtrl.h
|
||||||
|
$(CC) $(CFLAGS) counterTest.cpp
|
||||||
|
|
||||||
|
Counter.o: Counter.cpp Counter.h
|
||||||
|
$(CC) $(CFLAGS) Counter.cpp
|
||||||
|
|
||||||
|
CounterCtrl.o: CounterCtrl.cpp CounterCtrl.h CounterState.h
|
||||||
|
$(CC) $(CFLAGS) CounterCtrl.cpp
|
||||||
|
|
||||||
|
CounterState.o: CounterState.cpp CounterState.h Counter.h
|
||||||
|
$(CC) $(CFLAGS) CounterState.cpp
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f $(EXE) $(OBJS)
|
@ -0,0 +1,28 @@
|
|||||||
|
//
|
||||||
|
// Counter.cpp
|
||||||
|
//
|
||||||
|
// implements an up/down-Counter
|
||||||
|
//
|
||||||
|
// (C) R. Bonderer, HSR Hochschule Rapperswil, Okt. 2017
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "Counter.h"
|
||||||
|
|
||||||
|
Counter::Counter(int val): countValue(val)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void Counter::count(int step)
|
||||||
|
{
|
||||||
|
countValue += step;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Counter::getCounter() const
|
||||||
|
{
|
||||||
|
return countValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Counter::setCounter(int val)
|
||||||
|
{
|
||||||
|
countValue = val;
|
||||||
|
}
|
@ -0,0 +1,29 @@
|
|||||||
|
//
|
||||||
|
// Counter.h
|
||||||
|
//
|
||||||
|
// implements an up/down-Counter
|
||||||
|
//
|
||||||
|
// (C) R. Bonderer, HSR Hochschule Rapperswil, Okt. 2017
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef COUNTER_H__
|
||||||
|
#define COUNTER_H__
|
||||||
|
|
||||||
|
class Counter
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Counter(int val);
|
||||||
|
|
||||||
|
void count(int step);
|
||||||
|
// counts the counter up (step>0) or down (step<0) by step
|
||||||
|
|
||||||
|
int getCounter() const;
|
||||||
|
// returns the counter value
|
||||||
|
|
||||||
|
void setCounter(int val);
|
||||||
|
// sets the counter to val
|
||||||
|
private:
|
||||||
|
int countValue;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
@ -0,0 +1,104 @@
|
|||||||
|
//
|
||||||
|
// CounterCtrl.cpp
|
||||||
|
//
|
||||||
|
// implements the Finite State Machine (FSM) of an up/down-Counter as a table
|
||||||
|
//
|
||||||
|
// (C) R. Bonderer, HSR Hochschule Rapperswil, Okt. 2017
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include "CounterCtrl.h"
|
||||||
|
#include "Counter.h"
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
const CounterCtrl::Transition CounterCtrl::fsm[] = // this table defines the fsm
|
||||||
|
{//currentState checker function action function next state
|
||||||
|
{idleState, &CounterCtrl::checkIdleUp, &CounterCtrl::actionIdleUp, countUpState},
|
||||||
|
{idleState, &CounterCtrl::checkIdleDown, &CounterCtrl::actionIdleDown, countDownState},
|
||||||
|
{countUpState, &CounterCtrl::checkUpUp, &CounterCtrl::actionUpUp, countUpState},
|
||||||
|
{countUpState, &CounterCtrl::checkUpIdle, &CounterCtrl::actionUpIdle, idleState},
|
||||||
|
{countDownState, &CounterCtrl::checkDownDown, &CounterCtrl::actionDownDown, countDownState},
|
||||||
|
{countDownState, &CounterCtrl::checkDownIdle, &CounterCtrl::actionDownIdle, idleState}
|
||||||
|
};
|
||||||
|
|
||||||
|
CounterCtrl::CounterCtrl(int initValue) :
|
||||||
|
currentState(idleState),
|
||||||
|
myCounter(initValue)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void CounterCtrl::process(Event e) // this function never changes
|
||||||
|
{
|
||||||
|
for (size_t i = 0; i < sizeof(fsm) / sizeof(Transition); ++i) // let compiler determine number of transitions
|
||||||
|
{
|
||||||
|
if (fsm[i].currentState == currentState && // is there an entry in the table?
|
||||||
|
(this->*fsm[i].pChecker)(e))
|
||||||
|
{
|
||||||
|
(this->*fsm[i].pAction)();
|
||||||
|
currentState = fsm[i].nextState;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// check functions
|
||||||
|
bool CounterCtrl::checkIdleUp(Event e)
|
||||||
|
{
|
||||||
|
return evUp == e;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CounterCtrl::checkIdleDown(Event e)
|
||||||
|
{
|
||||||
|
return evDown == e;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CounterCtrl::checkUpIdle(Event e)
|
||||||
|
{
|
||||||
|
return evStop == e;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CounterCtrl::checkDownIdle(Event e)
|
||||||
|
{
|
||||||
|
return evStop == e;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CounterCtrl::checkUpUp(Event e)
|
||||||
|
{
|
||||||
|
return evCount == e;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CounterCtrl::checkDownDown(Event e)
|
||||||
|
{
|
||||||
|
return evCount == e;
|
||||||
|
}
|
||||||
|
|
||||||
|
// action functions
|
||||||
|
void CounterCtrl::actionIdleUp(void)
|
||||||
|
{
|
||||||
|
cout << "State: idleState, counter = " << myCounter.getCounter() << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CounterCtrl::actionIdleDown(void)
|
||||||
|
{
|
||||||
|
cout << "State: idleState, counter = " << myCounter.getCounter() << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CounterCtrl::actionUpIdle(void)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void CounterCtrl::actionDownIdle(void)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void CounterCtrl::actionUpUp(void)
|
||||||
|
{
|
||||||
|
myCounter.count(1);
|
||||||
|
cout << "State: countUpState, counter = " << myCounter.getCounter() << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CounterCtrl::actionDownDown(void)
|
||||||
|
{
|
||||||
|
myCounter.count(-1);
|
||||||
|
cout << "State: countDownState, counter = " << myCounter.getCounter() << endl;
|
||||||
|
}
|
@ -0,0 +1,60 @@
|
|||||||
|
//
|
||||||
|
// CounterCtrl.h
|
||||||
|
//
|
||||||
|
// implements the Finite State Machine (FSM) of an up/down-Counter as a table
|
||||||
|
//
|
||||||
|
// (C) R. Bonderer, HSR Hochschule Rapperswil, Okt. 2017
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef COUNTERCTRL_H__
|
||||||
|
#define COUNTERCTRL_H__
|
||||||
|
#include "Counter.h"
|
||||||
|
|
||||||
|
class CounterCtrl
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
enum Event{evUp, // count upwards
|
||||||
|
evDown, // count downwards
|
||||||
|
evCount, // count (up or down)
|
||||||
|
evStop}; // stop counting
|
||||||
|
CounterCtrl(int initValue = 0);
|
||||||
|
void process(Event e);
|
||||||
|
// changes the state of the FSM based on the event 'e'
|
||||||
|
// starts the actions
|
||||||
|
|
||||||
|
private:
|
||||||
|
enum State{idleState, // idle state
|
||||||
|
countUpState, // counting up at each count event
|
||||||
|
countDownState}; // counting down at each count event
|
||||||
|
|
||||||
|
State currentState; // holds the current state of the FSM
|
||||||
|
Counter myCounter;
|
||||||
|
|
||||||
|
typedef bool (CounterCtrl::*Checker)(Event); // function ptr for checker function
|
||||||
|
typedef void (CounterCtrl::*Action)(void); // function ptr for action function
|
||||||
|
// check functions
|
||||||
|
bool checkIdleUp(Event e);
|
||||||
|
bool checkIdleDown(Event e);
|
||||||
|
bool checkUpIdle(Event e);
|
||||||
|
bool checkDownIdle(Event e);
|
||||||
|
bool checkUpUp(Event e);
|
||||||
|
bool checkDownDown(Event e);
|
||||||
|
|
||||||
|
// action functions
|
||||||
|
void actionIdleUp(void);
|
||||||
|
void actionIdleDown(void);
|
||||||
|
void actionUpIdle(void);
|
||||||
|
void actionDownIdle(void);
|
||||||
|
void actionUpUp(void);
|
||||||
|
void actionDownDown(void);
|
||||||
|
|
||||||
|
struct Transition
|
||||||
|
{
|
||||||
|
State currentState; // current state
|
||||||
|
Checker pChecker; // pointer to checker function
|
||||||
|
Action pAction; // pointer to action function
|
||||||
|
State nextState; // next state
|
||||||
|
};
|
||||||
|
static const Transition fsm[];
|
||||||
|
};
|
||||||
|
#endif
|
Binary file not shown.
@ -0,0 +1,52 @@
|
|||||||
|
//
|
||||||
|
// counterTest.cpp
|
||||||
|
//
|
||||||
|
// Test program for the Finite State Machine (FSM) of an up/down-Counter
|
||||||
|
//
|
||||||
|
// (C) R. Bonderer, HSR Hochschule Rapperswil, Okt. 2017
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include "CounterCtrl.h"
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
char answer;
|
||||||
|
CounterCtrl myFsm(0);
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
cout << endl << "-------------------------------------------" << endl;
|
||||||
|
cout << " u Count up" << endl;
|
||||||
|
cout << " d Count down" << endl;
|
||||||
|
cout << " c Count" << endl;
|
||||||
|
cout << " s Stop counting" << endl;
|
||||||
|
cout << " q Quit" << endl;
|
||||||
|
|
||||||
|
cout << endl << "Please press key: ";
|
||||||
|
cin >> answer;
|
||||||
|
cout << endl;
|
||||||
|
|
||||||
|
switch (answer)
|
||||||
|
{
|
||||||
|
case 'u':
|
||||||
|
myFsm.process(CounterCtrl::evUp);
|
||||||
|
break;
|
||||||
|
case 'd':
|
||||||
|
myFsm.process(CounterCtrl::evDown);
|
||||||
|
break;
|
||||||
|
case 'c':
|
||||||
|
myFsm.process(CounterCtrl::evCount);
|
||||||
|
break;
|
||||||
|
case 's':
|
||||||
|
myFsm.process(CounterCtrl::evStop);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} while (answer != 'q');
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
Binary file not shown.
@ -0,0 +1,26 @@
|
|||||||
|
#
|
||||||
|
# Makefile fuer Counter-Programm
|
||||||
|
# File: makefile
|
||||||
|
# Reto Bonderer, 07.10.2017
|
||||||
|
#
|
||||||
|
CC = g++
|
||||||
|
LINK = g++
|
||||||
|
CFLAGS = -c -Wall
|
||||||
|
LFLAGS = -Wall
|
||||||
|
OBJS = Counter.o CounterCtrl.o counterTest.o
|
||||||
|
EXE = counterTest
|
||||||
|
|
||||||
|
$(EXE): $(OBJS)
|
||||||
|
$(LINK) $(LFLAGS) -o $(EXE) $(OBJS)
|
||||||
|
|
||||||
|
counterTest.o: counterTest.cpp CounterCtrl.h
|
||||||
|
$(CC) $(CFLAGS) counterTest.cpp
|
||||||
|
|
||||||
|
Counter.o: Counter.cpp Counter.h
|
||||||
|
$(CC) $(CFLAGS) Counter.cpp
|
||||||
|
|
||||||
|
CounterCtrl.o: CounterCtrl.cpp CounterCtrl.h Counter.h
|
||||||
|
$(CC) $(CFLAGS) CounterCtrl.cpp
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f $(EXE) $(OBJS)
|
@ -0,0 +1,28 @@
|
|||||||
|
//
|
||||||
|
// Counter.cpp
|
||||||
|
//
|
||||||
|
// implements an up/down-Counter
|
||||||
|
//
|
||||||
|
// (C) R. Bonderer, HSR Hochschule Rapperswil, Okt. 2017
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "Counter.h"
|
||||||
|
|
||||||
|
Counter::Counter(int val): countValue(val)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void Counter::count(int step)
|
||||||
|
{
|
||||||
|
countValue += step;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Counter::getCounter() const
|
||||||
|
{
|
||||||
|
return countValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Counter::setCounter(int val)
|
||||||
|
{
|
||||||
|
countValue = val;
|
||||||
|
}
|
@ -0,0 +1,29 @@
|
|||||||
|
//
|
||||||
|
// Counter.h
|
||||||
|
//
|
||||||
|
// implements an up/down-Counter
|
||||||
|
//
|
||||||
|
// (C) R. Bonderer, HSR Hochschule Rapperswil, Okt. 2017
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef COUNTER_H__
|
||||||
|
#define COUNTER_H__
|
||||||
|
|
||||||
|
class Counter
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Counter(int val);
|
||||||
|
|
||||||
|
void count(int step);
|
||||||
|
// counts the counter up (step>0) or down (step<0) by step
|
||||||
|
|
||||||
|
int getCounter() const;
|
||||||
|
// returns the counter value
|
||||||
|
|
||||||
|
void setCounter(int val);
|
||||||
|
// sets the counter to val
|
||||||
|
private:
|
||||||
|
int countValue;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
@ -0,0 +1,69 @@
|
|||||||
|
//
|
||||||
|
// CounterCtrl.cpp
|
||||||
|
//
|
||||||
|
// implements the Finite State Machine (FSM) of an up/down-Counter as a simple table
|
||||||
|
//
|
||||||
|
// (C) R. Bonderer, HSR Hochschule Rapperswil, Okt. 2017
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include "CounterCtrl.h"
|
||||||
|
#include "Counter.h"
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
const CounterCtrl::Transition CounterCtrl::fsm[] = // this table defines the fsm
|
||||||
|
{//currentState triggering event action function next state
|
||||||
|
{idleState, evUp, &CounterCtrl::actionIdleUp, countUpState},
|
||||||
|
{idleState, evDown, &CounterCtrl::actionIdleDown, countDownState},
|
||||||
|
{countUpState, evCount, &CounterCtrl::actionUpUp, countUpState},
|
||||||
|
{countUpState, evStop, &CounterCtrl::actionDoNothing, idleState},
|
||||||
|
{countDownState, evCount, &CounterCtrl::actionDownDown, countDownState},
|
||||||
|
{countDownState, evStop, &CounterCtrl::actionDoNothing, idleState}
|
||||||
|
};
|
||||||
|
|
||||||
|
CounterCtrl::CounterCtrl(int initValue) :
|
||||||
|
currentState(idleState),
|
||||||
|
myCounter(initValue)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void CounterCtrl::process(Event e) // execution engine, this function never changes
|
||||||
|
{
|
||||||
|
for (size_t i = 0; i < sizeof(fsm) / sizeof(Transition); ++i) // determine number of transitions automatically
|
||||||
|
{
|
||||||
|
if (fsm[i].currentState == currentState && fsm[i].ev == e) // is there an entry in the table?
|
||||||
|
{
|
||||||
|
(this->*fsm[i].pAction)();
|
||||||
|
currentState = fsm[i].nextState;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// action functions
|
||||||
|
void CounterCtrl::actionIdleUp(void)
|
||||||
|
{
|
||||||
|
cout << "State: idleState, counter = " << myCounter.getCounter() << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CounterCtrl::actionIdleDown(void)
|
||||||
|
{
|
||||||
|
cout << "State: idleState, counter = " << myCounter.getCounter() << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CounterCtrl::actionDoNothing(void)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void CounterCtrl::actionUpUp(void)
|
||||||
|
{
|
||||||
|
myCounter.count(1);
|
||||||
|
cout << "State: countUpState, counter = " << myCounter.getCounter() << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CounterCtrl::actionDownDown(void)
|
||||||
|
{
|
||||||
|
myCounter.count(-1);
|
||||||
|
cout << "State: countDownState, counter = " << myCounter.getCounter() << endl;
|
||||||
|
}
|
@ -0,0 +1,51 @@
|
|||||||
|
//
|
||||||
|
// CounterCtrl.h
|
||||||
|
//
|
||||||
|
// implements the Finite State Machine (FSM) of an up/down-Counter as a simple table
|
||||||
|
//
|
||||||
|
// (C) R. Bonderer, HSR Hochschule Rapperswil, Okt. 2017
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef COUNTERCTRL_H__
|
||||||
|
#define COUNTERCTRL_H__
|
||||||
|
#include "Counter.h"
|
||||||
|
|
||||||
|
class CounterCtrl
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
enum Event{evUp, // count upwards
|
||||||
|
evDown, // count downwards
|
||||||
|
evCount, // count (up or down)
|
||||||
|
evStop}; // stop counting
|
||||||
|
CounterCtrl(int initValue = 0);
|
||||||
|
void process(Event e);
|
||||||
|
// changes the state of the FSM based on the event 'e'
|
||||||
|
// starts the actions
|
||||||
|
|
||||||
|
private:
|
||||||
|
enum State{idleState, // idle state
|
||||||
|
countUpState, // counting up at each count event
|
||||||
|
countDownState}; // counting down at each count event
|
||||||
|
|
||||||
|
State currentState; // holds the current state of the FSM
|
||||||
|
Counter myCounter;
|
||||||
|
|
||||||
|
typedef void (CounterCtrl::*Action)(void); // function ptr for action function
|
||||||
|
|
||||||
|
// action functions
|
||||||
|
void actionIdleUp(void);
|
||||||
|
void actionIdleDown(void);
|
||||||
|
void actionDoNothing(void);
|
||||||
|
void actionUpUp(void);
|
||||||
|
void actionDownDown(void);
|
||||||
|
|
||||||
|
struct Transition
|
||||||
|
{
|
||||||
|
State currentState; // current state
|
||||||
|
Event ev; // event triggering the transition
|
||||||
|
Action pAction; // pointer to action function
|
||||||
|
State nextState; // next state
|
||||||
|
};
|
||||||
|
static const Transition fsm[];
|
||||||
|
};
|
||||||
|
#endif
|
Binary file not shown.
@ -0,0 +1,52 @@
|
|||||||
|
//
|
||||||
|
// counterTest.cpp
|
||||||
|
//
|
||||||
|
// Test program for the Finite State Machine (FSM) of an up/down-Counter
|
||||||
|
//
|
||||||
|
// (C) R. Bonderer, HSR Hochschule Rapperswil, Okt. 2017
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include "CounterCtrl.h"
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
char answer;
|
||||||
|
CounterCtrl myFsm;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
cout << endl << "-------------------------------------------" << endl;
|
||||||
|
cout << " u Count up" << endl;
|
||||||
|
cout << " d Count down" << endl;
|
||||||
|
cout << " c Count" << endl;
|
||||||
|
cout << " s Stop counting" << endl;
|
||||||
|
cout << " q Quit" << endl;
|
||||||
|
|
||||||
|
cout << endl << "Please press key: ";
|
||||||
|
cin >> answer;
|
||||||
|
cout << endl;
|
||||||
|
|
||||||
|
switch (answer)
|
||||||
|
{
|
||||||
|
case 'u':
|
||||||
|
myFsm.process(CounterCtrl::evUp);
|
||||||
|
break;
|
||||||
|
case 'd':
|
||||||
|
myFsm.process(CounterCtrl::evDown);
|
||||||
|
break;
|
||||||
|
case 'c':
|
||||||
|
myFsm.process(CounterCtrl::evCount);
|
||||||
|
break;
|
||||||
|
case 's':
|
||||||
|
myFsm.process(CounterCtrl::evStop);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} while (answer != 'q');
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,26 @@
|
|||||||
|
#
|
||||||
|
# Makefile fuer Counter-Programm
|
||||||
|
# File: makefile
|
||||||
|
# Reto Bonderer, 07.10.2017
|
||||||
|
#
|
||||||
|
CC = g++
|
||||||
|
LINK = g++
|
||||||
|
CFLAGS = -c -Wall
|
||||||
|
LFLAGS = -Wall
|
||||||
|
OBJS = Counter.o CounterCtrl.o counterTest.o
|
||||||
|
EXE = counterTest
|
||||||
|
|
||||||
|
$(EXE): $(OBJS)
|
||||||
|
$(LINK) $(LFLAGS) -o $(EXE) $(OBJS)
|
||||||
|
|
||||||
|
counterTest.o: counterTest.cpp CounterCtrl.h
|
||||||
|
$(CC) $(CFLAGS) counterTest.cpp
|
||||||
|
|
||||||
|
Counter.o: Counter.cpp Counter.h
|
||||||
|
$(CC) $(CFLAGS) Counter.cpp
|
||||||
|
|
||||||
|
CounterCtrl.o: CounterCtrl.cpp CounterCtrl.h Counter.h
|
||||||
|
$(CC) $(CFLAGS) CounterCtrl.cpp
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f $(EXE) $(OBJS)
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -0,0 +1,194 @@
|
|||||||
|
/*****************************************************************************/
|
||||||
|
/* STDINT.H v5.2.1 */
|
||||||
|
/* Copyright (c) 2002-2009 Texas Instruments Incorporated */
|
||||||
|
/*****************************************************************************/
|
||||||
|
#ifndef _STDINT_H_
|
||||||
|
#define _STDINT_H_
|
||||||
|
|
||||||
|
/* 7.18.1.1 Exact-width integer types */
|
||||||
|
|
||||||
|
typedef int int16_t;
|
||||||
|
typedef unsigned int uint16_t;
|
||||||
|
typedef long int32_t;
|
||||||
|
typedef unsigned long uint32_t;
|
||||||
|
|
||||||
|
|
||||||
|
#if defined(__TMS470__) || defined(_TMS320C6X) || defined(__TMS320C28X__)
|
||||||
|
typedef long long int64_t;
|
||||||
|
typedef unsigned long long uint64_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* 7.18.1.2 Minimum-width integer types */
|
||||||
|
|
||||||
|
typedef int16_t int_least8_t;
|
||||||
|
typedef uint16_t uint_least8_t;
|
||||||
|
|
||||||
|
typedef int16_t int_least16_t;
|
||||||
|
typedef uint16_t uint_least16_t;
|
||||||
|
typedef int32_t int_least32_t;
|
||||||
|
typedef uint32_t uint_least32_t;
|
||||||
|
|
||||||
|
|
||||||
|
#if defined(__TMS470__) || defined(_TMS320C6X) || defined(__TMS320C28X__)
|
||||||
|
typedef int64_t int_least64_t;
|
||||||
|
typedef uint64_t uint_least64_t;
|
||||||
|
#else
|
||||||
|
/* sorry, int_least64_t not implemented for C54x, C55x, MSP430 */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* 7.18.1.3 Fastest minimum-width integer types */
|
||||||
|
|
||||||
|
typedef int16_t int_fast8_t;
|
||||||
|
typedef uint16_t uint_fast8_t;
|
||||||
|
typedef int16_t int_fast16_t;
|
||||||
|
typedef uint16_t uint_fast16_t;
|
||||||
|
|
||||||
|
typedef int32_t int_fast32_t;
|
||||||
|
typedef uint32_t uint_fast32_t;
|
||||||
|
|
||||||
|
|
||||||
|
#if defined(__TMS470__) || defined(_TMS320C6X) || defined(__TMS320C28X__)
|
||||||
|
typedef int64_t int_fast64_t;
|
||||||
|
typedef uint64_t uint_fast64_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* 7.18.1.4 Integer types capable of holding object pointers */
|
||||||
|
typedef long intptr_t;
|
||||||
|
typedef unsigned long uintptr_t;
|
||||||
|
|
||||||
|
/* 7.18.1.5 Greatest-width integer types */
|
||||||
|
#if defined(__TMS320C55X__) || defined(__TMS470__) || defined(_TMS320C6X) || defined(__TMS320C28X__)
|
||||||
|
typedef long long intmax_t;
|
||||||
|
typedef unsigned long long uintmax_t;
|
||||||
|
#elif defined(_TMS320C5XX) || defined(__TMS320C27X__) || defined(__MSP430__)
|
||||||
|
typedef long intmax_t;
|
||||||
|
typedef unsigned long uintmax_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
According to footnotes in the 1999 C standard, "C++ implementations
|
||||||
|
should define these macros only when __STDC_LIMIT_MACROS is defined
|
||||||
|
before <stdint.h> is included."
|
||||||
|
*/
|
||||||
|
#if !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS)
|
||||||
|
|
||||||
|
/* 7.18.2 Limits of specified width integer types */
|
||||||
|
|
||||||
|
|
||||||
|
#define INT16_MAX 0x7fff
|
||||||
|
#define INT16_MIN (-INT16_MAX-1)
|
||||||
|
#define UINT16_MAX 0xffff
|
||||||
|
|
||||||
|
#define INT32_MAX 0x7fffffff
|
||||||
|
#define INT32_MIN (-INT32_MAX-1)
|
||||||
|
#define UINT32_MAX 0xffffffff
|
||||||
|
|
||||||
|
|
||||||
|
#if defined(__TMS470__) || defined(_TMS320C6X) || defined(__TMS320C28X__)
|
||||||
|
#define INT64_MAX 0x7fffffffffffffff
|
||||||
|
#define INT64_MIN (-INT64_MAX-1)
|
||||||
|
#define UINT64_MAX 0xffffffffffffffff
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define INT_LEAST8_MAX INT16_MAX
|
||||||
|
#define INT_LEAST8_MIN INT16_MIN
|
||||||
|
#define UINT_LEAST8_MAX UINT16_MAX
|
||||||
|
|
||||||
|
#define INT_LEAST16_MAX INT16_MAX
|
||||||
|
#define INT_LEAST16_MIN INT16_MIN
|
||||||
|
#define UINT_LEAST16_MAX UINT16_MAX
|
||||||
|
#define INT_LEAST32_MAX INT32_MAX
|
||||||
|
#define INT_LEAST32_MIN INT32_MIN
|
||||||
|
#define UINT_LEAST32_MAX UINT32_MAX
|
||||||
|
|
||||||
|
|
||||||
|
#if defined(__TMS470__) || defined(_TMS320C6X) || defined(__TMS320C28X__)
|
||||||
|
#define INT_LEAST64_MAX INT64_MAX
|
||||||
|
#define INT_LEAST64_MIN INT64_MIN
|
||||||
|
#define UINT_LEAST64_MAX UINT64_MAX
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define INT_FAST8_MAX INT16_MAX
|
||||||
|
#define INT_FAST8_MIN INT16_MIN
|
||||||
|
#define UINT_FAST8_MAX UINT16_MAX
|
||||||
|
#define INT_FAST16_MAX INT16_MAX
|
||||||
|
#define INT_FAST16_MIN INT16_MIN
|
||||||
|
#define UINT_FAST16_MAX UINT16_MAX
|
||||||
|
|
||||||
|
#define INT_FAST32_MAX INT32_MAX
|
||||||
|
#define INT_FAST32_MIN INT32_MIN
|
||||||
|
#define UINT_FAST32_MAX UINT32_MAX
|
||||||
|
|
||||||
|
|
||||||
|
#if defined(__TMS470__) || defined(_TMS320C6X) || defined(__TMS320C28X__)
|
||||||
|
#define INT_FAST64_MAX INT64_MAX
|
||||||
|
#define INT_FAST64_MIN INT64_MIN
|
||||||
|
#define UINT_FAST64_MAX UINT64_MAX
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define INTPTR_MAX INT32_MAX
|
||||||
|
#define INTPTR_MIN INT32_MIN
|
||||||
|
#define UINTPTR_MAX UINT32_MAX
|
||||||
|
|
||||||
|
#if defined(__TMS470__) || defined(_TMS320C6X) || defined(__TMS320C28X__)
|
||||||
|
#define INTMAX_MIN INT64_MIN
|
||||||
|
#define INTMAX_MAX INT64_MAX
|
||||||
|
#define UINTMAX_MAX UINT64_MAX
|
||||||
|
#elif defined(_TMS320C5XX) || defined(__TMS320C27X__) || defined(__MSP430__)
|
||||||
|
#define INTMAX_MIN INT32_MIN
|
||||||
|
#define INTMAX_MAX INT32_MAX
|
||||||
|
#define UINTMAX_MAX UINT32_MAX
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* 7.18.3 Limits of other integer types */
|
||||||
|
|
||||||
|
#define PTRDIFF_MAX INT32_MAX
|
||||||
|
#define PTRDIFF_MIN INT32_MIN
|
||||||
|
|
||||||
|
#define SIG_ATOMIC_MIN INT32_MIN
|
||||||
|
#define SIG_ATOMIC_MAX INT32_MAX
|
||||||
|
|
||||||
|
#define SIZE_MAX INT32_MAX
|
||||||
|
|
||||||
|
#ifndef WCHAR_MAX
|
||||||
|
#define WCHAR_MAX 0xffffu
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef WCHAR_MIN
|
||||||
|
#define WCHAR_MIN 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define WINT_MIN INT32_MIN
|
||||||
|
#define WINT_MAX INT32_MAX
|
||||||
|
|
||||||
|
/* 7.18.4.1 Macros for minimum-width integer constants */
|
||||||
|
|
||||||
|
/*
|
||||||
|
There is a defect report filed against the C99 standard concerning how
|
||||||
|
the (U)INTN_C macros should be implemented. Please refer to --
|
||||||
|
http://wwwold.dkuug.dk/JTC1/SC22/WG14/www/docs/dr_209.htm
|
||||||
|
for more information. These macros are implemented according to the
|
||||||
|
suggestion given at this web site.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define INT8_C(value) ((int_least8_t)(value))
|
||||||
|
#define UINT8_C(value) ((uint_least8_t)(value))
|
||||||
|
#define INT16_C(value) ((int_least16_t)(value))
|
||||||
|
#define UINT16_C(value) ((uint_least16_t)(value))
|
||||||
|
#define INT32_C(value) ((int_least32_t)(value))
|
||||||
|
#define UINT32_C(value) ((uint_least32_t)(value))
|
||||||
|
|
||||||
|
|
||||||
|
#if defined(__TMS470__) || defined(_TMS320C6X) || defined(__TMS320C28X__)
|
||||||
|
#define INT64_C(value) ((int_least64_t)(value))
|
||||||
|
#define UINT64_C(value) ((uint_least64_t)(value))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* 7.18.4.2 Macros for greatest-width integer constants */
|
||||||
|
|
||||||
|
#define INTMAX_C(value) ((intmax_t)(value))
|
||||||
|
#define UINTMAX_C(value) ((uintmax_t)(value))
|
||||||
|
|
||||||
|
#endif /* !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS) */
|
||||||
|
|
||||||
|
#endif /* _STDINT_H_ */
|
Loading…
Reference in new issue