Compare commits
	
		
			3 Commits
		
	
	
		
			262b89fe45
			...
			comments
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| a141b01380 | |||
| 821df428e9 | |||
| dac64a2d64 | 
| @@ -15,7 +15,6 @@ Factory::Factory() { | ||||
| void Factory::initialize() { | ||||
|     Trace::initialize(); | ||||
|  | ||||
|     // TODO: Initialize factory attributes here | ||||
|  | ||||
|  | ||||
| #if defined(TOUCHGFX_ENABLED) && (TOUCHGFX_ENABLED != 0) | ||||
| @@ -27,24 +26,21 @@ void Factory::initialize() { | ||||
| void Factory::build() { | ||||
|     Trace::out("Factory: Creating app components..."); | ||||
|  | ||||
|     // Start state machine(s) | ||||
|  | ||||
|     // Start SM of ButtonEventLogger & ButtonsController | ||||
|     buttonEventLogger_.startBehavior(); | ||||
|     ButtonsController::getInstance()->startBehavior(); | ||||
|  | ||||
|     // Register CallBack of ButtonController with himself for the provider and onButtonChangeState for the CallBack Method | ||||
|     ButtonsController::getInstance()->registerCallback ( | ||||
|     		ButtonEventsHandler::getInstance(), | ||||
| 			(interface::ButtonsControllerCallbackProvider::CallbackMethod) &ButtonEventsHandler::onButtonChangeState | ||||
| 			); | ||||
|  | ||||
|     buttonEventLogger_.startBehavior(); | ||||
|     // Subscribe ButtonEventLogger to ButtonEventsHandler & start SM of ButtonEventsHandler | ||||
|     ButtonEventsHandler::getInstance()->subscribe(&buttonEventLogger_); | ||||
|     ButtonEventsHandler::getInstance()->startBehavior(); | ||||
|  | ||||
|  | ||||
| 	 | ||||
|     // TODO: Start state-machines here | ||||
|  | ||||
| #if defined(TOUCHGFX_ENABLED) && (TOUCHGFX_ENABLED != 0) | ||||
|     getTouchGfxTask().start(); | ||||
| #endif | ||||
|   | ||||
| @@ -11,8 +11,6 @@ | ||||
| #include "platform/f7-disco-gcc/board/ButtonsController.h" | ||||
| #include "mdw/button/ButtonEventsHandler.h" | ||||
|  | ||||
| // TODO: Add C++ specific includes here | ||||
|  | ||||
| namespace app { | ||||
|  | ||||
| /** | ||||
| @@ -30,7 +28,6 @@ public: | ||||
| #endif | ||||
|  | ||||
| protected: | ||||
|     // TODO: Add static attributes here | ||||
|     static ButtonEventsLogger buttonEventLogger_; | ||||
| }; | ||||
|  | ||||
|   | ||||
| @@ -19,9 +19,8 @@ ButtonStateSm::ButtonStateSm() | ||||
|  | ||||
| 	stWaitButtonPressed.addTransition(event::evButtonPressed, &stButtonPressed); | ||||
|  | ||||
| 	// TODO bug if setTimeout is used before addTransition !!! | ||||
| 	stButtonPressed.addTransition(event::evButtonReleased, &stButtonShortPressed); | ||||
| 	stButtonPressed.setTimeout(1000, &stButtonLongPressed); | ||||
| 	stButtonPressed.addTransition(event::evButtonReleased, &stButtonShortPressed); | ||||
| 	stButtonPressed.registerOnExit((XFState::callback)&ButtonStateSm::genNullTransition); | ||||
|  | ||||
| 	stButtonShortPressed.registerOnEntry((XFState::callback)&ButtonStateSm::notifyShortPress); | ||||
|   | ||||
| @@ -25,7 +25,6 @@ protected: | ||||
| 	typedef enum { | ||||
| 		evButtonPressed = 10, | ||||
| 		evButtonReleased, | ||||
| 		evTimeout, | ||||
| 		evReturn | ||||
| 	} event; | ||||
|  | ||||
|   | ||||
| @@ -13,68 +13,95 @@ | ||||
|  | ||||
| XFState::XFState(XFBehavior* behavior) | ||||
| 	: pBehavior(behavior) { | ||||
| 	/* | ||||
| 	 * Initialise behavior of this state on the constructor. | ||||
| 	 * Can't be null ! | ||||
| 	 */ | ||||
| 	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) { | ||||
| 	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; | ||||
| 	t.evType = type; | ||||
| 	t.evid = evid; | ||||
| 	t.time = time; | ||||
| 	t.evType = type; | ||||
| 	t.nextState = state; | ||||
| 	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) { | ||||
|  | ||||
| 	// Execute onState callBack without parameter if it's defined | ||||
| 	if(cbState_ != nullptr) { | ||||
| 		(pBehavior->*cbState_)(); | ||||
| 	} | ||||
|  | ||||
| 	// Execute onState callBack with event as parameter if it's defined | ||||
| 	if(cbEvState_ != nullptr) { | ||||
| 		(pBehavior->*cbEvState_)(ev); | ||||
| 	} | ||||
|  | ||||
| 	// Test each transition and change state if one is actual transition | ||||
| 	for(transition t : transitions_) { | ||||
|  | ||||
| 		if(t.evType == XFEvent::XFEventType::Initial){ | ||||
| 			pBehavior->curentXFState_ = t.nextState; | ||||
| 			pBehavior->changeXFState = true; | ||||
| 			return XFEventStatus::Consumed; | ||||
| 		} | ||||
| 		switch(ev->getEventType()) { | ||||
|  | ||||
| 		if(t.evType == XFEvent::XFEventType::Timeout) { | ||||
| 			pBehavior->curentXFState_ = t.nextState; | ||||
| 			pBehavior->changeXFState = true; | ||||
| 			return XFEventStatus::Consumed; | ||||
| 		} | ||||
| 			case XFEvent::XFEventType::Initial: | ||||
| 				if(t.evType == XFEvent::XFEventType::Initial) { | ||||
| 					return changeState(t.nextState); | ||||
| 				} | ||||
| 				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; | ||||
| } | ||||
|  | ||||
| void XFState::onEntry(const XFEvent* ev) { | ||||
|  | ||||
| 	// Execute onEntry callBack without parameter if it's defined | ||||
| 	if(cbEntry_ != nullptr) { | ||||
| 		(pBehavior->*cbEntry_)(); | ||||
| 	} | ||||
|  | ||||
| 	// Execute onExit callBack with event as parameter if it's defined | ||||
| 	if(cbEvEntry_ != nullptr) { | ||||
| 		(pBehavior->*cbEvEntry_)(ev); | ||||
| 	} | ||||
|  | ||||
| 	// If a timeout is on the list of transition start it with is own delay | ||||
| 	for(transition t : transitions_) { | ||||
|  | ||||
| 		if(t.evType == XFEvent::XFEventType::Timeout) { | ||||
| @@ -84,14 +111,18 @@ void XFState::onEntry(const XFEvent* ev) { | ||||
| 	} | ||||
| } | ||||
| void XFState::onExit(const XFEvent* ev) { | ||||
|  | ||||
| 	// Execute onExit callBack without parameter if it's defined | ||||
| 	if(cbExit_ != nullptr) { | ||||
| 		(pBehavior->*cbExit_)(); | ||||
| 	} | ||||
|  | ||||
| 	// Execute onExit callBack with event as parameter if it's defined | ||||
| 	if(cbEvExit_ != nullptr) { | ||||
| 		(pBehavior->*cbEvExit_)(ev); | ||||
| 	} | ||||
|  | ||||
| 	// If a timeout is on the list of transition and isn't the actual event, stop it | ||||
| 	for(transition t: transitions_) { | ||||
|  | ||||
| 		if(t.evType == XFEvent::XFEventType::Timeout) { | ||||
|   | ||||
| @@ -84,16 +84,21 @@ XFBehavior::TerminateBehavior XFBehavior::process(const XFEvent * pEvent) | ||||
| } | ||||
|  | ||||
| XFEventStatus XFBehavior::processEvent(){ | ||||
|  | ||||
| 	/* | ||||
| 	 * Basic double switch pattern but not switch on an enum but on Object XFState | ||||
| 	 */ | ||||
|  | ||||
| 	XFEventStatus eventStatus = XFEventStatus::Unknown; | ||||
| 	const XFEvent * ev = getCurrentEvent(); | ||||
|  | ||||
| 	oldXFState_ = curentXFState_; | ||||
| 	oldXFState_ = currentXFState_; | ||||
|  | ||||
| 	eventStatus =  curentXFState_->onState(ev); | ||||
| 	eventStatus =  currentXFState_->onState(ev); | ||||
|  | ||||
| 	if(changeXFState){ | ||||
| 		oldXFState_->onExit(ev); | ||||
| 		curentXFState_->onEntry(ev); | ||||
| 		currentXFState_->onEntry(ev); | ||||
| 	} | ||||
|  | ||||
| 	return eventStatus; | ||||
|   | ||||
| @@ -21,24 +21,68 @@ class XFBehavior; | ||||
| class XFState { | ||||
| 	friend class XFBehavior; | ||||
| 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() = 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); }; | ||||
|  | ||||
| 	/** | ||||
| 	 * 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); }; | ||||
|  | ||||
| 	// Callback typedef for callback without parameter | ||||
| 	typedef void (XFBehavior::*callback)(); | ||||
| 	typedef void (XFBehavior::*callbackEv)(const XFEvent* ev); | ||||
|  | ||||
| 	//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; }; | ||||
|  | ||||
| 	/** | ||||
| 	 * 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; }; | ||||
|  | ||||
|  | ||||
| 	//Callback typedef for callback with event in parameter | ||||
| 	typedef void (XFBehavior::*callbackEv)(const XFEvent* ev); | ||||
|  | ||||
| 	//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; }; | ||||
|  | ||||
| 	/** | ||||
| 	 * 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; }; | ||||
|  | ||||
| protected: | ||||
| 	void addTransition(XFEvent::XFEventType type, const int evid, const int time, XFState* state); | ||||
|  | ||||
| 	XFEventStatus changeState(XFState* state); | ||||
| 	XFEventStatus onState(const XFEvent* ev); | ||||
| 	void onEntry(const XFEvent* ev); | ||||
| 	void onExit(const XFEvent* ev); | ||||
| @@ -53,18 +97,22 @@ protected: | ||||
| 	} transition; | ||||
| 	std::list<transition> transitions_; | ||||
|  | ||||
| 	callback cbState_; | ||||
| 	callback cbEntry_; | ||||
| 	callback cbExit_; | ||||
| 	callbackEv cbEvState_; | ||||
| 	callbackEv cbEvEntry_; | ||||
| 	callbackEv cbEvExit_; | ||||
| 	callback cbState_ = nullptr; | ||||
| 	callback cbEntry_ = nullptr; | ||||
| 	callback cbExit_ = nullptr; | ||||
| 	callbackEv cbEvState_ = nullptr; | ||||
| 	callbackEv cbEvEntry_ = nullptr; | ||||
| 	callbackEv cbEvExit_ = nullptr; | ||||
|  | ||||
| }; | ||||
|  | ||||
|  | ||||
| class XFInitialState : public XFState { | ||||
| public: | ||||
| 	/** | ||||
| 	 * Use for set next state of the Initial State. | ||||
| 	 * @param state Pointer to the next state | ||||
| 	 */ | ||||
| 	inline XFInitialState(XFBehavior* behavior) : XFState(behavior) {}; | ||||
| 	~XFInitialState() = default; | ||||
| 	inline void addInitialTransition(XFState* state) { addTransition(XFEvent::XFEventType::Initial, XFEvent::Initial, 0, state); }; | ||||
|   | ||||
| @@ -55,7 +55,7 @@ public: | ||||
| protected: | ||||
|     /** | ||||
|      * 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. | ||||
|      */ | ||||
|     virtual XFEventStatus processEvent(); | ||||
| @@ -100,9 +100,20 @@ protected: | ||||
|     const XFEvent * pCurrentEvent_;					///< Reference to actually processed event. | ||||
|  | ||||
| protected: | ||||
|     /** | ||||
|      * Behavior have at least an Initial State. | ||||
|      */ | ||||
|     XFInitialState stInitial; | ||||
| 	XFState* curentXFState_ = &stInitial; | ||||
|  | ||||
|     /** | ||||
|      * Pointer for the curent and old state of this behavior | ||||
|      */ | ||||
| 	XFState* currentXFState_ = &stInitial; | ||||
| 	XFState* oldXFState_ = &stInitial; | ||||
|  | ||||
| 	/** | ||||
| 	 * Keep in trace when state is changed (have to be set to true in every processEvent | ||||
| 	 */ | ||||
| 	bool changeXFState = false; | ||||
|  | ||||
| }; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user