Compare commits
	
		
			14 Commits
		
	
	
		
			3d5f026a94
			...
			main
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| c9d2c05b73 | |||
| c07c47385e | |||
| 68fd8440fc | |||
| c1b4baeb2e | |||
| 09ea237a13 | |||
| 26ef097d86 | |||
| 9b56357770 | |||
| 57720e50f7 | |||
| 05f186188f | |||
| 20fd0631c6 | |||
| 268c270a4d | |||
| 9059d77b3e | |||
| 92c2faa858 | |||
| 2ee12ca042 | 
							
								
								
									
										
											BIN
										
									
								
								UML/event.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								UML/event.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 44 KiB | 
							
								
								
									
										55
									
								
								UML/event.puml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								UML/event.puml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,55 @@ | |||||||
|  | @startuml | ||||||
|  |  | ||||||
|  | participant Behavior as b | ||||||
|  | participant Dispatcher as d | ||||||
|  | entity Event as e | ||||||
|  | participant EventQueue as eq | ||||||
|  | queue "EventQueue::queue_" as q | ||||||
|  |  | ||||||
|  | == Create an Event == | ||||||
|  | ||| | ||||||
|  | ?->> b ++ : GEN | ||||||
|  | b -> e ** : new | ||||||
|  | b -> b --++ : pushEvent | ||||||
|  | e -> b : getBehavior | ||||||
|  | b --> e ++: setBehavior | ||||||
|  | e --> b -- | ||||||
|  | b -> d ++ : getDispatcher | ||||||
|  | d --> b | ||||||
|  | b -> d -- : pushEvent | ||||||
|  | d ->? -- : push | ||||||
|  |  | ||||||
|  |  | ||||||
|  | ||| | ||||||
|  | ||| | ||||||
|  | == Push Event  == | ||||||
|  | ||| | ||||||
|  | ?->> d ++: pushEvent | ||||||
|  | d -> eq--++: push | ||||||
|  | eq -> q ++ | ||||||
|  | q --> eq | ||||||
|  | eq -> q -- : pushEndQueue | ||||||
|  |  | ||||||
|  | ||| | ||||||
|  | ||| | ||||||
|  | == Dispatch == | ||||||
|  | ||| | ||||||
|  | ?->> d ++: executeOnce | ||||||
|  | d -> q : getFront | ||||||
|  | q -> e ++ | ||||||
|  | e --> q | ||||||
|  | q --> d : event | ||||||
|  | d -> q : pop | ||||||
|  | deactivate q | ||||||
|  | d -> d --++ : dispatchEvent | ||||||
|  | d -> b ++ : getBehavior | ||||||
|  | b --> d | ||||||
|  | d -> b -- : process | ||||||
|  | b -> b--: processEvent | ||||||
|  |  | ||||||
|  | destroy e | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  | @enduml | ||||||
							
								
								
									
										
											BIN
										
									
								
								UML/timeAlgorithme.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								UML/timeAlgorithme.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 28 KiB | 
							
								
								
									
										27
									
								
								UML/timeAlgorithme.puml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								UML/timeAlgorithme.puml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,27 @@ | |||||||
|  | @startuml | ||||||
|  |  | ||||||
|  | start | ||||||
|  | :newTime = 0 | ||||||
|  | totalTime = 0 | ||||||
|  | isEnd = it == list.end() | ||||||
|  | lastTime = 0; | ||||||
|  |  | ||||||
|  | #tomato:if (!isEnd) then (not end) | ||||||
|  |     #tomato:totalTime += it.getRelTicks(); | ||||||
|  | endif | ||||||
|  |  | ||||||
|  |     while ( !isEnd && (totalTime <= newTime) ) is (goForward) | ||||||
|  |     :isEnd = (++it == list.end()); | ||||||
|  |         :lastTime = totalTime; | ||||||
|  |         #tomato:if (!isEnd) then (not end) | ||||||
|  |             #tomato:totalTime += it.getRelTicks(); | ||||||
|  |         endif | ||||||
|  |     endwhile | ||||||
|  |  | ||||||
|  | #tomato:if (!isEnd) then (not end) | ||||||
|  |     #tomato:subRelTicks(newTime- lastTime); | ||||||
|  | endif | ||||||
|  | :it.setRelTicks(newTime - lastTime); | ||||||
|  | :insert(it, newTimeout); | ||||||
|  |  | ||||||
|  | @enduml | ||||||
							
								
								
									
										
											BIN
										
									
								
								UML/timeout.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								UML/timeout.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 63 KiB | 
							
								
								
									
										62
									
								
								UML/timeout.puml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										62
									
								
								UML/timeout.puml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,62 @@ | |||||||
