XF upgrade

This commit is contained in:
Rémi Heredero 2023-11-26 20:19:58 +01:00
parent dc2dc5c58b
commit 0d07b98cfd
11 changed files with 235 additions and 172 deletions

View File

@ -29,13 +29,15 @@ XFEventStatus ButtonEventsLogger::processEvent() {
int evid = ev->getId(); int evid = ev->getId();
oldState_ = curentState_; oldState_ = curentState_;
changeState = false; changeXFState = false;
switch (curentState_) { //on state switch (curentState_) { //on state
case state::initial: case state::initial:
if(evType == XFEvent::Initial) { if(evType == XFEvent::Initial) {
curentState_ = state::waitButtonPressed; curentState_ = state::waitButtonPressed;
changeState = true; changeXFState = true;
eventStatus = XFEventStatus::Consumed; eventStatus = XFEventStatus::Consumed;
} }
break; break;
@ -44,19 +46,19 @@ XFEventStatus ButtonEventsLogger::processEvent() {
if(evid == event::evButtonShortPressed){ if(evid == event::evButtonShortPressed){
Trace::out("ButtonEventLogger: Button %d short pressed", ev->getButtonId()); Trace::out("ButtonEventLogger: Button %d short pressed", ev->getButtonId());
curentState_ = state::waitButtonPressed; curentState_ = state::waitButtonPressed;
changeState = true; changeXFState = true;
eventStatus = XFEventStatus::Consumed; eventStatus = XFEventStatus::Consumed;
} }
if(evid == event::evButtonLongPressed){ if(evid == event::evButtonLongPressed){
Trace::out("ButtonEventLogger: Button %d long pressed", ev->getButtonId()); Trace::out("ButtonEventLogger: Button %d long pressed", ev->getButtonId());
curentState_ = state::waitButtonPressed; curentState_ = state::waitButtonPressed;
changeState = true; changeXFState = true;
eventStatus = XFEventStatus::Consumed; eventStatus = XFEventStatus::Consumed;
} }
break; break;
} }
if(changeState) { if(changeXFState) {
switch (oldState_) { // onExit switch (oldState_) { // onExit
case state::initial: case state::initial:
break; break;
@ -73,7 +75,7 @@ XFEventStatus ButtonEventsLogger::processEvent() {
break; break;
} }
changeState = false; changeXFState = false;
} }
return eventStatus; return eventStatus;
} }

View File

@ -10,6 +10,7 @@
#include "xf/behavior.h" #include "xf/behavior.h"
#include "interface/buttoneventshandlerobserver.h" #include "interface/buttoneventshandlerobserver.h"
#include "xf/XFState.h"
class ButtonEventsLogger : public XFBehavior, public interface::ButtonEventsHandlerObserver { class ButtonEventsLogger : public XFBehavior, public interface::ButtonEventsHandlerObserver {
public: public:
@ -23,7 +24,7 @@ protected:
XFEventStatus processEvent() override; XFEventStatus processEvent() override;
typedef enum { typedef enum {
evButtonShortPressed, evButtonShortPressed = 1,
evButtonLongPressed evButtonLongPressed
} event; } event;
@ -32,11 +33,8 @@ protected:
waitButtonPressed waitButtonPressed
} state; } state;
// TODO changeState and put next variable on behavior
state curentState_; state curentState_;
state oldState_; state oldState_;
bool changeState = false;
}; };

View File

