/** * @author RĂ©mi Heredero * @version 1.0.0 * @date July 2023 * @file blinker.c */ #include "blinker.h" void BLINKER_init(BLINKER* me){ me->state = STBL_INIT; me->timeOn = 500; me->timeOff = 500; me->numberOfBlink = 3; me->nBlinkIsOn = false; me->remainBlinks = 3; me->wait.f = NULL; me->on.f = NULL; me->off.f = NULL; me->finished.f = NULL; } void BLINKER_startBehaviour(BLINKER* me) { POST(me, &BLINKER_processEvent, evBLinit, 0, 0); } bool BLINKER_processEvent(Event* ev) { bool processed = false; BLINKER* me = (BLINKER*)Event_getTarget(ev); BLINKER_STATES oldState = me->state; evIDT evid = Event_getId(ev); switch (me->state) { // onState case STBL_INIT: if (ev->id == evBLinit) { me->state = STBL_WAIT; } break; case STBL_WAIT: me->remainBlinks = me->numberOfBlink; if(evid == evBLblinkN) { me->state = STBL_ON; me->nBlinkIsOn = true; BLINKER_emitTimer(me, me->timeOn); } if(evid == evBLblink) { me->state = STBL_ON; me->nBlinkIsOn = false; BLINKER_emitTimer(me, me->timeOn); } break; case STBL_ON: if (me->nBlinkIsOn) { me->remainBlinks = (me->remainBlinks) - 1; } if (evid == evBLtimer) { me->state = STBL_OFF; BLINKER_emitTimer(me, me->timeOff); } break; case STBL_OFF: if (evid == evBLtimer) { if (me->remainBlinks == 0) { me->state = STBL_WAIT; if (me->finished.f != NULL) { me->finished.f(me->finished.p); } } else { me->state = STBL_ON; BLINKER_emitTimer(me, me->timeOn); } } break; } if(oldState != me->state){ switch (oldState) { // onExit case STBL_INIT: break; case STBL_WAIT: break; case STBL_ON: break; case STBL_OFF: break; } switch (me->state) { // onEntry case STBL_INIT: break; case STBL_WAIT: if (me->wait.f != NULL) { me->wait.f(me->wait.p); } break; case STBL_ON: if (me->on.f != NULL) { me->on.f(me->on.p); } break; case STBL_OFF: if (me->off.f != NULL) { me->off.f(me->off.p); } break; } processed = true; } return processed; } /************* * Callbacks * *************/ void BLINKER_onWait(BLINKER* me, BLINKER_CALLBACK_FUNCTION f, void* p) { me->wait.f = f; me->wait.p = p; } void BLINKER_onOn(BLINKER* me, BLINKER_CALLBACK_FUNCTION f, void* p) { me->on.f = f; me->on.p = p; } void BLINKER_onOff(BLINKER* me, BLINKER_CALLBACK_FUNCTION f, void* p) { me->off.f = f; me->off.p = p; } void BLINKER_onFinished(BLINKER* me, BLINKER_CALLBACK_FUNCTION f, void* p) { me->finished.f = f; me->finished.p = p; } /************ * EMITTERS * ************/ void BLINKER_emitBlink(BLINKER* me, uint16_t t) { POST(me, &BLINKER_processEvent, evBLblink, t, 0); } void BLINKER_emitBlinkN(BLINKER* me, uint16_t t) { POST(me, &BLINKER_processEvent, evBLblinkN, t, 0); } void BLINKER_emitTimer(BLINKER* me, uint16_t t) { POST(me, &BLINKER_processEvent, evBLtimer, t, 0); } /*********** * SETTERS * ***********/ void BLINKER_setTimeOn(BLINKER* me, uint16_t v) { me->timeOn = v; } void BLINKER_setTimeOff(BLINKER* me, uint16_t v) { me->timeOff = v; } void BLINKER_setNumberOfBlink(BLINKER* me, uint8_t v) { me->numberOfBlink = v; } void BLINKER_setNBlinkIsOn(BLINKER* me, bool v) { me->nBlinkIsOn = v; } void BLINKER_setRemainBlinks(BLINKER* me, uint8_t v) { me->remainBlinks = v; } void BLINKER_endBlink(BLINKER* me) { me->remainBlinks = 0; }