Initial commit

This commit is contained in:
2023-09-19 15:59:49 +02:00
commit bef0bade14
1860 changed files with 582828 additions and 0 deletions

View 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.

Binary file not shown.

View 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

View 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

View 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

View 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

View File

@ -0,0 +1,6 @@
/** @defgroup port_idf_qt IDF Qt Port Classes
*
* XF port classes for the `IDF Qt` port.
*
*/

View 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"

View 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