@ -10,10 +10,22 @@
#include "board/ButtonsController.h" #include "board/ButtonsController.h"
ButtonEventsHandler::ButtonEventsHandler() { ButtonEventsHandler::ButtonEventsHandler()
: stRun(this) {
for(uint8_t i = 0; i< MAX_OBSERVER; i++) { for(uint8_t i = 0; i< MAX_OBSERVER; i++) {
observer_[i] = nullptr; observer_[i] = nullptr;
} }
stInitial.setNextState(&stRun);
stRun.registerOnEntry((XFState::callback)&ButtonEventsHandler::startButtonSM);
}
void ButtonEventsHandler::startButtonSM(const XFEvent* ev) {
buttonStateSm_[0].startBehavior();
buttonStateSm_[1].startBehavior();
buttonStateSm_[2].startBehavior();
buttonStateSm_[3].startBehavior();
} }
ButtonEventsHandler* ButtonEventsHandler::getInstance() { ButtonEventsHandler* ButtonEventsHandler::getInstance() {
@ -21,54 +33,6 @@ ButtonEventsHandler* ButtonEventsHandler::getInstance() {
return &buttonEventsHandler_; return &buttonEventsHandler_;
} }
XFEventStatus ButtonEventsHandler::processEvent() {
eEventStatus eventStatus = XFEventStatus::Unknown;
const XFEvent* ev = getCurrentEvent();
XFEvent::XFEventType evType = ev->getEventType();
int evid = ev->getId();
oldState_ = currentState_;
changeState_ = false;
switch (currentState_) {
case state::initial:
if(evType == XFEvent::Initial) {
currentState_ = state::run;
changeState_ = true;
eventStatus = XFEventStatus::Consumed;
}
break;
case state::run:
break;
}
if(changeState_) {
switch (oldState_) { // onExit
case state::initial:
break;
case state::run:
break;
}
switch (currentState_) { // onEntry
case state::initial:
break;
case state::run:
buttonStateSm_[0].startBehavior();
buttonStateSm_[1].startBehavior();
buttonStateSm_[2].startBehavior();
buttonStateSm_[3].startBehavior();
break;
}
}
return eventStatus;
}
void ButtonEventsHandler::onButtonChangeState(uint16_t buttonIndex, bool pressed) { void ButtonEventsHandler::onButtonChangeState(uint16_t buttonIndex, bool pressed) {
if(pressed) { if(pressed) {
buttonStateSm_[buttonIndex].genButtonPressed(); buttonStateSm_[buttonIndex].genButtonPressed();

View File

@ -31,16 +31,9 @@ public:
protected: protected:
ButtonEventsHandler(); ButtonEventsHandler();
XFEventStatus processEvent() override; void startButtonSM(const XFEvent* ev);
typedef enum { XFState stRun;
initial,
run
} state ;
state currentState_;
state oldState_;
bool changeState_;
interface::ButtonEventsHandlerObserver* observer_[MAX_OBSERVER]; interface::ButtonEventsHandlerObserver* observer_[MAX_OBSERVER];
ButtonStateSm buttonStateSm_[4]; ButtonStateSm buttonStateSm_[4];

View File

@ -18,7 +18,7 @@ public:
void genButtonReleased(); void genButtonReleased();
protected: protected:
XFEventStatus processEvent() override; XFEventStatus processEvent();
typedef enum { typedef enum {
evButtonPressed, evButtonPressed,

View File

@ -9,10 +9,18 @@
#include "trace/trace.h" #include "trace/trace.h"
#include "main.h" #include "main.h"
ButtonsController::ButtonsController() { ButtonsController::ButtonsController()
curentState_ = state::initial; : stCheckButtons(this),
stDebounce(this) {
cbProvider = nullptr; cbProvider = nullptr;
cbMethod = nullptr; cbMethod = nullptr;
stInitial.setNextState(&stCheckButtons);
stCheckButtons.setNextState(event::evButtonIrq, &stDebounce);
stCheckButtons.registerOnEntry((XFState::callback)&ButtonsController::fctCheckButtons);
stDebounce.setTimeout(20, &stCheckButtons);
}; };
ButtonsController* ButtonsController::getInstance() { ButtonsController* ButtonsController::getInstance() {
@ -37,61 +45,7 @@ bool ButtonsController::registerCallback(
return true; return true;
} }
XFEventStatus ButtonsController::processEvent() { void ButtonsController::fctCheckButtons(const XFEvent* ev) {
eEventStatus eventStatus = XFEventStatus::Unknown;
const XFEvent* ev = getCurrentEvent();
XFEvent::XFEventType evType = ev->getEventType();
int evid = ev->getId();
oldState_ = curentState_;
changeState = false;
switch (curentState_) {
case state::initial:
if(evType == XFEvent::Initial) {
curentState_ = state::checkButtons;
changeState = true;
eventStatus = XFEventStatus::Consumed;
}
break;
case state::checkButtons:
if (evid == event::evButtonIrq) {
curentState_ = state::debounce;
changeState = true;
eventStatus = XFEventStatus::Consumed;
}
break;
case state::debounce:
if (evid == event::evTimeout) {
curentState_ = state::checkButtons;
changeState = true;
eventStatus = XFEventStatus::Consumed;
}
break;
}
if(changeState) {
switch (oldState_) { // onExit
case state::initial:
break;
case state::checkButtons:
break;
case state::debounce:
break;
}
switch (curentState_) { // onEntry
case state::initial:
break;
case state::checkButtons:
if(cbProvider != nullptr) { if(cbProvider != nullptr) {
newState[0] = HAL_GPIO_ReadPin(BUTTON0_GPIO_Port, BUTTON0_Pin); newState[0] = HAL_GPIO_ReadPin(BUTTON0_GPIO_Port, BUTTON0_Pin);
@ -121,13 +75,5 @@ XFEventStatus ButtonsController::processEvent() {
} }
} }
break; }
case state::debounce:
scheduleTimeout(event::evTimeout, 100);
break;
}
}
return eventStatus;
}

View File

@ -19,27 +19,23 @@ public:
protected: protected:
ButtonsController(); ButtonsController();
XFEventStatus processEvent() override;
typedef enum { typedef enum {
evButtonIrq = 1, evButtonIrq = 10,
evTimeout evTimeout
} event; } event;
typedef enum {
initial,
checkButtons,
debounce
} state;
state curentState_;
state oldState_;
bool changeState = false;
interface::ButtonsControllerCallbackProvider* cbProvider; interface::ButtonsControllerCallbackProvider* cbProvider;
interface::ButtonsControllerCallbackProvider::CallbackMethod cbMethod; interface::ButtonsControllerCallbackProvider::CallbackMethod cbMethod;
bool newState[4]; bool newState[4];
bool buttonState[4]; bool buttonState[4];
void fctCheckButtons(const XFEvent* ev);
void fctScheduleTimeout(const XFEvent* ev);
XFState stCheckButtons;
XFState stDebounce;
public: public:
virtual void onIrq() override; virtual void onIrq() override;
virtual bool registerCallback( virtual bool registerCallback(

78
src/xf/core/XFState.cpp Normal file
View File

@ -0,0 +1,78 @@
/*
* XFState.cpp
*
* Created on: 23 nov. 2023
* Author: remi.heredero
*/
#include "xf/XFState.h"
#include "xf/include/xf/behavior.h"
#include <cassert>
#include "xf/event.h"
#include "trace/trace.h"
XFState::XFState(XFBehavior* behavior)
: pBehavior(behavior) {
assert(behavior != nullptr);
}
void XFState::setNextState(const int evid, const int time, XFEvent::XFEventType type, XFState* state) {
assert(state != nullptr);
transition t;
t.evid = evid;
t.time = time;
t.evType = type;
t.nextState = state;
transitions_.push_back(t);
}
XFEventStatus XFState::onState(const XFEvent* ev) {
assert(ev != nullptr);
assert(pBehavior != nullptr);
for(transition t : transitions_) {
assert(t.nextState != nullptr);
if(t.evType == XFEvent::XFEventType::Initial){
pBehavior->curentXFState_ = t.nextState;
pBehavior->changeXFState = true;
return XFEventStatus::Consumed;
}
if(t.evType == XFEvent::XFEventType::Timeout) {
pBehavior->curentXFState_ = t.nextState;
pBehavior->changeXFState = true;
return XFEventStatus::Consumed;
}
if(t.evid == ev->getId()) {
pBehavior->curentXFState_ = t.nextState;
pBehavior->changeXFState = true;
return XFEventStatus::Consumed;
}
}
return XFEventStatus::NotConsumed;
}
void XFState::onEntry(const XFEvent* ev) {
if(cbEntry_ != nullptr) {
(pBehavior->*cbEntry_)(ev);
}
for(transition t : transitions_) {
assert(t.nextState != nullptr);
if(t.evType == XFEvent::XFEventType::Timeout) {
pBehavior->scheduleTimeout(XFEvent::Timeout, t.time);
}
}
}
void XFState::onExit(const XFEvent* ev) {
if(cbExit_ != nullptr) {
(pBehavior->*cbExit_)(ev);
}
}

View File

@ -5,6 +5,7 @@
#include "xf/timeout.h" #include "xf/timeout.h"
#include "xf/initialevent.h" #include "xf/initialevent.h"
#include "xf/behavior.h" #include "xf/behavior.h"
#include "trace/trace.h"
using interface::XFResourceFactory; using interface::XFResourceFactory;
@ -12,7 +13,8 @@ XFBehavior::XFBehavior(bool ownDispatcher /* = false */) :
pDispatcher_(nullptr), pDispatcher_(nullptr),
hasOwnDispatcher_(ownDispatcher), hasOwnDispatcher_(ownDispatcher),
deleteOnTerminate_(false), deleteOnTerminate_(false),
pCurrentEvent_(nullptr) pCurrentEvent_(nullptr),
stInitial(this)
{ {
if (ownDispatcher) if (ownDispatcher)
{ {
@ -81,6 +83,22 @@ XFBehavior::TerminateBehavior XFBehavior::process(const XFEvent * pEvent)
return (eventStatus == XFEventStatus::Terminate); return (eventStatus == XFEventStatus::Terminate);
} }
XFEventStatus XFBehavior::processEvent(){
XFEventStatus eventStatus = XFEventStatus::Unknown;
const XFEvent * ev = getCurrentEvent();
oldXFState_ = curentXFState_;
eventStatus = curentXFState_->onState(ev);
if(changeXFState){
oldXFState_->onExit(ev);
curentXFState_->onEntry(ev);
}
return eventStatus;
}
interface::XFDispatcher * XFBehavior::getDispatcher() interface::XFDispatcher * XFBehavior::getDispatcher()
{ {
return pDispatcher_; return pDispatcher_;

View File

@ -0,0 +1,58 @@
/*
* XFState.h
*
* Created on: 23 nov. 2023
* Author: remi.heredero
*/
#ifndef XFSTATE_H_
#define XFSTATE_H_
#include "xf/interface/reactive.h"
#include "xf/interface/dispatcher.h"
#include "xf/eventstatus.h"
#include "xf/initialevent.h"
#include "xf/nulltransition.h"
#include "xf/timeout.h"
class XFBehavior;
#include <list>
class XFState {
friend class XFBehavior;
public:
XFState(XFBehavior* behavior);
~XFState() = default;
inline void setNextState(XFState* state) { setNextState(XFEvent::Initial, XFEvent::XFEventType::Initial, state); };
inline void setNextState(const int evid, XFState* state) { setNextState(evid, XFEvent::XFEventType::Event, state); };
inline void setTimeout(int time, XFState* nextState) { setNextState(XFEvent::Timeout, time, XFEvent::XFEventType::Timeout, nextState); };
typedef void (XFBehavior::*callback)(const XFEvent* ev);
inline void registerOnEntry(callback cbEntry) { cbEntry_ = cbEntry; };
inline void registerOnExit(callback cbExit) { cbExit_ = cbExit; };
protected:
inline void setNextState(const int evid, XFEvent::XFEventType type, XFState* state) {setNextState(evid, 0, type, state); };
void setNextState(const int evid, const int time, XFEvent::XFEventType type, XFState* state);
XFEventStatus onState(const XFEvent* ev);
void onEntry(const XFEvent* ev);
void onExit(const XFEvent* ev);
protected:
XFBehavior* const pBehavior;
typedef struct {
int evid;
int time;
XFEvent::XFEventType evType;
XFState* nextState;
} transition;
std::list<transition> transitions_;
callback cbEntry_;
callback cbExit_;
};
#endif /* XFSTATE_H_ */

View File

@ -8,6 +8,9 @@
#include "xf/nulltransition.h" #include "xf/nulltransition.h"
#include "xf/timeout.h" #include "xf/timeout.h"
#include "xf/include/xf/XFState.h"
#include <list>
class XFTimeout; class XFTimeout;
/** @ingroup xf_core /** @ingroup xf_core
@ -25,8 +28,8 @@ class XFTimeout;
* called every time an event or timeout arrives. The event (or timeout) can * called every time an event or timeout arrives. The event (or timeout) can
* be accessed via the getCurrentEvent() method. * be accessed via the getCurrentEvent() method.
*/ */
class XFBehavior : public interface::XFReactive class XFBehavior : public interface::XFReactive {
{ friend class XFState;
public: public:
#define GEN(event) pushEvent(new event) #define GEN(event) pushEvent(new event)
@ -55,7 +58,7 @@ protected:
* This method needs to be overridden to implement the * This method needs to be overridden to implement the
* behavior (i.e. state machine) needed. * behavior (i.e. state machine) needed.
*/ */
virtual XFEventStatus processEvent() = 0; virtual XFEventStatus processEvent();
const XFEvent * getCurrentEvent() const; ///< Returns the current event to be processed in processEvent(). const XFEvent * getCurrentEvent() const; ///< Returns the current event to be processed in processEvent().
interface::XFDispatcher * getDispatcher(); ///< Returns reference to #_pDispatcher. interface::XFDispatcher * getDispatcher(); ///< Returns reference to #_pDispatcher.
@ -95,6 +98,13 @@ protected:
bool hasOwnDispatcher_; ///< True if behavior has its own dispatcher, False if the default dispatcher is used. bool hasOwnDispatcher_; ///< True if behavior has its own dispatcher, False if the default dispatcher is used.
bool deleteOnTerminate_; ///< Indicates if the behavior can be deleted after reception of a 'terminate event'. bool deleteOnTerminate_; ///< Indicates if the behavior can be deleted after reception of a 'terminate event'.
const XFEvent * pCurrentEvent_; ///< Reference to actually processed event. const XFEvent * pCurrentEvent_; ///< Reference to actually processed event.
protected:
XFState stInitial;
XFState* curentXFState_ = &stInitial;
XFState* oldXFState_ = &stInitial;
bool changeXFState = false;
}; };
/** @} */ // end of xf_core group /** @} */ // end of xf_core group