Compare commits
30 Commits
820aff5af4
...
main
Author | SHA1 | Date | |
---|---|---|---|
c9d2c05b73 | |||
c07c47385e | |||
68fd8440fc | |||
c1b4baeb2e | |||
09ea237a13 | |||
26ef097d86 | |||
9b56357770 | |||
57720e50f7 | |||
05f186188f | |||
20fd0631c6 | |||
268c270a4d | |||
9059d77b3e | |||
92c2faa858 | |||
2ee12ca042 | |||
3d5f026a94 | |||
54265d70d1 | |||
f26d9803ac | |||
a327899e11 | |||
0978fdb7a5 | |||
5c889da959 | |||
a1960d7f3b | |||
a86d9b1dfc | |||
e302dab670 | |||
f809d4f647 | |||
208ab5ec63 | |||
08ad191f2e | |||
dd9498f38d | |||
4002757765 | |||
c1e65d41ee | |||
b3cec6c926 |
8
.gitignore
vendored
@ -53,3 +53,11 @@ compile_commands.json
|
||||
|
||||
*_qmlcache.qrc
|
||||
*.user
|
||||
test-bench/test1/ide-cubeide-test1-idf/Debug
|
||||
test-bench/test5/ide-cubeide-test5-idf/.settings/language.settings.xml
|
||||
test-bench/test1/ide-cubeide-test1-idf/.settings/language.settings.xml
|
||||
test-bench/test2/ide-cubeide-test2-idf/.settings/language.settings.xml
|
||||
test-bench/test2/ide-cubeide-test2-idf/Debug
|
||||
test-bench/test4/ide-cubeide-test4-idf/.settings/language.settings.xml
|
||||
test-bench/test3/ide-cubeide-test3-idf/.settings/language.settings.xml
|
||||
.idea
|
||||
|
BIN
UML/event.png
Normal file
After Width: | Height: | Size: 44 KiB |
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
After Width: | Height: | Size: 28 KiB |
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
After Width: | Height: | Size: 63 KiB |
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
|
119
readme.md
Normal file
@ -0,0 +1,119 @@
|
||||
# Goal of this project
|
||||
- Design an algorithm which lets the `XFTimeoutManager` behave in the same timely manner independent of whether it handles one or nn timeouts
|
||||
- Implement the core classes of the XF
|
||||
- Implement the port classes for following ports: *common*, *idf-qt*, *idf-stm32*
|
||||
- Test and comment the code of the XF
|
||||
- The tests provided need to run using Qt and on the *Embedded System* platform
|
||||
- Demonstrate the right functioning of the XF by comparing and documenting the output created by the tests running on the *Embedded System*
|
||||
|
||||
# Time Algorithm
|
||||
|
||||
|
||||
<img src="./UML/timeAlgorithme.png">
|
||||
|
||||
# Sequence Diagrams
|
||||
## Timeout
|
||||
|
||||
<img src="./UML/timeout.png">
|
||||
|
||||
## Event
|
||||
|
||||
<img src="./UML/event.png">
|
||||
|
||||
# Tests
|
||||
## Test 1
|
||||
This test launches an instance of the Task01Tm class and produces some output. Optionally, multiple instances of Task01Tm can be created to test the XF.
|
||||
|
||||
The Test Factory (TestFactory01) instantiates 2 objects:
|
||||
- An object of Task01Tm which outputs the text "Say Hello" every second
|
||||
- An object of Task01Tm which outputs the text "Echo" every half second
|
||||
|
||||
<details>
|
||||
<summary>QT result ✅</summary>
|
||||
|
||||
<img src="./test-bench/test1/ide-qtcreator-test1-idf/result.PNG">
|
||||
|
||||
This test is successfully passed
|
||||
|
||||
</details>
|
||||
<details>
|
||||
<summary>STM result ✅</summary>
|
||||
|
||||
<img src="./test-bench/test1/ide-cubeide-test1-idf/result.png">
|
||||
|
||||
</details>
|
||||
|
||||
## Test 2
|
||||
This test checks again timeout handling and proper termination of a state machine. In case the state machine was statically/globally created, the XF must not delete the object, when requested to terminate the behavior. If the state-machine was created on the heap (dynamic allocation), the XF must delete the state machine upon request to terminate.
|
||||
|
||||
Weather or not the state machine should be deleted is handled with the 'deleteOnTerminate()' method provided by the XFReactive interface.
|
||||
|
||||
<details>
|
||||
<summary>QT result ✅</summary>
|
||||
|
||||
<img src="./test-bench/test2/ide-qtcreator-test2-idf/result.PNG">
|
||||
|
||||
This test is successfully passed
|
||||
|
||||
</details>
|
||||
<details>
|
||||
<summary>STM result ✅</summary>
|
||||
|
||||
<img src="./test-bench/test2/ide-cubeide-test2-idf/result.png">
|
||||
|
||||
</details>
|
||||
|
||||
## Test 3
|
||||
This test checks basic event handling in state machines. In this example the StateMachine03 class sends itself an evRestart event to change from one state to another.
|
||||
|
||||
<details>
|
||||
<summary>QT result ✅</summary>
|
||||
|
||||
<img src="./test-bench/test3/ide-qtcreator-test3-idf/result.PNG">
|
||||
|
||||
This test is successfully passed
|
||||
|
||||
</details>
|
||||
<details>
|
||||
<summary>STM result ✅</summary>
|
||||
|
||||
<img src="./test-bench/test3/ide-cubeide-test3-idf/result.png">
|
||||
|
||||
</details>
|
||||
|
||||
## Test 4
|
||||
Tests if timeouts are correctly cancelled. When leaving a state with a transition having a timeout, without the timeout raises, the timeout must be cancelled (unscheduled).
|
||||
|
||||
<details>
|
||||
<summary>QT result ✅</summary>
|
||||
|
||||
<img src="./test-bench/test4/ide-qtcreator-test4-idf/result.PNG">
|
||||
|
||||
This test is successfully passed
|
||||
|
||||
</details>
|
||||
<details>
|
||||
<summary>STM result ✅</summary>
|
||||
|
||||
<img src="./test-bench/test4/ide-cubeide-test4-idf/result.png">
|
||||
|
||||
</details>
|
||||
|
||||
## Test 5
|
||||
With this test multiple timeouts are added to the XFTimeoutManager list at the same time. This tests the way how new timeouts are added in relation to other timeouts (with the same timeout value) already added to the list. For more details how the objects are created, please refere to the implementation of the TestFactory05 class.
|
||||
|
||||
<details>
|
||||
<summary>QT result ✅</summary>
|
||||
|
||||
<img src="./test-bench/test5/ide-qtcreator-test5-idf/result.PNG">
|
||||
|
||||
This test is successfully passed
|
||||
|
||||
</details>
|
||||
<details>
|
||||
<summary>STM result ✅</summary>
|
||||
|
||||
<img src="./test-bench/test5/ide-cubeide-test5-idf/result.png">
|
||||
|
||||
</details>
|
||||
|
@ -2,51 +2,98 @@
|
||||
#include "xf/timeout.h"
|
||||
#include "xf/initialevent.h"
|
||||
#include "xf/behavior.h"
|
||||
#include "trace/trace.h"
|
||||
|
||||
// TODO: Implement code for XFBehavior class
|
||||
|
||||
XFBehavior::XFBehavior() {
|
||||
|
||||
this->deleteOnTerminate_ = false;
|
||||
}
|
||||
|
||||
XFBehavior::~XFBehavior() {
|
||||
|
||||
}
|
||||
|
||||
void XFBehavior::startBehavior() {
|
||||
|
||||
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) {
|
||||
|
||||
if(pEvent->getBehavior()==nullptr) {
|
||||
pEvent->setBehavior(this);
|
||||
}
|
||||
this->getDispatcher()->pushEvent(pEvent);
|
||||
}
|
||||
|
||||
bool XFBehavior::deleteOnTerminate() const {
|
||||
return deleteOnTerminate_;
|
||||
return this->deleteOnTerminate_;
|
||||
}
|
||||
|
||||
void XFBehavior::setDeleteOnTerminate(bool deleteBehaviour) {
|
||||
deleteOnTerminate_ = deleteBehaviour;
|
||||
this->deleteOnTerminate_ = deleteBehaviour;
|
||||
}
|
||||
|
||||
const XFEvent *XFBehavior::getCurrentEvent() const {
|
||||
return pCurrentEvent_;
|
||||
return this->pCurrentEvent_;
|
||||
}
|
||||
|
||||
interface::XFDispatcher *XFBehavior::getDispatcher() {
|
||||
|
||||
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() {
|
||||
|
||||
if(pCurrentEvent_->getEventType() == XFEvent::Timeout) {
|
||||
return (XFTimeout*) this->pCurrentEvent_;
|
||||
} else {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void XFBehavior::setCurrentEvent(const XFEvent *pEvent) {
|
||||
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) {
|
||||
setCurrentEvent(pEvent);
|
||||
processEvent();
|
||||
return deleteOnTerminate_;
|
||||
this->setCurrentEvent(pEvent);
|
||||
|
||||
// Get status of the event processing
|
||||
XFEventStatus status = XFEventStatus::Unknown;
|
||||
status = this->processEvent();
|
||||
|
||||
// Check if event was consumed and if it should be deleted
|
||||
if(status == XFEventStatus::Consumed && pEvent->deleteAfterConsume()) {
|
||||
delete pEvent;
|
||||
}
|
||||
|
||||
// Check if the behavior is terminated and return the result
|
||||
XFBehavior::TerminateBehavior terminateBehavior = false;
|
||||
if(status == XFEventStatus::Terminate) {
|
||||
terminateBehavior = true;
|
||||
}
|
||||
return terminateBehavior;
|
||||
}
|
||||
|
@ -1,10 +1,8 @@
|
||||
#include "xf/customevent.h"
|
||||
|
||||
// TODO done: Implement code for XFCustomEvent class
|
||||
|
||||
|
||||
XFCustomEvent::XFCustomEvent(int id, interface::XFBehavior *pBehavior):
|
||||
XFEvent(XFEventType::Unknown, id){
|
||||
XFEvent(XFEventType::Event, id){
|
||||
setBehavior(pBehavior);
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,5 @@
|
||||
#include "xf/defaulttransition.h"
|
||||
|
||||
// TODO done: Implement code for XFDefaultTransition class
|
||||
|
||||
XFDefaultTransition::XFDefaultTransition():
|
||||
XFEvent(XFEventType::DefaultTransition) {
|
||||
|
||||
|
@ -1,7 +1,5 @@
|
||||
#include "xf/initialevent.h"
|
||||
|
||||
// TODO done: Implement code for XFInitialEvent class
|
||||
|
||||
XFInitialEvent::XFInitialEvent():
|
||||
XFEvent(XFEventType::Initial) {
|
||||
|
||||
|
@ -1,9 +1,8 @@
|
||||
#include "xf/timeout.h"
|
||||
|
||||
// TODO done: Implement code for XFTimeout class
|
||||
|
||||
XFTimeout::XFTimeout(int id, int interval, interface::XFBehavior *pBehavior):
|
||||
XFEvent(XFEventType::Timeout, id), interval_(interval) {
|
||||
this->setRelTicks(this->getInterval());
|
||||
setBehavior(pBehavior);
|
||||
}
|
||||
|
||||
|
@ -24,10 +24,8 @@ interface::XFDispatcher * interface::XFDispatcher::getInstance() {
|
||||
return &dispatcher;
|
||||
}
|
||||
|
||||
// TODO: Implement code for XFDispatcher class
|
||||
|
||||
XFDispatcher::XFDispatcher() {
|
||||
|
||||
this->pMutex_ = interface::XFMutex::create();
|
||||
}
|
||||
|
||||
XFDispatcher::~XFDispatcher() {
|
||||
@ -35,11 +33,20 @@ XFDispatcher::~XFDispatcher() {
|
||||
}
|
||||
|
||||
void XFDispatcher::dispatchEvent(const XFEvent *pEvent) const {
|
||||
pEvent->getBehavior()->startBehavior();
|
||||
XFBehavior::TerminateBehavior terminateBehavior;
|
||||
terminateBehavior = pEvent->getBehavior()->process(pEvent);
|
||||
if(terminateBehavior && pEvent->getBehavior()->deleteOnTerminate()) {
|
||||
delete pEvent->getBehavior();
|
||||
if(pEvent->deleteAfterConsume()) {
|
||||
delete pEvent;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void XFDispatcher::pushEvent(XFEvent *pEvent) {
|
||||
events_.push(pEvent);
|
||||
this->pMutex_->lock();
|
||||
events_.push(pEvent, false);
|
||||
this->pMutex_->unlock();
|
||||
}
|
||||
|
||||
void XFDispatcher::scheduleTimeout(int timeoutId, int interval, interface::XFBehavior *pBehavior) {
|
||||
@ -51,11 +58,23 @@ void XFDispatcher::unscheduleTimeout(int timeoutId, interface::XFBehavior *pBeha
|
||||
}
|
||||
|
||||
void XFDispatcher::executeOnce() {
|
||||
if(!this->events_.empty()) {
|
||||
|
||||
this->pMutex_->lock();
|
||||
const XFEvent *ev = this->events_.front();
|
||||
this->events_.pop();
|
||||
this->pMutex_->unlock();
|
||||
|
||||
dispatchEvent(ev);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int XFDispatcher::execute(const void *param) {
|
||||
|
||||
(void) param;
|
||||
while(true){
|
||||
this->executeOnce();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -8,6 +8,9 @@
|
||||
#include "xf/interface/behavior.h"
|
||||
#include "xf/interface/mutex.h"
|
||||
#include "timeoutmanager.h"
|
||||
#if defined(XF_TRACE_EVENT_PUSH_POP) && (XF_TRACE_EVENT_PUSH_POP != 0)
|
||||
#include "trace/trace.h"
|
||||
#endif // XF_TRACE_EVENT_PUSH_POP
|
||||
|
||||
using Mutex = interface::XFMutex; // Rename XFMutex interface class to Mutex for easier use.
|
||||
|
||||
@ -21,9 +24,8 @@ interface::XFTimeoutManager * interface::XFTimeoutManager::getInstance() {
|
||||
return &timeoutManager;
|
||||
}
|
||||
|
||||
// TODO done: Implement code for XFTimeoutManager class
|
||||
|
||||
XFTimeoutManager::XFTimeoutManager() {
|
||||
this->pMutex_ = interface::XFMutex::create();
|
||||
}
|
||||
|
||||
XFTimeoutManager::~XFTimeoutManager() {
|
||||
@ -31,21 +33,42 @@ XFTimeoutManager::~XFTimeoutManager() {
|
||||
}
|
||||
|
||||
void XFTimeoutManager::addTimeout(XFTimeout *pNewTimeout) {
|
||||
pMutex_->lock();
|
||||
timeouts_.push_front(pNewTimeout);
|
||||
pMutex_->unlock();
|
||||
|
||||
const int newTime = pNewTimeout->getInterval();
|
||||
int totalTime = 0;
|
||||
bool isEnd = true;
|
||||
int lastTime = 0;
|
||||
|
||||
this->pMutex_->lock();
|
||||
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();
|
||||
|
||||
}
|
||||
|
||||
void XFTimeoutManager::returnTimeout(XFTimeout *pTimeout) {
|
||||
pMutex_->lock();
|
||||
this->pMutex_->lock();
|
||||
XFDispatcher::getInstance()->pushEvent(pTimeout);
|
||||
timeouts_.remove(pTimeout);
|
||||
pMutex_->unlock();
|
||||
this->timeouts_.remove(pTimeout);
|
||||
this->pMutex_->unlock();
|
||||
}
|
||||
|
||||
void XFTimeoutManager::start(std::function<void (uint32_t)> startTimeoutManagerTimer) {
|
||||
startTimeoutManagerTimer(tickInterval_);
|
||||
startTimeoutManagerTimer(this->tickInterval_);
|
||||
}
|
||||
|
||||
void XFTimeoutManager::scheduleTimeout(int32_t timeoutId, int32_t interval, interface::XFBehavior *pBehavior) {
|
||||
@ -54,18 +77,44 @@ void XFTimeoutManager::scheduleTimeout(int32_t timeoutId, int32_t interval, inte
|
||||
}
|
||||
|
||||
void XFTimeoutManager::unscheduleTimeout(int32_t timeoutId, interface::XFBehavior *pBehavior) {
|
||||
for(XFTimeout* timeout : timeouts_) {
|
||||
bool id = ( timeout->getId() == timeoutId );
|
||||
bool behavior = ( timeout->getBehavior() == pBehavior);
|
||||
if( id && behavior ) {
|
||||
timeouts_.remove(timeout);
|
||||
this->pMutex_->lock();
|
||||
TimeoutList::iterator it;
|
||||
for(it = this->timeouts_.begin(); it != this->timeouts_.end(); it++){
|
||||
|
||||
if((*it)->getId()==timeoutId && (*it)->getBehavior() == pBehavior) {
|
||||
it = this->timeouts_.erase(it);
|
||||
}
|
||||
|
||||
}
|
||||
this->pMutex_->unlock();
|
||||
}
|
||||
|
||||
void XFTimeoutManager::tick() {
|
||||
for(XFTimeout* timeout : timeouts_) {
|
||||
|
||||
bool isEmpty = this->timeouts_.empty();
|
||||
int rTime;
|
||||
|
||||
if(!isEmpty) {
|
||||
|
||||
this->pMutex_->lock();
|
||||
|
||||
XFTimeout* timeout = this->timeouts_.front();
|
||||
timeout->substractFromRelTicks(tickInterval_);
|
||||
rTime = timeout->getRelTicks();
|
||||
|
||||
while (!isEmpty && (rTime <= 0) ) {
|
||||
|
||||
XFDispatcher::getInstance()->pushEvent(timeout);
|
||||
this->timeouts_.pop_front();
|
||||
|
||||
timeout = this->timeouts_.front();
|
||||
isEmpty = this->timeouts_.empty();
|
||||
if(!isEmpty) rTime = timeout->getRelTicks();
|
||||
|
||||
}
|
||||
|
||||
this->pMutex_->unlock();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5,10 +5,40 @@
|
||||
#include <cassert>
|
||||
#include "eventqueue.h"
|
||||
|
||||
// TODO: Implement code for XFEventQueue class
|
||||
// TODO done: Implement code for XFEventQueue class
|
||||
|
||||
bool XFEventQueue::pend()
|
||||
{
|
||||
XFEventQueue::XFEventQueue(){
|
||||
|
||||
}
|
||||
|
||||
XFEventQueue::~XFEventQueue(){
|
||||
|
||||
}
|
||||
|
||||
bool XFEventQueue::empty() const {
|
||||
return queue_.empty();
|
||||
}
|
||||
|
||||
bool XFEventQueue::push(const XFEvent *pEvent, bool fromISR) {
|
||||
(void) fromISR;
|
||||
mutex_.lock();
|
||||
queue_.push(pEvent);
|
||||
mutex_.unlock();
|
||||
return true;
|
||||
}
|
||||
|
||||
const XFEvent* XFEventQueue::front() {
|
||||
return queue_.front();
|
||||
}
|
||||
|
||||
void XFEventQueue::pop() {
|
||||
mutex_.lock();
|
||||
queue_.pop();
|
||||
mutex_.unlock();
|
||||
}
|
||||
|
||||
|
||||
bool XFEventQueue::pend() {
|
||||
// Method cannot be used in an IDF! Waiting within
|
||||
// this method would block the whole XF
|
||||
return false;
|
||||
|
@ -8,11 +8,23 @@
|
||||
/**
|
||||
* @brief Implementation of interface::XFMutex::create method.
|
||||
*/
|
||||
interface::XFMutex * interface::XFMutex::create()
|
||||
{
|
||||
interface::XFMutex * interface::XFMutex::create() {
|
||||
return new ::XFMutex;
|
||||
}
|
||||
|
||||
// TODO: Implement code for XFMutex class
|
||||
void XFMutex::lock() {
|
||||
enterCritical();
|
||||
}
|
||||
|
||||
void XFMutex::unlock() {
|
||||
exitCritical();
|
||||
}
|
||||
|
||||
bool XFMutex::tryLock(int32_t timeout) {
|
||||
XFMutex::lock();
|
||||
return true;
|
||||
}
|
||||
|
||||
// TODO done: Implement code for XFMutex class
|
||||
|
||||
#endif // USE_XF_IDF_STM32_MUTEX_CLASS
|
||||
|
@ -9,21 +9,47 @@
|
||||
|
||||
using interface::XFTimeoutManager;
|
||||
|
||||
void XF_initialize(int timeInterval)
|
||||
{
|
||||
void XF_initialize(int timeInterval) {
|
||||
XF::initialize(timeInterval);
|
||||
}
|
||||
|
||||
void XF_exec()
|
||||
{
|
||||
void XF_exec() {
|
||||
XF::exec();
|
||||
}
|
||||
|
||||
void XF_execOnce()
|
||||
{
|
||||
void XF_execOnce() {
|
||||
XF::execOnce();
|
||||
}
|
||||
|
||||
// TODO: Implement code for XF class
|
||||
|
||||
bool XF::isInitialized_ = false;
|
||||
bool XF::isRunning_ = false;
|
||||
|
||||
void XF::initialize(int timeInterval, int argc, char *argv[]){
|
||||
|
||||
if(!isInitialized_) {
|
||||
interface::XFTimeoutManager::getInstance()->initialize(timeInterval);
|
||||
|
||||
isInitialized_ = true;
|
||||
}
|
||||
}
|
||||
|
||||
int XF::exec(){
|
||||
int foo;
|
||||
foo = interface::XFDispatcher::getInstance()->execute();
|
||||
isRunning_ = true;
|
||||
return foo;
|
||||
}
|
||||
|
||||
int XF::execOnce() {
|
||||
interface::XFDispatcher::getInstance()->executeOnce();
|
||||
isRunning_ = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool XF::isRunning() {
|
||||
return isRunning_;
|
||||
}
|
||||
|
||||
#endif // USE_XF_IDF_STM32_XF_CLASS
|
||||
|
@ -11,6 +11,8 @@
|
||||
#define USE_XF_IDF_QT_EVENT_QUEUE_CLASS 1
|
||||
#define USE_XF_IDF_QT_MUTEX_CLASS 1
|
||||
|
||||
#define XF_TRACE_EVENT_PUSH_POP 1
|
||||
|
||||
#include "idf-qt/eventqueue.h"
|
||||
#endif // PORT_IDF_QT
|
||||
|
||||
|
BIN
test-bench/test1/ide-cubeide-test1-idf/result.png
Normal file
After Width: | Height: | Size: 37 KiB |
BIN
test-bench/test1/ide-qtcreator-test1-idf/result.PNG
Normal file
After Width: | Height: | Size: 15 KiB |
BIN
test-bench/test2/ide-cubeide-test2-idf/result.png
Normal file
After Width: | Height: | Size: 23 KiB |
BIN
test-bench/test2/ide-qtcreator-test2-idf/result.PNG
Normal file
After Width: | Height: | Size: 20 KiB |
BIN
test-bench/test3/ide-cubeide-test3-idf/result.png
Normal file
After Width: | Height: | Size: 36 KiB |
BIN
test-bench/test3/ide-qtcreator-test3-idf/result.PNG
Normal file
After Width: | Height: | Size: 11 KiB |
BIN
test-bench/test4/ide-cubeide-test4-idf/result.png
Normal file
After Width: | Height: | Size: 38 KiB |
BIN
test-bench/test4/ide-qtcreator-test4-idf/result.PNG
Normal file
After Width: | Height: | Size: 20 KiB |
BIN
test-bench/test5/ide-cubeide-test5-idf/result.png
Normal file
After Width: | Height: | Size: 35 KiB |
BIN
test-bench/test5/ide-qtcreator-test5-idf/result.PNG
Normal file
After Width: | Height: | Size: 20 KiB |