Compare commits

...
This repository has been archived on 2024-01-25. You can view files and clone it, but cannot push or open issues or pull requests.

3 Commits

Author SHA1 Message Date
a141b01380 Comments for modified part of XF 2023-11-28 07:54:55 +01:00
821df428e9 fix miss order Timeout bug 2023-11-27 21:30:11 +01:00
dac64a2d64 add comments on XFState.h 2023-11-27 17:16:13 +01:00
8 changed files with 132 additions and 46 deletions

View File

@ -15,7 +15,6 @@ Factory::Factory() {
void Factory::initialize() { void Factory::initialize() {
Trace::initialize(); Trace::initialize();
// TODO: Initialize factory attributes here
#if defined(TOUCHGFX_ENABLED) && (TOUCHGFX_ENABLED != 0) #if defined(TOUCHGFX_ENABLED) && (TOUCHGFX_ENABLED != 0)
@ -27,24 +26,21 @@ void Factory::initialize() {
void Factory::build() { void Factory::build() {
Trace::out("Factory: Creating app components..."); Trace::out("Factory: Creating app components...");
// Start state machine(s) // Start SM of ButtonEventLogger & ButtonsController
buttonEventLogger_.startBehavior(); buttonEventLogger_.startBehavior();
ButtonsController::getInstance()->startBehavior(); ButtonsController::getInstance()->startBehavior();
// Register CallBack of ButtonController with himself for the provider and onButtonChangeState for the CallBack Method
ButtonsController::getInstance()->registerCallback ( ButtonsController::getInstance()->registerCallback (
ButtonEventsHandler::getInstance(), ButtonEventsHandler::getInstance(),
(interface::ButtonsControllerCallbackProvider::CallbackMethod) &ButtonEventsHandler::onButtonChangeState (interface::ButtonsControllerCallbackProvider::CallbackMethod) &ButtonEventsHandler::onButtonChangeState
); );
buttonEventLogger_.startBehavior(); // Subscribe ButtonEventLogger to ButtonEventsHandler & start SM of ButtonEventsHandler
ButtonEventsHandler::getInstance()->subscribe(&buttonEventLogger_); ButtonEventsHandler::getInstance()->subscribe(&buttonEventLogger_);
ButtonEventsHandler::getInstance()->startBehavior(); ButtonEventsHandler::getInstance()->startBehavior();
// TODO: Start state-machines here
#if defined(TOUCHGFX_ENABLED) && (TOUCHGFX_ENABLED != 0) #if defined(TOUCHGFX_ENABLED) && (TOUCHGFX_ENABLED != 0)
getTouchGfxTask().start(); getTouchGfxTask().start();
#endif #endif

View File

@ -11,8 +11,6 @@
#include "platform/f7-disco-gcc/board/ButtonsController.h" #include "platform/f7-disco-gcc/board/ButtonsController.h"
#include "mdw/button/ButtonEventsHandler.h" #include "mdw/button/ButtonEventsHandler.h"
// TODO: Add C++ specific includes here
namespace app { namespace app {
/** /**
@ -30,7 +28,6 @@ public:
#endif #endif
protected: protected:
// TODO: Add static attributes here
static ButtonEventsLogger buttonEventLogger_; static ButtonEventsLogger buttonEventLogger_;
}; };

View File

@ -19,9 +19,8 @@ ButtonStateSm::ButtonStateSm()
stWaitButtonPressed.addTransition(event::evButtonPressed, &stButtonPressed); stWaitButtonPressed.addTransition(event::evButtonPressed, &stButtonPressed);
// TODO bug if setTimeout is used before addTransition !!!
stButtonPressed.addTransition(event::evButtonReleased, &stButtonShortPressed);
stButtonPressed.setTimeout(1000, &stButtonLongPressed); stButtonPressed.setTimeout(1000, &stButtonLongPressed);
stButtonPressed.addTransition(event::evButtonReleased, &stButtonShortPressed);
stButtonPressed.registerOnExit((XFState::callback)&ButtonStateSm::genNullTransition); stButtonPressed.registerOnExit((XFState::callback)&ButtonStateSm::genNullTransition);
stButtonShortPressed.registerOnEntry((XFState::callback)&ButtonStateSm::notifyShortPress); stButtonShortPressed.registerOnEntry((XFState::callback)&ButtonStateSm::notifyShortPress);

View File

@ -25,7 +25,6 @@ protected:
typedef enum { typedef enum {
evButtonPressed = 10, evButtonPressed = 10,
evButtonReleased, evButtonReleased,
evTimeout,
evReturn evReturn
} event; } event;

View File

@ -13,68 +13,95 @@
XFState::XFState(XFBehavior* behavior) XFState::XFState(XFBehavior* behavior)
: pBehavior(behavior) { : pBehavior(behavior) {
/*
* Initialise behavior of this state on the constructor.
* Can't be null !
*/
assert(behavior != nullptr); assert(behavior != nullptr);
cbState_ = nullptr;
cbEntry_ = nullptr;
cbExit_ = nullptr;
cbEvState_ = nullptr;
cbEvEntry_ = nullptr;
cbEvExit_ = nullptr;
} }
void XFState::addTransition(XFEvent::XFEventType type, const int evid, const int time, XFState* state) { void XFState::addTransition(XFEvent::XFEventType type, const int evid, const int time, XFState* state) {
assert(state != nullptr); assert(state != nullptr);
/*
* Create a transition with his Type, ID, time if Timeout and the state to be set when this transition happen
* Push the transition on the list of transition of the event
* Pointer State can't be null
*/
transition t; transition t;
t.evType = type;
t.evid = evid; t.evid = evid;
t.time = time; t.time = time;
t.evType = type;
t.nextState = state; t.nextState = state;
transitions_.push_back(t); transitions_.push_back(t);
} }
XFEventStatus XFState::changeState(XFState* state) {
// Change current state of the behavior
pBehavior->currentXFState_ = state;
// Set state is changed
pBehavior->changeXFState = true;
// Return the event status as consumed
return XFEventStatus::Consumed;
}
XFEventStatus XFState::onState(const XFEvent* ev) { XFEventStatus XFState::onState(const XFEvent* ev) {
// Execute onState callBack without parameter if it's defined
if(cbState_ != nullptr) { if(cbState_ != nullptr) {
(pBehavior->*cbState_)(); (pBehavior->*cbState_)();
} }
// Execute onState callBack with event as parameter if it's defined
if(cbEvState_ != nullptr) { if(cbEvState_ != nullptr) {
(pBehavior->*cbEvState_)(ev); (pBehavior->*cbEvState_)(ev);
} }
// Test each transition and change state if one is actual transition
for(transition t : transitions_) { for(transition t : transitions_) {
if(t.evType == XFEvent::XFEventType::Initial){ switch(ev->getEventType()) {
pBehavior->curentXFState_ = t.nextState;
pBehavior->changeXFState = true;
return XFEventStatus::Consumed;
}
if(t.evType == XFEvent::XFEventType::Timeout) { case XFEvent::XFEventType::Initial:
pBehavior->curentXFState_ = t.nextState; if(t.evType == XFEvent::XFEventType::Initial) {
pBehavior->changeXFState = true; return changeState(t.nextState);
return XFEventStatus::Consumed; }
} break;
case XFEvent::XFEventType::Timeout:
if(t.evType == XFEvent::XFEventType::Timeout) {
return changeState(t.nextState);
}
break;
case XFEvent::XFEventType::Event:
if(t.evid == ev->getId()) {
return changeState(t.nextState);
}
break;
if(t.evid == ev->getId()) {
pBehavior->curentXFState_ = t.nextState;
pBehavior->changeXFState = true;
return XFEventStatus::Consumed;
} }
} }
// Return event status as notConsumed if actual event isn't on the list of transitions
return XFEventStatus::NotConsumed; return XFEventStatus::NotConsumed;
} }
void XFState::onEntry(const XFEvent* ev) { void XFState::onEntry(const XFEvent* ev) {
// Execute onEntry callBack without parameter if it's defined
if(cbEntry_ != nullptr) { if(cbEntry_ != nullptr) {
(pBehavior->*cbEntry_)(); (pBehavior->*cbEntry_)();
} }
// Execute onExit callBack with event as parameter if it's defined
if(cbEvEntry_ != nullptr) { if(cbEvEntry_ != nullptr) {
(pBehavior->*cbEvEntry_)(ev); (pBehavior->*cbEvEntry_)(ev);
} }
// If a timeout is on the list of transition start it with is own delay
for(transition t : transitions_) { for(transition t : transitions_) {
if(t.evType == XFEvent::XFEventType::Timeout) { if(t.evType == XFEvent::XFEventType::Timeout) {
@ -84,14 +111,18 @@ void XFState::onEntry(const XFEvent* ev) {
} }
} }
void XFState::onExit(const XFEvent* ev) { void XFState::onExit(const XFEvent* ev) {
// Execute onExit callBack without parameter if it's defined
if(cbExit_ != nullptr) { if(cbExit_ != nullptr) {
(pBehavior->*cbExit_)(); (pBehavior->*cbExit_)();
} }
// Execute onExit callBack with event as parameter if it's defined
if(cbEvExit_ != nullptr) { if(cbEvExit_ != nullptr) {
(pBehavior->*cbEvExit_)(ev); (pBehavior->*cbEvExit_)(ev);
} }
// If a timeout is on the list of transition and isn't the actual event, stop it
for(transition t: transitions_) { for(transition t: transitions_) {
if(t.evType == XFEvent::XFEventType::Timeout) { if(t.evType == XFEvent::XFEventType::Timeout) {

View File

@ -84,16 +84,21 @@ XFBehavior::TerminateBehavior XFBehavior::process(const XFEvent * pEvent)
} }
XFEventStatus XFBehavior::processEvent(){ XFEventStatus XFBehavior::processEvent(){
/*
* Basic double switch pattern but not switch on an enum but on Object XFState
*/
XFEventStatus eventStatus = XFEventStatus::Unknown; XFEventStatus eventStatus = XFEventStatus::Unknown;
const XFEvent * ev = getCurrentEvent(); const XFEvent * ev = getCurrentEvent();
oldXFState_ = curentXFState_; oldXFState_ = currentXFState_;
eventStatus = curentXFState_->onState(ev); eventStatus = currentXFState_->onState(ev);
if(changeXFState){ if(changeXFState){
oldXFState_->onExit(ev); oldXFState_->onExit(ev);
curentXFState_->onEntry(ev); currentXFState_->onEntry(ev);
} }
return eventStatus; return eventStatus;

View File

@ -21,24 +21,68 @@ class XFBehavior;
class XFState { class XFState {
friend class XFBehavior; friend class XFBehavior;
public: public:
/**
* Create and initialise a State for the behavior.
* Have to be initialized in the constructor of the behavior.
* @param behavior Pointer to the behavior class. Use the keyword this
*/
XFState(XFBehavior* behavior); XFState(XFBehavior* behavior);
~XFState() = default; ~XFState() = default;
/**
* Set the conditional state of an custom event.
* @param evid Id of the event for set the next State
* @param state Pointer to the next state
*/
inline void addTransition(const int evid, XFState* state) { addTransition(XFEvent::XFEventType::Event, evid, 0, state); }; inline void addTransition(const int evid, XFState* state) { addTransition(XFEvent::XFEventType::Event, evid, 0, state); };
/**
* Set a new timer with a certain duration on every entry of this state.
* Set next state after
* @param time Time duration of the timeout
* @param nextState Pointer to the next state
*/
inline void setTimeout(int time, XFState* nextState) { addTransition(XFEvent::XFEventType::Timeout, XFEvent::Timeout, time, nextState); }; inline void setTimeout(int time, XFState* nextState) { addTransition(XFEvent::XFEventType::Timeout, XFEvent::Timeout, time, nextState); };
// Callback typedef for callback without parameter
typedef void (XFBehavior::*callback)(); typedef void (XFBehavior::*callback)();
typedef void (XFBehavior::*callbackEv)(const XFEvent* ev);
//inline void registerOnState(callback cbState) { cbState_ = cbState; }; //inline void registerOnState(callback cbState) { cbState_ = cbState; };
/**
* Register the method for the entry callback without parameter
* @param cbEntry Callback automatically called when the state is onEntry
*/
inline void registerOnEntry(callback cbEntry) { cbEntry_ = cbEntry; }; inline void registerOnEntry(callback cbEntry) { cbEntry_ = cbEntry; };
/**
* Register the method for the exit callback without parameter
* @param cbExit Callback automatically called when the state is onExit
*/
inline void registerOnExit(callback cbExit) { cbExit_ = cbExit; }; inline void registerOnExit(callback cbExit) { cbExit_ = cbExit; };
//Callback typedef for callback with event in parameter
typedef void (XFBehavior::*callbackEv)(const XFEvent* ev);
//inline void registerOnState(callbackEv cbState) { cbEvState_ = cbState; }; //inline void registerOnState(callbackEv cbState) { cbEvState_ = cbState; };
/**
* Register the method for the entry callback with event in parameter.
* @param cbEntry Callback automatically called when the state is onEntry
*/
inline void registerOnEntry(callbackEv cbEntry) { cbEvEntry_ = cbEntry; }; inline void registerOnEntry(callbackEv cbEntry) { cbEvEntry_ = cbEntry; };
/**
* Register the method for the exit callback with event in parameter
* @param cbExit Callback automatically called when the state is onExit
*/
inline void registerOnExit(callbackEv cbExit) { cbEvExit_ = cbExit; }; inline void registerOnExit(callbackEv cbExit) { cbEvExit_ = cbExit; };
protected: protected:
void addTransition(XFEvent::XFEventType type, const int evid, const int time, XFState* state); void addTransition(XFEvent::XFEventType type, const int evid, const int time, XFState* state);
XFEventStatus changeState(XFState* state);
XFEventStatus onState(const XFEvent* ev); XFEventStatus onState(const XFEvent* ev);
void onEntry(const XFEvent* ev); void onEntry(const XFEvent* ev);
void onExit(const XFEvent* ev); void onExit(const XFEvent* ev);
@ -53,18 +97,22 @@ protected:
} transition; } transition;
std::list<transition> transitions_; std::list<transition> transitions_;
callback cbState_; callback cbState_ = nullptr;
callback cbEntry_; callback cbEntry_ = nullptr;
callback cbExit_; callback cbExit_ = nullptr;
callbackEv cbEvState_; callbackEv cbEvState_ = nullptr;
callbackEv cbEvEntry_; callbackEv cbEvEntry_ = nullptr;
callbackEv cbEvExit_; callbackEv cbEvExit_ = nullptr;
}; };
class XFInitialState : public XFState { class XFInitialState : public XFState {
public: public:
/**
* Use for set next state of the Initial State.
* @param state Pointer to the next state
*/
inline XFInitialState(XFBehavior* behavior) : XFState(behavior) {}; inline XFInitialState(XFBehavior* behavior) : XFState(behavior) {};
~XFInitialState() = default; ~XFInitialState() = default;
inline void addInitialTransition(XFState* state) { addTransition(XFEvent::XFEventType::Initial, XFEvent::Initial, 0, state); }; inline void addInitialTransition(XFState* state) { addTransition(XFEvent::XFEventType::Initial, XFEvent::Initial, 0, state); };

View File

@ -55,7 +55,7 @@ public:
protected: protected:
/** /**
* Executes the current event in its implemented behavior. * Executes the current event in its implemented behavior.
* This method needs to be overridden to implement the * This method can be overridden to implement the
* behavior (i.e. state machine) needed. * behavior (i.e. state machine) needed.
*/ */
virtual XFEventStatus processEvent(); virtual XFEventStatus processEvent();
@ -100,9 +100,20 @@ protected:
const XFEvent * pCurrentEvent_; ///< Reference to actually processed event. const XFEvent * pCurrentEvent_; ///< Reference to actually processed event.
protected: protected:
/**
* Behavior have at least an Initial State.
*/
XFInitialState stInitial; XFInitialState stInitial;
XFState* curentXFState_ = &stInitial;
/**
* Pointer for the curent and old state of this behavior
*/
XFState* currentXFState_ = &stInitial;
XFState* oldXFState_ = &stInitial; XFState* oldXFState_ = &stInitial;
/**
* Keep in trace when state is changed (have to be set to true in every processEvent
*/
bool changeXFState = false; bool changeXFState = false;
}; };