diff --git a/AppKit/fifo.h b/AppKit/fifo.h index 576caf5..0794224 100644 --- a/AppKit/fifo.h +++ b/AppKit/fifo.h @@ -48,6 +48,7 @@ void fifo_clear(fifo_t* self){ self->read_idx = self->write_idx = 0; } + OS_STATIC_FORCE_INLINE os_bool_t fifo_is_empty(fifo_t* self){ return (self->write_idx==self->read_idx); diff --git a/AppKit/gai_action.c b/AppKit/gai_action.c new file mode 100644 index 0000000..56f7775 --- /dev/null +++ b/AppKit/gai_action.c @@ -0,0 +1 @@ +#include diff --git a/AppKit/gai_action.h b/AppKit/gai_action.h new file mode 100644 index 0000000..3266008 --- /dev/null +++ b/AppKit/gai_action.h @@ -0,0 +1,81 @@ +#ifndef INCLUDED_GAI_ACTION_H +#define INCLUDED_GAI_ACTION_H + +#ifndef INCLUDED_OS_TYPES_H +#include +#endif /*INCLUDED_OS_TYPES_H*/ + +#ifndef INCLUDED_OS_COMPILER_H +#include +#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*/ diff --git a/AppKit/gai_fsm.c b/AppKit/gai_fsm.c new file mode 100644 index 0000000..4405658 --- /dev/null +++ b/AppKit/gai_fsm.c @@ -0,0 +1,31 @@ +#include + +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); + } + } +} + diff --git a/AppKit/gai_fsm.h b/AppKit/gai_fsm.h new file mode 100644 index 0000000..2d9bffd --- /dev/null +++ b/AppKit/gai_fsm.h @@ -0,0 +1,180 @@ +#ifndef INCLUDED_GAI_FSM_H +#define INCLUDED_GAI_FSM_H + +#ifndef INCLUDED_OS_TYPES_H +#include +#endif /*INCLUDED_OS_TYPES_H*/ + +#ifndef INCLUDED_OS_COMPILER_H +#include +#endif /*INCLUDED_OS_COMPILER_H*/ + +#ifndef INCLUDED_OS_LIST_H +#include +#endif /*INCLUDED_OS_LIST_H*/ + +#ifndef INCLUDED_GAI_ACTION_H +#include +#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*/ diff --git a/Kernel/SingleCore/os_systick.h b/Kernel/SingleCore/os_systick.h index a488b4c..60e6af3 100644 --- a/Kernel/SingleCore/os_systick.h +++ b/Kernel/SingleCore/os_systick.h @@ -69,10 +69,13 @@ void os_systick_tick(void){ OS_STATIC_FORCE_INLINE os_tick_t os_systick_get(void){ +#if 0 os_critical_enter(); os_tick_t ticks = g_os_systick_ticks; os_critical_leave(); return ticks; +#endif + return g_os_systick_ticks; }