加入状态机
This commit is contained in:
@@ -48,6 +48,7 @@ void fifo_clear(fifo_t* self){
|
|||||||
self->read_idx = self->write_idx = 0;
|
self->read_idx = self->write_idx = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
OS_STATIC_FORCE_INLINE
|
OS_STATIC_FORCE_INLINE
|
||||||
os_bool_t fifo_is_empty(fifo_t* self){
|
os_bool_t fifo_is_empty(fifo_t* self){
|
||||||
return (self->write_idx==self->read_idx);
|
return (self->write_idx==self->read_idx);
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
#include <gai_action.h>
|
||||||
@@ -0,0 +1,81 @@
|
|||||||
|
#ifndef INCLUDED_GAI_ACTION_H
|
||||||
|
#define INCLUDED_GAI_ACTION_H
|
||||||
|
|
||||||
|
#ifndef INCLUDED_OS_TYPES_H
|
||||||
|
#include <os_types.h>
|
||||||
|
#endif /*INCLUDED_OS_TYPES_H*/
|
||||||
|
|
||||||
|
#ifndef INCLUDED_OS_COMPILER_H
|
||||||
|
#include <os_compiler.h>
|
||||||
|
#endif /*INCLUDED_OS_COMPILER_H*/
|
||||||
|
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------------------------------------------------ */
|
||||||
|
/* */
|
||||||
|
|
||||||
|
typedef struct gai_action_t gai_action_t;
|
||||||
|
typedef void (*gai_action_function_t)(gai_action_t* self);
|
||||||
|
typedef void (*gai_action_update_function_t)(gai_action_t* self, void* params);
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
kGaiActionStatus_UnInitialized=0,
|
||||||
|
kGaiActionStatus_Running,
|
||||||
|
kGaiActionStatus_Terminated,
|
||||||
|
}gai_action_status_t;
|
||||||
|
|
||||||
|
struct gai_action_t{
|
||||||
|
gai_action_status_t status;
|
||||||
|
gai_action_function_t onInitialize;
|
||||||
|
gai_action_update_function_t onUpdate;
|
||||||
|
gai_action_function_t onCleanup;
|
||||||
|
void* userdata;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------------------------------------------------ */
|
||||||
|
/* */
|
||||||
|
|
||||||
|
OS_STATIC_FORCE_INLINE
|
||||||
|
void gai_action_init(gai_action_t* self,
|
||||||
|
gai_action_function_t onInitialize,
|
||||||
|
gai_action_update_function_t onUpdate,
|
||||||
|
gai_action_function_t onCleanup, void* userdata){
|
||||||
|
self->status = kGaiActionStatus_UnInitialized;
|
||||||
|
self->onInitialize = onInitialize;
|
||||||
|
self->onUpdate = onUpdate;
|
||||||
|
self->onCleanup = onCleanup;
|
||||||
|
self->userdata = userdata;
|
||||||
|
}
|
||||||
|
|
||||||
|
OS_STATIC_FORCE_INLINE
|
||||||
|
void gai_action_Initialize(gai_action_t* self){
|
||||||
|
if(self->onInitialize){
|
||||||
|
self->onInitialize(self);
|
||||||
|
}
|
||||||
|
self->status = kGaiActionStatus_Running;
|
||||||
|
}
|
||||||
|
|
||||||
|
OS_STATIC_FORCE_INLINE
|
||||||
|
gai_action_status_t gai_action_Update(gai_action_t* self, void* userdata){
|
||||||
|
if(self->status==kGaiActionStatus_Terminated){
|
||||||
|
return kGaiActionStatus_Terminated;
|
||||||
|
}
|
||||||
|
if(self->onUpdate){
|
||||||
|
self->onUpdate(self, userdata);
|
||||||
|
}else{
|
||||||
|
self->status = kGaiActionStatus_Terminated;
|
||||||
|
}
|
||||||
|
return self->status;
|
||||||
|
}
|
||||||
|
|
||||||
|
OS_STATIC_FORCE_INLINE
|
||||||
|
void gai_action_Cleanup(gai_action_t* self){
|
||||||
|
if(self->status == kGaiActionStatus_Terminated){
|
||||||
|
if(self->onCleanup){
|
||||||
|
self->onCleanup(self);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self->status = kGaiActionStatus_UnInitialized;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif /*INCLUDED_GAI_ACTION_H*/
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
#include <gai_fsm.h>
|
||||||
|
|
||||||
|
static os_int_t FindNextState(gai_fsm_t* self, os_list_t* transitions, void* ud){
|
||||||
|
os_list_node_t * p_node = 0;
|
||||||
|
for(p_node = transitions->next; p_node!=transitions; p_node= p_node->next){
|
||||||
|
gai_fsm_transition_t* p_transition = os_list_member_of(p_node, gai_fsm_transition_t, node);
|
||||||
|
if(p_transition->evaluator(self, p_transition, ud)){
|
||||||
|
return p_transition->to_state_id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void gai_fsm_update(gai_fsm_t* self, void* userdata){
|
||||||
|
if(!self->current_state_p){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
gai_action_status_t status = gai_fsm_status(self);
|
||||||
|
if(status==kGaiActionStatus_Running){
|
||||||
|
gai_action_Update(&self->current_state_p->action, userdata);
|
||||||
|
}else if(status==kGaiActionStatus_Terminated){
|
||||||
|
os_int_t to_state_id = FindNextState(self, &self->current_state_p->transition_list, userdata);
|
||||||
|
gai_fsm_state_t* p_next_state = gai_fsm_find_state(self, to_state_id);
|
||||||
|
if(p_next_state){
|
||||||
|
gai_action_Cleanup(&self->current_state_p->action);
|
||||||
|
self->current_state_p = p_next_state;
|
||||||
|
gai_action_Initialize(&self->current_state_p->action);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,180 @@
|
|||||||
|
#ifndef INCLUDED_GAI_FSM_H
|
||||||
|
#define INCLUDED_GAI_FSM_H
|
||||||
|
|
||||||
|
#ifndef INCLUDED_OS_TYPES_H
|
||||||
|
#include <os_types.h>
|
||||||
|
#endif /*INCLUDED_OS_TYPES_H*/
|
||||||
|
|
||||||
|
#ifndef INCLUDED_OS_COMPILER_H
|
||||||
|
#include <os_compiler.h>
|
||||||
|
#endif /*INCLUDED_OS_COMPILER_H*/
|
||||||
|
|
||||||
|
#ifndef INCLUDED_OS_LIST_H
|
||||||
|
#include <os_list.h>
|
||||||
|
#endif /*INCLUDED_OS_LIST_H*/
|
||||||
|
|
||||||
|
#ifndef INCLUDED_GAI_ACTION_H
|
||||||
|
#include <gai_action.h>
|
||||||
|
#endif /*INCLUDED_GAI_ACTION_H*/
|
||||||
|
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------------------------------------------------ */
|
||||||
|
/* */
|
||||||
|
|
||||||
|
typedef struct gai_fsm_state_t gai_fsm_state_t;
|
||||||
|
typedef struct gai_fsm_transition_t gai_fsm_transition_t;
|
||||||
|
typedef struct gai_fsm_t gai_fsm_t;
|
||||||
|
|
||||||
|
typedef os_bool_t (*gai_fsm_evaluator_t)(gai_fsm_t* self, gai_fsm_transition_t* transition, void* ud);
|
||||||
|
|
||||||
|
struct gai_fsm_state_t{
|
||||||
|
os_list_node_t node;
|
||||||
|
os_int_t id;
|
||||||
|
os_list_t transition_list;
|
||||||
|
gai_action_t action;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct gai_fsm_transition_t{
|
||||||
|
os_list_node_t node;
|
||||||
|
os_int_t from_state_id;
|
||||||
|
os_int_t to_state_id;
|
||||||
|
gai_fsm_evaluator_t evaluator;
|
||||||
|
void* userdata;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct gai_fsm_t{
|
||||||
|
gai_fsm_state_t* current_state_p;
|
||||||
|
os_list_t state_list;
|
||||||
|
void* userdata;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------------------------------------------------ */
|
||||||
|
/* */
|
||||||
|
|
||||||
|
OS_STATIC_FORCE_INLINE
|
||||||
|
void gai_fsm_init(gai_fsm_t* self, void* userdata){
|
||||||
|
self->current_state_p = 0;
|
||||||
|
os_list_init(&self->state_list);
|
||||||
|
self->userdata = userdata;
|
||||||
|
}
|
||||||
|
|
||||||
|
OS_STATIC_FORCE_INLINE
|
||||||
|
void gai_fsm_add_state(gai_fsm_t* self, gai_fsm_state_t * state){
|
||||||
|
os_list_insert_after(&self->state_list, &state->node);
|
||||||
|
}
|
||||||
|
|
||||||
|
OS_STATIC_FORCE_INLINE
|
||||||
|
void gai_fsm_add_transition(gai_fsm_t* self, gai_fsm_transition_t* transition){
|
||||||
|
os_list_node_t* p_node;
|
||||||
|
for(p_node = self->state_list.next; p_node!=&self->state_list; p_node = p_node->next){
|
||||||
|
gai_fsm_state_t* p_state = os_list_member_of(p_node, gai_fsm_state_t, node);
|
||||||
|
if(transition->from_state_id != p_state->id){
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
os_list_insert_after(&p_state->transition_list, &transition->node);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
OS_STATIC_FORCE_INLINE
|
||||||
|
gai_action_status_t gai_fsm_status(gai_fsm_t* self){
|
||||||
|
if(self->current_state_p){
|
||||||
|
return self->current_state_p->action.status;
|
||||||
|
}
|
||||||
|
return kGaiActionStatus_UnInitialized;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
OS_STATIC_FORCE_INLINE
|
||||||
|
gai_fsm_transition_t* gai_fsm_find_transition(gai_fsm_t* self, os_int_t from_state_id, os_int_t to_state_id){
|
||||||
|
gai_fsm_state_t * p_from_state = 0;
|
||||||
|
os_list_node_t* p_node;
|
||||||
|
for(p_node = self->state_list.next; p_node!=&self->state_list; p_node = p_node->next){
|
||||||
|
gai_fsm_state_t* p_state = os_list_member_of(p_node, gai_fsm_state_t, node);
|
||||||
|
if(p_state->id==from_state_id){
|
||||||
|
p_from_state = p_state;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(p_from_state==0){
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
for(p_node = p_from_state->transition_list.next; p_node!=&p_from_state->transition_list; p_node= p_node->next){
|
||||||
|
gai_fsm_transition_t* p_transition = os_list_member_of(p_node, gai_fsm_transition_t, node);
|
||||||
|
if(p_transition->to_state_id == to_state_id){
|
||||||
|
return p_transition;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
OS_STATIC_FORCE_INLINE
|
||||||
|
gai_fsm_state_t* gai_fsm_find_state(gai_fsm_t* self, os_int_t state_id){
|
||||||
|
os_list_node_t* p_node;
|
||||||
|
for(p_node = self->state_list.next; p_node!=&self->state_list; p_node = p_node->next){
|
||||||
|
gai_fsm_state_t* p_state = os_list_member_of(p_node, gai_fsm_state_t, node);
|
||||||
|
if(p_state->id==state_id){
|
||||||
|
return p_state;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
OS_STATIC_FORCE_INLINE
|
||||||
|
os_bool_t gai_fsm_has_transition(gai_fsm_t* self, os_int_t from_state_id, os_int_t to_state_id){
|
||||||
|
return (gai_fsm_find_transition(self, from_state_id, to_state_id)!=0)?OS_TRUE:OS_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
OS_STATIC_FORCE_INLINE
|
||||||
|
os_bool_t gai_fsm_has_state(gai_fsm_t* self, os_int_t state_id){
|
||||||
|
return (gai_fsm_find_state(self, state_id)!=0)?OS_TRUE:OS_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
OS_STATIC_FORCE_INLINE
|
||||||
|
void gai_fsm_set_state(gai_fsm_t* self, os_int_t state_id){
|
||||||
|
gai_fsm_state_t* p_state = gai_fsm_find_state(self, state_id);
|
||||||
|
if(p_state==0){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
gai_action_Cleanup(&p_state->action);
|
||||||
|
self->current_state_p = p_state;
|
||||||
|
gai_action_Initialize(&p_state->action);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------------------------------------------------ */
|
||||||
|
/* */
|
||||||
|
|
||||||
|
OS_STATIC_FORCE_INLINE
|
||||||
|
void gai_fsm_state_init(gai_fsm_state_t* self, os_int_t id,
|
||||||
|
gai_action_function_t onInitialize,
|
||||||
|
gai_action_update_function_t onUpdate,
|
||||||
|
gai_action_function_t onCleanup, void* userdata){
|
||||||
|
os_list_init(&self->node);
|
||||||
|
self->id = id;
|
||||||
|
os_list_init(&self->transition_list);
|
||||||
|
gai_action_init(&self->action, onInitialize, onUpdate, onCleanup, userdata);
|
||||||
|
}
|
||||||
|
|
||||||
|
OS_STATIC_FORCE_INLINE
|
||||||
|
void gai_fsm_transition_init(gai_fsm_transition_t* self,
|
||||||
|
os_int_t from_state_id,
|
||||||
|
os_int_t to_state_id,
|
||||||
|
gai_fsm_evaluator_t evaluator,
|
||||||
|
void* userdata){
|
||||||
|
self->evaluator = evaluator;
|
||||||
|
self->from_state_id = from_state_id;
|
||||||
|
self->to_state_id = to_state_id;
|
||||||
|
os_list_init(&self->node);
|
||||||
|
self->userdata = userdata;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------------------------------------------------ */
|
||||||
|
/* */
|
||||||
|
|
||||||
|
|
||||||
|
void gai_fsm_update(gai_fsm_t* self, void* userdata);
|
||||||
|
|
||||||
|
#endif /*INCLUDED_GAI_FSM_H*/
|
||||||
@@ -69,10 +69,13 @@ void os_systick_tick(void){
|
|||||||
|
|
||||||
OS_STATIC_FORCE_INLINE
|
OS_STATIC_FORCE_INLINE
|
||||||
os_tick_t os_systick_get(void){
|
os_tick_t os_systick_get(void){
|
||||||
|
#if 0
|
||||||
os_critical_enter();
|
os_critical_enter();
|
||||||
os_tick_t ticks = g_os_systick_ticks;
|
os_tick_t ticks = g_os_systick_ticks;
|
||||||
os_critical_leave();
|
os_critical_leave();
|
||||||
return ticks;
|
return ticks;
|
||||||
|
#endif
|
||||||
|
return g_os_systick_ticks;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user