|  | @startuml | ||||||
|  |  | ||||||
|  | participant "Behavior::StateMachine" as sm | ||||||
|  | participant Dispatcher as d | ||||||
|  | participant TimeoutManager as tm | ||||||
|  | entity "Event::Timeout" as t | ||||||
|  | queue "TimeoutManager::timeouts_" as timeouts | ||||||
|  |  | ||||||
|  | autoactivate off | ||||||
|  | ||| | ||||||
|  | ||| | ||||||
|  | == Schedule timeout == | ||||||
|  | ||| | ||||||
|  | sm -> sm++ : scheduleTimeout | ||||||
|  | sm -> d ++: getDispatcher | ||||||
|  | d --> sm --: dispatcher | ||||||
|  | sm -> d --++ : scheduleTimeout | ||||||
|  | d -> tm ++: getTimeoutManager | ||||||
|  | tm --> d --: timeoutManager | ||||||
|  | d -> tm --++ : scheduleTimeout | ||||||
|  | tm -> t ** : new | ||||||
|  | t --> tm | ||||||
|  | tm -> timeouts --++: insert | ||||||
|  |  | ||||||
|  | ||| | ||||||
|  | ||| | ||||||
|  | == Decrement timeout (and dispatch) == | ||||||
|  | ||| | ||||||
|  | loop every tickInterval | ||||||
|  | ?->> tm ++: tick | ||||||
|  | tm -> timeouts : getFront | ||||||
|  | timeouts -> t ++ | ||||||
|  | t --> timeouts | ||||||
|  | timeouts --> tm : timeout | ||||||
|  | tm -> t  --: decrement | ||||||
|  | end | ||||||
|  | ||| | ||||||
|  | note left t | ||||||
|  | When timeout is 0, | ||||||
|  | dispatch event | ||||||
|  | end note | ||||||
|  | t -> timeouts : pop | ||||||
|  | deactivate timeouts | ||||||
|  | t ->? --: pushEvent | ||||||
|  |  | ||||||
|  | ||| | ||||||
|  | ||| | ||||||
|  | == Unschedule timeout == | ||||||
|  | ||| | ||||||
|  | sm -> sm++ : unscheduleTimeout | ||||||
|  | sm -> d ++: getDispatcher | ||||||
|  | d --> sm --: dispatcher | ||||||
|  | sm -> d --++ : unscheduleTimeout | ||||||
|  | d -> tm ++: getTimeoutManager | ||||||
|  | tm --> d --: timeoutManager | ||||||
|  | d -> tm --++ : unscheduleTimeout | ||||||
|  | tm -> timeouts --: erase | ||||||
|  | timeouts -> t !! | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  | @enduml | ||||||
							
								
								
									
										46
									
								
								readme.md
									
									
									
									
									
								
							
							
						
						
									
										46
									
								
								readme.md
									
									
									
									
									
								
							| @@ -7,30 +7,18 @@ | |||||||
