Compare commits
	
		
			3 Commits
		
	
	
		
			262b89fe45
			...
			comments
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| a141b01380 | |||
| 821df428e9 | |||
| dac64a2d64 | 
| @@ -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 | ||||||
|   | |||||||
| @@ -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_; | ||||||
| }; | }; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -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); | ||||||
|   | |||||||
| @@ -25,7 +25,6 @@ protected: | |||||||
| 	typedef enum { | 	typedef enum { | ||||||
| 		evButtonPressed = 10, | 		evButtonPressed = 10, | ||||||
| 		evButtonReleased, | 		evButtonReleased, | ||||||
| 		evTimeout, |  | ||||||
| 		evReturn | 		evReturn | ||||||
| 	} event; | 	} event; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -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_) { | ||||||
|  |  | ||||||
|  | 		switch(ev->getEventType()) { | ||||||
|  |  | ||||||
|  | 			case XFEvent::XFEventType::Initial: | ||||||
| 				if(t.evType == XFEvent::XFEventType::Initial) { | 				if(t.evType == XFEvent::XFEventType::Initial) { | ||||||
| 			pBehavior->curentXFState_ = t.nextState; | 					return changeState(t.nextState); | ||||||
| 			pBehavior->changeXFState = true; |  | ||||||
| 			return XFEventStatus::Consumed; |  | ||||||
| 				} | 				} | ||||||
|  | 				break; | ||||||
|  |  | ||||||
|  | 			case XFEvent::XFEventType::Timeout: | ||||||
| 				if(t.evType == XFEvent::XFEventType::Timeout) { | 				if(t.evType == XFEvent::XFEventType::Timeout) { | ||||||
| 			pBehavior->curentXFState_ = t.nextState; | 					return changeState(t.nextState); | ||||||
| 			pBehavior->changeXFState = true; |  | ||||||
| 			return XFEventStatus::Consumed; |  | ||||||
| 				} | 				} | ||||||
|  | 				break; | ||||||
|  |  | ||||||
|  | 			case XFEvent::XFEventType::Event: | ||||||
| 				if(t.evid == ev->getId()) { | 				if(t.evid == ev->getId()) { | ||||||
| 			pBehavior->curentXFState_ = t.nextState; | 					return changeState(t.nextState); | ||||||
| 			pBehavior->changeXFState = true; | 				} | ||||||
| 			return XFEventStatus::Consumed; | 				break; | ||||||
|  |  | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	// 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) { | ||||||
|   | |||||||
| @@ -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; | ||||||
|   | |||||||
| @@ -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); }; | ||||||
|   | |||||||
| @@ -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; | ||||||
|  |  | ||||||
| }; | }; | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user