diff --git a/nbproject/configurations.xml b/nbproject/configurations.xml index b239181..09f6cc3 100644 --- a/nbproject/configurations.xml +++ b/nbproject/configurations.xml @@ -22,8 +22,8 @@ src/mcc_generated_files/device_config.h - src/middleware/clickHandler.h src/middleware/blinker.h + src/middleware/click_handler.h src/xf/ireactive.h @@ -58,7 +58,7 @@ src/middleware/blinker.c - src/middleware/clickHandler.c + src/middleware/click_handler.c src/xf/xf.c @@ -200,6 +200,9 @@ + + + diff --git a/src/middleware/click_handler.c b/src/middleware/click_handler.c new file mode 100644 index 0000000..32a227e --- /dev/null +++ b/src/middleware/click_handler.c @@ -0,0 +1,177 @@ +/** + * @author Rémi Heredero + * @version 1.0.0 + * @date July 2023 + * @file click_handler.c + */ + +#include "click_handler.h" + +void CLICK_HANDLER_init(CLICK_HANDLER* me){ + me->state = STCH_INIT; + me->clickTimer = 250; + me->wait.f = NULL; + me->long_click.f = NULL; + me->single_click.f = NULL; + me->double_click.f = NULL; +} + +void CLICK_HANDLER_startBehaviour(CLICK_HANDLER* me){ + POST(me, &CLICK_HANDLER_processEvent, evCHinit, 0, 0); +} + +bool CLICK_HANDLER_processEvent(Event* ev) { + bool processed = false; + CLICK_HANDLER* me = (CLICK_HANDLER*)Event_getTarget(ev); + CLICK_HANDLER_STATES oldState = me->state; + evIDT evid = Event_getId(ev); + + switch (me->state) { // onState + case STCH_INIT: + if (ev->id == evCHinit) { + me->state = STCH_WAIT; + } + break; + + case STCH_WAIT: + if(evid == evCHpbpress) { + me->state = STCH_LONG_CLICK; + CLICK_HANDLER_emitTimer(me, me->clickTimer); + } + break; + + case STCH_LONG_CLICK: + if(evid == evCHpbrelease) { + me->state = STCH_SINGLE_CLICK; + } + if(evid == evCHtimer) { + me->state = STCH_WAIT; + } + break; + + case STCH_SINGLE_CLICK: + if(evid == evCHpbpress) { + me->state = STCH_DOUBLE_CLICK; + } + if(evid == evCHtimer) { + me->state = STCH_WAIT; + } + break; + + case STCH_DOUBLE_CLICK: + if(evid == evCHpbrelease) { + me->state = STCH_WAIT; + } + if(evid == evCHtimer) { + me->state = STCH_WAIT; + } + break; + } + + if(oldState != me->state){ + switch (oldState) { // onExit + case STCH_INIT: + break; + + case STCH_WAIT: + break; + + case STCH_LONG_CLICK: + if(evid == evCHtimer) { + if (me->long_click.f != NULL) { + me->long_click.f(me->long_click.p); + } + } + break; + + case STCH_SINGLE_CLICK: + if(evid == evCHtimer) { + if (me->single_click.f != NULL) { + me->single_click.f(me->single_click.p); + } + } + break; + + case STCH_DOUBLE_CLICK: + if(evid == evCHtimer) { + if(me->double_click.f != NULL) { + me->double_click.f(me->double_click.p); + } + } + if(evid == evCHpbrelease) { + if(me->double_click.f != NULL) { + me->double_click.f(me->double_click.p); + } + } + break; + } + + switch (me->state) { // onEntry + case STCH_INIT: + break; + + case STCH_WAIT: + break; + + case STCH_LONG_CLICK: + break; + + case STCH_SINGLE_CLICK: + break; + + case STCH_DOUBLE_CLICK: + break; + } + + processed = true; + } + return processed; +} + +/************* + * Callbacks * + *************/ + +void CLICK_HANDLER_onWait(CLICK_HANDLER* me, CLICK_HANDLER_CALLBACK_FUNCTION f, void* p) { + me->wait.f = f; + me->wait.p = p; +} + +void CLICK_HANDLER_onLong_click(CLICK_HANDLER* me, CLICK_HANDLER_CALLBACK_FUNCTION f, void* p) { + me->long_click.f = f; + me->long_click.p = p; +} + +void CLICK_HANDLER_onSingle_click(CLICK_HANDLER* me, CLICK_HANDLER_CALLBACK_FUNCTION f, void* p) { + me->single_click.f = f; + me->single_click.p = p; +} + +void CLICK_HANDLER_onDouble_click(CLICK_HANDLER* me, CLICK_HANDLER_CALLBACK_FUNCTION f, void* p) { + me->double_click.f = f; + me->double_click.p = p; +} + +/************ + * EMITTERS * + ************/ + +void CLICK_HANDLER_emitTimer(CLICK_HANDLER* me, uint16_t t) { + POST(me, &CLICK_HANDLER_processEvent, evCHtimer, t, 0); +} + +void CLICK_HANDLER_emitPbpress(CLICK_HANDLER* me, uint16_t t) { + POST(me, &CLICK_HANDLER_processEvent, evCHpbpress, t, 0); +} + +void CLICK_HANDLER_emitPbrelease(CLICK_HANDLER* me, uint16_t t) { + POST(me, &CLICK_HANDLER_processEvent, evCHpbrelease, t, 0); +} + +/*********** + * SETTERS * + ***********/ + +void CLICK_HANDLER_setClickTimer(CLICK_HANDLER* me, uint16_t v) { + me->clickTimer = v; +} diff --git a/src/middleware/click_handler.h b/src/middleware/click_handler.h new file mode 100644 index 0000000..a79b8a0 --- /dev/null +++ b/src/middleware/click_handler.h @@ -0,0 +1,125 @@ +/** + * @author Rémi Heredero + * @version 1.0.0 + * @date July 2023 + * @file click_handler.h + */ +#ifndef CLICK_HANDLER_H +#define CLICK_HANDLER_H + +#include "../xf/xf.h" + +typedef enum { + STCH_INIT, + STCH_WAIT, + STCH_LONG_CLICK, + STCH_SINGLE_CLICK, + STCH_DOUBLE_CLICK +} CLICK_HANDLER_STATES; + +typedef enum { + evCHinit = 100, + evCHtimer, + evCHpbpress, + evCHpbrelease +} CLICK_HANDLER_EVENTS; + +typedef void (*CLICK_HANDLER_CALLBACK_FUNCTION)(void*); +typedef struct { + CLICK_HANDLER_CALLBACK_FUNCTION f; // function + void* p; // param(s) +} CLICK_HANDLER_CALLBACK; + +typedef struct { + CLICK_HANDLER_STATES state; + uint16_t clickTimer; + CLICK_HANDLER_CALLBACK wait; + CLICK_HANDLER_CALLBACK long_click; + CLICK_HANDLER_CALLBACK single_click; + CLICK_HANDLER_CALLBACK double_click; +} CLICK_HANDLER; + +/** + * Initialize the CLICK_HANDLER + * @param me the CLICK_HANDLER itself + */ +void CLICK_HANDLER_init(CLICK_HANDLER* me); + +/** + * Start the CLICK_HANDLER state machine + * @param me the CLICK_HANDLER itself + */ +void CLICK_HANDLER_startBehaviour(CLICK_HANDLER* me); + +/** + * Process the event + * @param ev the event to process + * @return true if the event is processed + */ +bool CLICK_HANDLER_processEvent(Event* ev); + +/************* + * Callbacks * + *************/ + +/** + * Set the callback function to call when the CLICK_HANDLER is entering state wait + * @param me the CLICK_HANDLER itself + * @param f the function to call + * @param p the param(s) to pass to the function + */ +void CLICK_HANDLER_onWait(CLICK_HANDLER* me, CLICK_HANDLER_CALLBACK_FUNCTION f, void* p); + +/** + * Set the callback function to call when the CLICK_HANDLER is entering state long_click + * @param me the CLICK_HANDLER itself + * @param f the function to call + * @param p the param(s) to pass to the function + */ +void CLICK_HANDLER_onLong_click(CLICK_HANDLER* me, CLICK_HANDLER_CALLBACK_FUNCTION f, void* p); + +/** + * Set the callback function to call when the CLICK_HANDLER is entering state single_click + * @param me the CLICK_HANDLER itself + * @param f the function to call + * @param p the param(s) to pass to the function + */ +void CLICK_HANDLER_onSingle_click(CLICK_HANDLER* me, CLICK_HANDLER_CALLBACK_FUNCTION f, void* p); + +/** + * Set the callback function to call when the CLICK_HANDLER is entering state double_click + * @param me the CLICK_HANDLER itself + * @param f the function to call + * @param p the param(s) to pass to the function + */ +void CLICK_HANDLER_onDouble_click(CLICK_HANDLER* me, CLICK_HANDLER_CALLBACK_FUNCTION f, void* p); + +/************ + * EMITTERS * + ************/ + +/** + * Emit the timer event + * @param me the CLICK_HANDLER itself + * @param t time to wait in ms before triggering event + */void CLICK_HANDLER_emitTimer(CLICK_HANDLER* me, uint16_t t); + +/** + * Emit the pbpress event + * @param me the CLICK_HANDLER itself + * @param t time to wait in ms before triggering event + */void CLICK_HANDLER_emitPbpress(CLICK_HANDLER* me, uint16_t t); + +/** + * Emit the pbrelease event + * @param me the CLICK_HANDLER itself + * @param t time to wait in ms before triggering event + */void CLICK_HANDLER_emitPbrelease(CLICK_HANDLER* me, uint16_t t); + +/*********** + * SETTERS * + ***********/ + +void CLICK_HANDLER_setClickTimer(CLICK_HANDLER* me, uint16_t v); + +#endif