summaryrefslogtreecommitdiffstats
path: root/branches/1.0/tinySAK/src/tsk_fsm.h
blob: b7639aa77e67b0b06d5661cf1ed383e1498a1ad3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
/*
* Copyright (C) 2009-2010 Mamadou Diop.
*
* Contact: Mamadou Diop <diopmamadou(at)doubango.org>
*	
* This file is part of Open Source Doubango Framework.
*
* DOUBANGO is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*	
* DOUBANGO 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 General Public License for more details.
*	
* You should have received a copy of the GNU General Public License
* along with DOUBANGO.
*
*/

/**@file tsk_fsm.h
 * @brief Finite-state machine (FSM) implementation.
 * @sa http://en.wikipedia.org/wiki/Finite-state_machine.
 *
 * @author Mamadou Diop <diopmamadou(at)doubango.org>
 *
 * @date Created: Sat Nov 8 16:54:58 2009 mdiop
 */
#ifndef _TINYSAK_FSM_H_
#define _TINYSAK_FSM_H_

#include "tinysak_config.h"
#include "tsk_list.h"
#include "tsk_safeobj.h"

/**@ingroup tsk_fsm_group
* @def TSK_FSM_ONTERMINATED
*/

TSK_BEGIN_DECLS

#define TSK_FSM_ONTERMINATED_F(self)				(tsk_fsm_onterminated_f)(self)

/**@ingroup tsk_fsm_group
* @def tsk_fsm_state_any
*/
/**@ingroup tsk_fsm_group
* @def tsk_fsm_state_default
*/
/**@ingroup tsk_fsm_group
* @def tsk_fsm_state_none
*/
/**@ingroup tsk_fsm_group
* @def tsk_fsm_state_final
*/
#define tsk_fsm_state_any -0xFFFF
#define tsk_fsm_state_default -0xFFF0
#define tsk_fsm_state_none -0xFF00
#define tsk_fsm_state_final -0xF000

/**@ingroup tsk_fsm_group
* @def tsk_fsm_action_any
*/
#define tsk_fsm_action_any -0xFFFF

/**@ingroup tsk_fsm_group
* @def tsk_fsm_state_id_t
*/
/**@ingroup tsk_fsm_group
* @def tsk_fsm_action_id_t
*/
/**@ingroup tsk_fsm_group
* @def tsk_fsm_cond
*/
/**@ingroup tsk_fsm_group
* @def tsk_fsm_exec
*/
/**@ingroup tsk_fsm_group
* @def tsk_fsm_onterminated
*/

typedef int tsk_fsm_state_id;
typedef int tsk_fsm_action_id;
typedef tsk_bool_t (*tsk_fsm_cond)(const void*, const void*);
typedef int (*tsk_fsm_exec)(va_list *app);
typedef int (*tsk_fsm_onterminated_f)(const void*);


/**@ingroup tsk_fsm_group
* @def TSK_FSM_ADD
*/
/**@ingroup tsk_fsm_group
* @def TSK_FSM_ADD_ALWAYS
*/
/**@ingroup tsk_fsm_group
* @def TSK_FSM_ADD_NOTHING
*/
/**@ingroup tsk_fsm_group
* @def TSK_FSM_ADD_ALWAYS_NOTHING
*/
/**@ingroup tsk_fsm_group
* @def TSK_FSM_ADD_DEFAULT
*/
/**@ingroup tsk_fsm_group
* @def TSK_FSM_ADD_NULL
*/
#define TSK_FSM_ADD(from, action, cond, to, exec, desc)\
	1,\
	(tsk_fsm_state_id)from, \
	(tsk_fsm_action_id)action, \
	(tsk_fsm_cond)cond, \
	(tsk_fsm_state_id)to, \
	(tsk_fsm_exec)exec, \
	(const char*)desc
#define TSK_FSM_ADD_ALWAYS(from, action, to, exec, desc) TSK_FSM_ADD(from, action, tsk_fsm_cond_always, to, exec, desc)
#define TSK_FSM_ADD_NOTHING(from, action, cond, desc) TSK_FSM_ADD(from, action, cond, from, tsk_fsm_exec_nothing, desc)
#define TSK_FSM_ADD_ALWAYS_NOTHING(from, desc)	TSK_FSM_ADD(from, tsk_fsm_action_any, tsk_fsm_cond_always, from, tsk_fsm_exec_nothing, desc)
#define TSK_FSM_ADD_DEFAULT()
#define TSK_FSM_ADD_NULL()\
	tsk_null

/**@ingroup tsk_fsm_group
* FSM entry.
*/
typedef struct tsk_fsm_entry_s
{
	TSK_DECLARE_OBJECT;

	tsk_fsm_state_id from;
	tsk_fsm_action_id action;
	tsk_fsm_cond cond;
	tsk_fsm_state_id to;
	tsk_fsm_exec exec;
	const char* desc;
}
tsk_fsm_entry_t;

/**@ingroup tsk_fsm_group
* List of @ref tsk_fsm_entry_t elements. 
*/
typedef tsk_list_t tsk_fsm_entries_L_t;

/**@ingroup tsk_fsm_group
* FSM.
*/
typedef struct tsk_fsm_s
{
	TSK_DECLARE_OBJECT;

	unsigned debug:1;
	tsk_fsm_state_id current;
	tsk_fsm_state_id term;
	tsk_fsm_entries_L_t* entries;

	tsk_fsm_onterminated_f callback_term;
	const void* callback_data;

	TSK_DECLARE_SAFEOBJ;
}
tsk_fsm_t;

TINYSAK_API tsk_fsm_t* tsk_fsm_create(tsk_fsm_state_id state_curr, tsk_fsm_state_id state_term);

TINYSAK_API int tsk_fsm_exec_nothing(va_list *app);
TINYSAK_API tsk_bool_t tsk_fsm_cond_always(const void*, const void*);
TINYSAK_API int tsk_fsm_set(tsk_fsm_t* self, ...);
TINYSAK_API int tsk_fsm_set_callback_terminated(tsk_fsm_t* self, tsk_fsm_onterminated_f callback, const void* callbackdata);
TINYSAK_API int tsk_fsm_act(tsk_fsm_t* self, tsk_fsm_action_id action, const void* cond_data1, const void* cond_data2, ...);
TINYSAK_API tsk_bool_t tsk_fsm_terminated(tsk_fsm_t* self);

TINYSAK_GEXTERN const tsk_object_def_t *tsk_fsm_def_t;
TINYSAK_GEXTERN const tsk_object_def_t *tsk_fsm_entry_def_t;

TSK_END_DECLS

#endif /* _TINYSAK_FSM_H_ */
OpenPOWER on IntegriCloud