| - Demonstrate the right functioning of the XF by comparing and documenting the output created by the tests running on the *Embedded System* | - Demonstrate the right functioning of the XF by comparing and documenting the output created by the tests running on the *Embedded System* | ||||||
|  |  | ||||||
| # Time Algorithm | # Time Algorithm | ||||||
| ``` mermaid |  | ||||||
| flowchart TD |  | ||||||
|     insert[it.subRelTick\ninsert] |  | ||||||
|      |  | ||||||
|      |  | ||||||
|     A(Start)--> B[relTime = 0] |  | ||||||
|     B --> C{relTime < desireTime} |  | ||||||
|     C --> |Yes| D[it++] |  | ||||||
|     D --> E{ End ? } |  | ||||||
|     E --> |No| F[it.getRelTick] |  | ||||||
|     F --> C |  | ||||||
|     E --> |Yes| insert |  | ||||||
| ``` |  | ||||||
|  |  | ||||||
| ```flow |  | ||||||
| st=>start: Start:>http://google.com[blank] |  | ||||||
|  |  | ||||||
| ``` | <img src="./UML/timeAlgorithme.png"> | ||||||
|  |  | ||||||
| ```sequence | # Sequence Diagrams | ||||||
| Andrew -> China : Says Hello | ## Timeout | ||||||
|  |  | ||||||
| ``` | <img src="./UML/timeout.png"> | ||||||
|  |  | ||||||
|  | ## Event | ||||||
|  |  | ||||||
|  | <img src="./UML/event.png"> | ||||||
|  |  | ||||||
| # Tests | # Tests | ||||||
| ## Test 1 | ## Test 1 | ||||||
| @@ -43,7 +31,7 @@ The Test Factory (TestFactory01) instantiates 2 objects: | |||||||
| <details> | <details> | ||||||
|   <summary>QT result ✅</summary> |   <summary>QT result ✅</summary> | ||||||
|  |  | ||||||
|  | <img src="./test-bench/test1/ide-qtcreator-test1-idf/result.PNG"> | ||||||
|  |  | ||||||
| This test is successfully passed | This test is successfully passed | ||||||
|  |  | ||||||
| @@ -51,7 +39,7 @@ This test is successfully passed | |||||||
| <details> | <details> | ||||||
|   <summary>STM result ✅</summary> |   <summary>STM result ✅</summary> | ||||||
|  |  | ||||||
|  | <img src="./test-bench/test1/ide-cubeide-test1-idf/result.png"> | ||||||
|  |  | ||||||
| </details> | </details> | ||||||
|  |  | ||||||
| @@ -63,7 +51,7 @@ Weather or not the state machine should be deleted is handled with the 'deleteOn | |||||||
| <details> | <details> | ||||||
|   <summary>QT result ✅</summary> |   <summary>QT result ✅</summary> | ||||||
|  |  | ||||||
|  | <img src="./test-bench/test2/ide-qtcreator-test2-idf/result.PNG"> | ||||||
|  |  | ||||||
| This test is successfully passed | This test is successfully passed | ||||||
|  |  | ||||||
| @@ -71,7 +59,7 @@ This test is successfully passed | |||||||
| <details> | <details> | ||||||
|   <summary>STM result ✅</summary> |   <summary>STM result ✅</summary> | ||||||
|  |  | ||||||
|  | <img src="./test-bench/test2/ide-cubeide-test2-idf/result.png"> | ||||||
|  |  | ||||||
| </details> | </details> | ||||||
|  |  | ||||||
| @@ -81,7 +69,7 @@ This test checks basic event handling in state machines. In this example the Sta | |||||||
| <details> | <details> | ||||||
|   <summary>QT result ✅</summary> |   <summary>QT result ✅</summary> | ||||||
|  |  | ||||||
|  | <img src="./test-bench/test3/ide-qtcreator-test3-idf/result.PNG"> | ||||||
|  |  | ||||||
| This test is successfully passed | This test is successfully passed | ||||||
|  |  | ||||||
| @@ -89,7 +77,7 @@ This test is successfully passed | |||||||
| <details> | <details> | ||||||
|   <summary>STM result ✅</summary> |   <summary>STM result ✅</summary> | ||||||
|  |  | ||||||
|  | <img src="./test-bench/test3/ide-cubeide-test3-idf/result.png"> | ||||||
|  |  | ||||||
| </details> | </details> | ||||||
|  |  | ||||||
| @@ -99,7 +87,7 @@ Tests if timeouts are correctly cancelled. When leaving a state with a transitio | |||||||
| <details> | <details> | ||||||
|   <summary>QT result ✅</summary> |   <summary>QT result ✅</summary> | ||||||
|  |  | ||||||
|  | <img src="./test-bench/test4/ide-qtcreator-test4-idf/result.PNG"> | ||||||
|  |  | ||||||
| This test is successfully passed | This test is successfully passed | ||||||
|  |  | ||||||
| @@ -107,7 +95,7 @@ This test is successfully passed | |||||||
| <details> | <details> | ||||||
|   <summary>STM result ✅</summary> |   <summary>STM result ✅</summary> | ||||||
|  |  | ||||||
|  | <img src="./test-bench/test4/ide-cubeide-test4-idf/result.png"> | ||||||
|  |  | ||||||
| </details> | </details> | ||||||
|  |  | ||||||
| @@ -117,7 +105,7 @@ With this test multiple timeouts are added to the XFTimeoutManager list at the s | |||||||
| <details> | <details> | ||||||
|   <summary>QT result ✅</summary> |   <summary>QT result ✅</summary> | ||||||
|  |  | ||||||
|  | <img src="./test-bench/test5/ide-qtcreator-test5-idf/result.PNG"> | ||||||
|  |  | ||||||
| This test is successfully passed | This test is successfully passed | ||||||
|  |  | ||||||
| @@ -125,7 +113,7 @@ This test is successfully passed | |||||||
| <details> | <details> | ||||||
|   <summary>STM result ✅</summary> |   <summary>STM result ✅</summary> | ||||||
|  |  | ||||||
|  | <img src="./test-bench/test5/ide-cubeide-test5-idf/result.png"> | ||||||
|  |  | ||||||
| </details> | </details> | ||||||
|  |  | ||||||
|   | |||||||
| @@ -16,6 +16,12 @@ void XFBehavior::startBehavior() { | |||||||
|     GEN(XFInitialEvent()); |     GEN(XFInitialEvent()); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * @brief Pushes the given event to the dispatcher. | ||||||
|  |  * | ||||||
|  |  * If the event has no behavior assigned, the behavior of this object is assigned. | ||||||
|  |  * @param pEvent Event to push to the dispatcher. | ||||||
|  |  */ | ||||||
| void XFBehavior::pushEvent(XFEvent *pEvent) { | void XFBehavior::pushEvent(XFEvent *pEvent) { | ||||||
|     if(pEvent->getBehavior()==nullptr) { |     if(pEvent->getBehavior()==nullptr) { | ||||||
|         pEvent->setBehavior(this); |         pEvent->setBehavior(this); | ||||||
| @@ -39,6 +45,13 @@ interface::XFDispatcher *XFBehavior::getDispatcher() { | |||||||
|     return interface::XFDispatcher::getInstance(); |     return interface::XFDispatcher::getInstance(); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * @brief Returns a reference to the actually processed timeout. | ||||||
|  |  * | ||||||
|  |  * Will work only if the current event is of type IXFEvent::Timeout. | ||||||
|  |  * | ||||||
|  |  * @return Pointer to the currently processed timeout or nullptr if the current event is not a timeout. | ||||||
|  |  */ | ||||||
| const XFTimeout *XFBehavior::getCurrentTimeout() { | const XFTimeout *XFBehavior::getCurrentTimeout() { | ||||||
|     if(pCurrentEvent_->getEventType() == XFEvent::Timeout) { |     if(pCurrentEvent_->getEventType() == XFEvent::Timeout) { | ||||||
|         return (XFTimeout*) this->pCurrentEvent_; |         return (XFTimeout*) this->pCurrentEvent_; | ||||||
| @@ -51,13 +64,33 @@ void XFBehavior::setCurrentEvent(const XFEvent *pEvent) { | |||||||
|     this->pCurrentEvent_ = pEvent; |     this->pCurrentEvent_ = pEvent; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * @brief Processes the given event. | ||||||
|  |  * | ||||||
|  |  * The dispatcher calls this method every time a new event | ||||||
|  |  * or timeout arrives. The process method stores the actual | ||||||
|  |  * event using the #_pCurrentEvent and then calls | ||||||
|  |  * processEvent(). | ||||||
|  |  * | ||||||
|  |  * In case you intend to call process() inside your state machine you | ||||||
|  |  * are doing something wrong! Call GEN() or pushEvent() instead! | ||||||
|  |  * | ||||||
|  |  * @param pEvent Event to process | ||||||
|  |  * @return if the behavior is terminated (basically a boolean) | ||||||
|  |  */ | ||||||
| XFBehavior::TerminateBehavior XFBehavior::process(const XFEvent *pEvent) { | XFBehavior::TerminateBehavior XFBehavior::process(const XFEvent *pEvent) { | ||||||
|     this->setCurrentEvent(pEvent); |     this->setCurrentEvent(pEvent); | ||||||
|  |  | ||||||
|  |     // Get status of the event processing | ||||||
|     XFEventStatus status = XFEventStatus::Unknown; |     XFEventStatus status = XFEventStatus::Unknown; | ||||||
|     status = this->processEvent(); |     status = this->processEvent(); | ||||||
|  |  | ||||||
|  |     // Check if event was consumed and if it should be deleted | ||||||
|     if(status == XFEventStatus::Consumed && pEvent->deleteAfterConsume()) { |     if(status == XFEventStatus::Consumed && pEvent->deleteAfterConsume()) { | ||||||
|         delete pEvent; |         delete pEvent; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     // Check if the behavior is terminated and return the result | ||||||
|     XFBehavior::TerminateBehavior terminateBehavior = false; |     XFBehavior::TerminateBehavior terminateBehavior = false; | ||||||
|     if(status == XFEventStatus::Terminate) { |     if(status == XFEventStatus::Terminate) { | ||||||
|         terminateBehavior = true; |         terminateBehavior = true; | ||||||
|   | |||||||
| @@ -34,8 +34,28 @@ XFTimeoutManager::~XFTimeoutManager() { | |||||||
|  |  | ||||||
| void XFTimeoutManager::addTimeout(XFTimeout *pNewTimeout) { | void XFTimeoutManager::addTimeout(XFTimeout *pNewTimeout) { | ||||||
|  |  | ||||||
|  |     const int newTime = pNewTimeout->getInterval(); | ||||||
|  |     int totalTime = 0; | ||||||
|  |     bool isEnd = true; | ||||||
|  |     int lastTime = 0; | ||||||
|  |  | ||||||
|     this->pMutex_->lock(); |     this->pMutex_->lock(); | ||||||
|     this->timeouts_.push_back(pNewTimeout); |     TimeoutList::iterator it = this->timeouts_.begin(); | ||||||
|  |     isEnd = (it == this->timeouts_.end()); | ||||||
|  |  | ||||||
|  |     if(!isEnd) totalTime += (*it)->getRelTicks(); | ||||||
|  |  | ||||||
|  |     while(!isEnd && (totalTime <= newTime)) { | ||||||
|  |         isEnd = (++it == this->timeouts_.end()); | ||||||
|  |         lastTime = totalTime; | ||||||
|  |         if(!isEnd) totalTime += (*it)->getRelTicks(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     if(!isEnd) (*it)->substractFromRelTicks(newTime-lastTime); | ||||||
|  |  | ||||||
|  |     pNewTimeout->setRelTicks(newTime-lastTime); | ||||||
|  |     this->timeouts_.insert(it, pNewTimeout); | ||||||
|  |  | ||||||
|     this->pMutex_->unlock(); |     this->pMutex_->unlock(); | ||||||
|  |  | ||||||
| } | } | ||||||
| @@ -70,22 +90,31 @@ void XFTimeoutManager::unscheduleTimeout(int32_t timeoutId, interface::XFBehavio | |||||||
| } | } | ||||||
|  |  | ||||||
| void XFTimeoutManager::tick() { | void XFTimeoutManager::tick() { | ||||||
|     //Trace::out("[DEBUG] - Tick"); |  | ||||||
|     if(!this->timeouts_.empty()) { |     bool isEmpty = this->timeouts_.empty(); | ||||||
|         TimeoutList::iterator it; |     int rTime; | ||||||
|  |  | ||||||
|  |     if(!isEmpty) { | ||||||
|  |  | ||||||
|         this->pMutex_->lock(); |         this->pMutex_->lock(); | ||||||
|         for(it=this->timeouts_.begin(); it != this->timeouts_.end(); it++) { |  | ||||||
|             if((*it)->getRelTicks() > 0) { |         XFTimeout* timeout = this->timeouts_.front(); | ||||||
|                 (*it)->substractFromRelTicks(this->tickInterval_); |         timeout->substractFromRelTicks(tickInterval_); | ||||||
|             } else { |         rTime = timeout->getRelTicks(); | ||||||
|                 XFEvent* ev = *(it); |  | ||||||
|                 XFDispatcher::getInstance()->pushEvent(ev); |         while (!isEmpty && (rTime <= 0) ) { | ||||||
|                 it = this->timeouts_.erase(it); |  | ||||||
|                 it--; |             XFDispatcher::getInstance()->pushEvent(timeout); | ||||||
|             } |             this->timeouts_.pop_front(); | ||||||
|  |  | ||||||
|  |             timeout = this->timeouts_.front(); | ||||||
|  |             isEmpty = this->timeouts_.empty(); | ||||||
|  |             if(!isEmpty) rTime = timeout->getRelTicks(); | ||||||
|  |  | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         this->pMutex_->unlock(); |         this->pMutex_->unlock(); | ||||||
|  |  | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user