Initial commit
This commit is contained in:
30
src/simplified/xf/port/idf-qt/README.md
Normal file
30
src/simplified/xf/port/idf-qt/README.md
Normal file
@ -0,0 +1,30 @@
|
||||
# XF Port - IDF Qt
|
||||
|
||||
This port folder contains specific classes for the _IDF Qt_ XF port.
|
||||
|
||||
# Classes used by the _IDF Qt_ Port
|
||||
|
||||
| Class name | File location | Define to set |
|
||||
|--|--|--|
|
||||
| `XFTimeoutManager` | xf/port/common/timeoutmanager.cpp | USE_XF_COMMON_TIMEOUTMANAGER_CLASS |
|
||||
| `XFDispatcher` | xf/port/common/dispatcher.cpp | USE_XF_COMMON_DISPATCHER_CLASS |
|
||||
| `XF` | xf/port/idf-qt/xf.cpp | USE_XF_IDF_QT_XF_CLASS |
|
||||
| `XFEventQueue` | xf/port/idf-qt/eventqueue.cpp | USE_XF_IDF_QT_EVENT_QUEUE_CLASS |
|
||||
| `XFMutex` | xf/port/idf-qt/mutex.cpp | USE_XF_IDF_QT_MUTEX_CLASS |
|
||||
|
||||
# Example _config/xf-config.h_ File
|
||||
|
||||
```c++
|
||||
// Defines used by the IDF Qt port
|
||||
#define USE_XF_COMMON_TIMEOUTMANAGER_CLASS 1
|
||||
#define USE_XF_COMMON_DISPATCHER_CLASS 1
|
||||
#define USE_XF_IDF_QT_XF_CLASS 1
|
||||
#define USE_XF_IDF_QT_EVENT_QUEUE_CLASS 1
|
||||
#define USE_XF_IDF_QT_MUTEX_CLASS 1
|
||||
|
||||
#include "idf-qt/eventqueue.h"
|
||||
```
|
||||
|
||||
> Note:
|
||||
>
|
||||
> Here is also a good place to indicate which `EventQueue` class the XF should use.
|
BIN
src/simplified/xf/port/idf-qt/README.pdf
Normal file
BIN
src/simplified/xf/port/idf-qt/README.pdf
Normal file
Binary file not shown.
55
src/simplified/xf/port/idf-qt/eventqueue.cpp
Normal file
55
src/simplified/xf/port/idf-qt/eventqueue.cpp
Normal file
@ -0,0 +1,55 @@
|
||||
#include <config/xf-config.h>
|
||||
|
||||
#if (USE_XF_IDF_QT_EVENT_QUEUE_CLASS != 0)
|
||||
|
||||
#include <cassert>
|
||||
#include <QtGlobal>
|
||||
#include <QMutexLocker>
|
||||
#include "eventqueue.h"
|
||||
|
||||
XFEventQueue::XFEventQueue()
|
||||
{
|
||||
}
|
||||
|
||||
XFEventQueue::~XFEventQueue()
|
||||
{
|
||||
newEvents_.wakeAll();
|
||||
}
|
||||
|
||||
bool XFEventQueue::empty() const
|
||||
{
|
||||
return queue_.isEmpty();
|
||||
}
|
||||
|
||||
bool XFEventQueue::push(const XFEvent * pEvent, bool fromISR)
|
||||
{
|
||||
(void)fromISR;
|
||||
QMutexLocker locker(&mutex_);
|
||||
queue_.enqueue(pEvent);
|
||||
// Tell waiting thread(s) there is again an event present
|
||||
newEvents_.wakeAll();
|
||||
return true;
|
||||
}
|
||||
|
||||
const XFEvent * XFEventQueue::front()
|
||||
{
|
||||
return queue_.front();
|
||||
}
|
||||
|
||||
void XFEventQueue::pop()
|
||||
{
|
||||
QMutexLocker locker(&mutex_);
|
||||
queue_.dequeue();
|
||||
}
|
||||
|
||||
bool XFEventQueue::pend()
|
||||
{
|
||||
QMutexLocker locker(&mutex_);
|
||||
// Wait for new events. Mutex needs to be in lock-state
|
||||
// prior to call wait()!
|
||||
newEvents_.wait(&mutex_);
|
||||
|
||||
return !queue_.isEmpty();
|
||||
}
|
||||
|
||||
#endif // USE_XF_IDF_QT_EVENT_QUEUE_CLASS
|
45
src/simplified/xf/port/idf-qt/eventqueue.h
Normal file
45
src/simplified/xf/port/idf-qt/eventqueue.h
Normal file
@ -0,0 +1,45 @@
|
||||
#ifndef XF_EVENT_QUEUE_DEFAULT_QT_H
|
||||
#define XF_EVENT_QUEUE_DEFAULT_QT_H
|
||||
|
||||
#include "config/xf-config.h"
|
||||
|
||||
#if (USE_XF_IDF_QT_EVENT_QUEUE_CLASS != 0)
|
||||
|
||||
#include <stdint.h>
|
||||
#include <QMutex>
|
||||
#include <QWaitCondition>
|
||||
#include <QQueue>
|
||||
#include "xf/interface/eventqueue.h"
|
||||
|
||||
/** @ingroup port_idf_qt
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Default Qt implementation for the XFEventQueue interface.
|
||||
*/
|
||||
class XFEventQueue : public interface::XFEventQueue
|
||||
{
|
||||
public:
|
||||
XFEventQueue();
|
||||
~XFEventQueue() override;
|
||||
|
||||
// XFEventQueue interface implementation
|
||||
public:
|
||||
bool empty() const override; ///< Returns true if no event is in the queue.
|
||||
bool push(const XFEvent * pEvent, bool fromISR = false) override; ///< Pushes the given event onto the queue. Returns false if the event could not be pushed.
|
||||
const XFEvent * front() override; ///< Returns pointer to next event to pop.
|
||||
void pop() override; ///< Pops the next event from the queue.
|
||||
bool pend() override; ///< Wait for the next event to arrive. Returns true if an event is in the queue.
|
||||
|
||||
protected:
|
||||
typedef QQueue<const XFEvent *> EventQueue; ///< Type of the event queue.
|
||||
|
||||
QMutex mutex_; ///< Mutex (non-recursive) protecting access to _queue.
|
||||
QWaitCondition newEvents_; ///< Wait condition to let thread wait until a new event arrives.
|
||||
EventQueue queue_; ///< Internal queue holding the events.
|
||||
};
|
||||
|
||||
/** @} */ // end of port_idf_qt group
|
||||
#endif // USE_XF_IDF_QT_EVENT_QUEUE_CLASS
|
||||
#endif // XF_EVENT_QUEUE_DEFAULT_QT_H
|
18
src/simplified/xf/port/idf-qt/mutex.cpp
Normal file
18
src/simplified/xf/port/idf-qt/mutex.cpp
Normal file
@ -0,0 +1,18 @@
|
||||
#include <config/xf-config.h>
|
||||
|
||||
#if (USE_XF_IDF_QT_MUTEX_CLASS != 0)
|
||||
|
||||
#include <cassert>
|
||||
#include "mutex.h"
|
||||
|
||||
/**
|
||||
* @brief Implementation of interface::XFMutex::create method.
|
||||
*/
|
||||
interface::XFMutex * interface::XFMutex::create()
|
||||
{
|
||||
return new ::XFMutex;
|
||||
}
|
||||
|
||||
// TODO: Implement code for XFMutex class
|
||||
|
||||
#endif // USE_XF_IDF_QT_MUTEX_CLASS
|
38
src/simplified/xf/port/idf-qt/mutex.h
Normal file
38
src/simplified/xf/port/idf-qt/mutex.h
Normal file
@ -0,0 +1,38 @@
|
||||
#ifndef XF_MUTEX_DEFAULT_QT_H
|
||||
#define XF_MUTEX_DEFAULT_QT_H
|
||||
|
||||
#include <config/xf-config.h>
|
||||
|
||||
#if (USE_XF_IDF_QT_MUTEX_CLASS != 0)
|
||||
|
||||
#include <stdint.h>
|
||||
#include <QMutex>
|
||||
#include "xf/interface/mutex.h"
|
||||
|
||||
/** @ingroup port_idf_qt
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Default Qt implementation for the XFMutex interface.
|
||||
*/
|
||||
class XFMutex : public interface::XFMutex
|
||||
{
|
||||
friend class interface::XFMutex;
|
||||
public:
|
||||
|
||||
void lock() override;
|
||||
void unlock() override;
|
||||
|
||||
bool tryLock(int32_t timeout = 0) override;
|
||||
|
||||
protected:
|
||||
XFMutex() = default; ///< Do not allow to directly create an object of this class. Call interface::XFMutex::create() instead.
|
||||
|
||||
protected:
|
||||
QMutex mutex_; ///< The real mutex.
|
||||
};
|
||||
|
||||
/** @} */ // end of port_idf_qt group
|
||||
#endif // USE_XF_IDF_QT_MUTEX_CLASS
|
||||
#endif // XF_MUTEX_DEFAULT_QT_H
|
6
src/simplified/xf/port/idf-qt/port-idf-qt.dox
Normal file
6
src/simplified/xf/port/idf-qt/port-idf-qt.dox
Normal file
@ -0,0 +1,6 @@
|
||||
|
||||
/** @defgroup port_idf_qt IDF Qt Port Classes
|
||||
*
|
||||
* XF port classes for the `IDF Qt` port.
|
||||
*
|
||||
*/
|
13
src/simplified/xf/port/idf-qt/xf-port-idf-qt.pri
Normal file
13
src/simplified/xf/port/idf-qt/xf-port-idf-qt.pri
Normal file
@ -0,0 +1,13 @@
|
||||
|
||||
INCLUDEPATH += \
|
||||
$$PWD \
|
||||
$$PWD/..
|
||||
|
||||
SOURCES += \
|
||||
"$$PWD/eventqueue.cpp" \
|
||||
"$$PWD/mutex.cpp" \
|
||||
"$$PWD/xf.cpp"
|
||||
|
||||
HEADERS += \
|
||||
"$$PWD/eventqueue.h" \
|
||||
"$$PWD/mutex.h"
|
134
src/simplified/xf/port/idf-qt/xf.cpp
Normal file
134
src/simplified/xf/port/idf-qt/xf.cpp
Normal file
@ -0,0 +1,134 @@
|
||||
#include <config/xf-config.h>
|
||||
|
||||
#if (USE_XF_IDF_QT_XF_CLASS != 0)
|
||||
|
||||
#include <QCoreApplication>
|
||||
#include <QThread>
|
||||
#include "xf/interface/timeoutmanager.h"
|
||||
#include "xf/interface/dispatcher.h"
|
||||
#include "xf/xf.h"
|
||||
|
||||
/**
|
||||
* In the Qt port we are going to use a QCoreApplication instance
|
||||
* which gets executed by the XF::exec() method.
|
||||
*
|
||||
* The default dispatcher is active in this port implementation.
|
||||
* This means, the default dispatcher has its own thread.
|
||||
*
|
||||
* The XF::execOnce() method is not applicable for this port.
|
||||
*/
|
||||
|
||||
bool XF::isInitialized_ = false;
|
||||
bool XF::isRunning_ = false;
|
||||
|
||||
/**
|
||||
* @brief Helper class used to call regularly XFTimeoutManager::tick()
|
||||
*
|
||||
* Internally a Qt timer is created to call the
|
||||
* XFTimeoutManager::tick() method
|
||||
* (see QObject::startTimer()).
|
||||
*/
|
||||
static class TimeoutManagerTimer : public QObject
|
||||
{
|
||||
public:
|
||||
TimeoutManagerTimer()
|
||||
: _timerId(0)
|
||||
{
|
||||
}
|
||||
|
||||
void start(int32_t tickInterval)
|
||||
{
|
||||
Q_ASSERT(_timerId == 0); // Method should be called only once!
|
||||
_timerId = startTimer(tickInterval, Qt::PreciseTimer);
|
||||
}
|
||||
|
||||
void timerEvent(QTimerEvent * event) override
|
||||
{
|
||||
if (event->timerId() == _timerId)
|
||||
{
|
||||
interface::XFTimeoutManager::getInstance()->tick();
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
int32_t _timerId;
|
||||
} timeoutManagerTimer;
|
||||
|
||||
/**
|
||||
* @brief The DispatcherThread calls the XFDispatcher execute() method in a separate thread.
|
||||
*/
|
||||
class DispatcherThread : public QThread
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief DispatcherThread constructor
|
||||
* @param dispatcher Dispatcher to be executed by the thread.
|
||||
*/
|
||||
DispatcherThread(interface::XFDispatcher * dispatcher)
|
||||
{
|
||||
dispatcher_ = dispatcher;
|
||||
assert(dispatcher_);
|
||||
}
|
||||
|
||||
// QThread interface
|
||||
protected:
|
||||
/**
|
||||
* @brief Method executed by the new thread.
|
||||
*
|
||||
* For more information read the documentation of QThread.
|
||||
*/
|
||||
void run() override
|
||||
{
|
||||
this->dispatcher_->execute();
|
||||
}
|
||||
|
||||
protected:
|
||||
interface::XFDispatcher * dispatcher_; ///< Pointer to dispatcher used by the DispatcherThread.
|
||||
};
|
||||
|
||||
static QCoreApplication & getApplication(int argc = 0, char * argv[] = nullptr)
|
||||
{
|
||||
static QCoreApplication app(argc, argv);
|
||||
return app;
|
||||
}
|
||||
|
||||
void XF::initialize(int timeInterval /* = 10 */, int argc /* = 0 */, char * argv[] /* = nullptr */)
|
||||
{
|
||||
if (!isInitialized_)
|
||||
{
|
||||
// Call getApplication() to create QT application instance
|
||||
::getApplication(argc, argv);
|
||||
|
||||
// Create and initialize TimeoutManager
|
||||
interface::XFTimeoutManager::getInstance()->initialize(timeInterval);
|
||||
// Start it
|
||||
interface::XFTimeoutManager::getInstance()->start(std::bind(&TimeoutManagerTimer::start, &timeoutManagerTimer, std::placeholders::_1));
|
||||
|
||||
isInitialized_ = true;
|
||||
}
|
||||
}
|
||||
|
||||
int XF::exec()
|
||||
{
|
||||
// Start default dispatcher (in a separate thread)
|
||||
DispatcherThread dispatcherThread(interface::XFDispatcher::getInstance());
|
||||
dispatcherThread.start();
|
||||
|
||||
isRunning_ = true;
|
||||
|
||||
// Start Qt event loop
|
||||
return ::getApplication().exec();
|
||||
}
|
||||
|
||||
int XF::execOnce()
|
||||
{
|
||||
Q_ASSERT(false); // Not applicable for this port
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool XF::isRunning()
|
||||
{
|
||||
return isRunning_;
|
||||
}
|
||||
|
||||
#endif // USE_XF_IDF_QT_XF_CLASS
|
Reference in New Issue
Block a user