2023-05-12 00:24:01 +01:00
|
|
|
#ifndef CACHINGQUEUE_H
|
|
|
|
|
#define CACHINGQUEUE_H
|
|
|
|
|
#include <QCoreApplication>
|
|
|
|
|
#include <QObject>
|
|
|
|
|
#include <QThread>
|
|
|
|
|
#include <QMutex>
|
|
|
|
|
#include <QMutexLocker>
|
2023-05-15 10:53:52 +01:00
|
|
|
#include <QMap>
|
2023-05-12 00:24:01 +01:00
|
|
|
#include <QMultiMap>
|
|
|
|
|
#include <QVariant>
|
2023-05-15 10:53:52 +01:00
|
|
|
#include <QQueue>
|
2023-05-12 00:24:01 +01:00
|
|
|
#include <QRect>
|
|
|
|
|
#include <QWaitCondition>
|
2023-05-15 10:53:52 +01:00
|
|
|
#include <QDateTime>
|
2023-05-24 19:50:01 +01:00
|
|
|
#include <QRandomGenerator>
|
2026-01-02 18:59:51 +00:00
|
|
|
#include <atomic>
|
2023-05-12 00:24:01 +01:00
|
|
|
|
|
|
|
|
#include "wfviewtypes.h"
|
2023-05-15 10:53:52 +01:00
|
|
|
#include "rigidentities.h"
|
2023-05-12 00:24:01 +01:00
|
|
|
|
|
|
|
|
enum queuePriority {
|
|
|
|
|
// Use prime numbers for priority, so that each queue is processed
|
|
|
|
|
priorityNone=0, priorityImmediate=1, priorityHighest=2, priorityHigh=3, priorityMediumHigh=5, priorityMedium=7, priorityMediumLow=11, priorityLow=19, priorityLowest=23
|
|
|
|
|
};
|
|
|
|
|
|
2024-02-09 17:08:04 +00:00
|
|
|
inline QMap<QString,int> priorityMap = {{"None",0},{"Immediate",1},{"Highest",2},{"High",3},{"Medium High",5},{"Medium",7},{"Medium Low",11},{"Low",19},{"Lowest",23}};
|
2023-05-12 00:24:01 +01:00
|
|
|
|
|
|
|
|
// Command with no param is a get by default
|
|
|
|
|
struct queueItem {
|
2026-01-02 18:59:51 +00:00
|
|
|
queueItem() : id(nextId++){}
|
2026-06-02 21:03:57 +01:00
|
|
|
queueItem (queueItem const &q): command(q.command), param(q.param), receiver(q.receiver), recurring(q.recurring), rawData(q.rawData), id(nextId++) {};
|
2026-01-02 18:59:51 +00:00
|
|
|
queueItem (funcs command, QVariant param, bool recurring, uchar receiver) : command(command), param(param), receiver(receiver), recurring(recurring), id(nextId++) {};
|
|
|
|
|
queueItem (funcs command, QVariant param, bool recurring) : command(command), param(param), receiver(0), recurring(recurring), id(nextId++) {};
|
|
|
|
|
queueItem (funcs command, QVariant param) : command(command), param(param),receiver(0), recurring(0), id(nextId++) {};
|
|
|
|
|
queueItem (funcs command, bool recurring, uchar receiver) : command(command), param(QVariant()), receiver(receiver), recurring(recurring), id(nextId++) {};
|
|
|
|
|
queueItem (funcs command, bool recurring) : command(command), param(QVariant()), receiver(0), recurring(recurring), id(nextId++) {};
|
|
|
|
|
queueItem (funcs command) : command(command), param(QVariant()), receiver(0), recurring(false), id(nextId++){};
|
2026-06-02 21:03:57 +01:00
|
|
|
queueItem (QByteArray rawData, uchar receiver=0) : command(funcNone), param(QVariant()), receiver(receiver), recurring(false), rawData(rawData), id(nextId++) {};
|
2023-06-05 09:27:37 +01:00
|
|
|
funcs command;
|
|
|
|
|
QVariant param;
|
2024-03-30 20:40:27 +00:00
|
|
|
uchar receiver;
|
2023-06-05 09:27:37 +01:00
|
|
|
bool recurring;
|
2026-06-02 21:03:57 +01:00
|
|
|
QByteArray rawData;
|
2026-01-02 18:59:51 +00:00
|
|
|
static std::atomic<qint64> nextId;
|
|
|
|
|
qint64 id = nextId++;
|
|
|
|
|
//qint64 id = QDateTime::currentMSecsSinceEpoch();
|
|
|
|
|
|
|
|
|
|
bool operator==(const queueItem& lhs) const
|
2024-06-12 17:11:01 +01:00
|
|
|
{
|
2026-05-23 15:11:05 +01:00
|
|
|
return (lhs.command == command &&
|
|
|
|
|
lhs.receiver == receiver &&
|
|
|
|
|
lhs.recurring == recurring &&
|
2026-06-02 21:03:57 +01:00
|
|
|
lhs.param.isValid() == param.isValid() &&
|
|
|
|
|
lhs.rawData == rawData);
|
2024-06-12 17:11:01 +01:00
|
|
|
}
|
2023-05-12 00:24:01 +01:00
|
|
|
};
|
|
|
|
|
|
2023-05-15 10:53:52 +01:00
|
|
|
struct cacheItem {
|
2026-01-02 18:59:51 +00:00
|
|
|
cacheItem() = default;
|
|
|
|
|
cacheItem(const cacheItem&) = default;
|
|
|
|
|
cacheItem& operator=(const cacheItem&) = default;
|
|
|
|
|
//cacheItem (cacheItem const &c): command(c.command), req(c.req), reply(c.reply), value(c.value), receiver(c.receiver) {};
|
2024-03-30 20:40:27 +00:00
|
|
|
cacheItem (funcs command, QVariant value, uchar receiver=0) : command(command), req(QDateTime()), reply(QDateTime()), value(value), receiver(receiver){};
|
2023-05-15 10:53:52 +01:00
|
|
|
|
2026-06-03 22:36:55 +01:00
|
|
|
funcs command = funcNone;
|
2023-06-05 09:27:37 +01:00
|
|
|
QDateTime req;
|
|
|
|
|
QDateTime reply;
|
|
|
|
|
QVariant value;
|
2026-06-03 22:36:55 +01:00
|
|
|
uchar receiver = 0;
|
2026-03-02 09:28:07 +00:00
|
|
|
uchar retries=0;
|
2026-01-02 18:59:51 +00:00
|
|
|
|
|
|
|
|
/*
|
2025-01-02 16:16:11 +00:00
|
|
|
cacheItem &operator=(const cacheItem &i) {
|
|
|
|
|
this->receiver=i.receiver;
|
|
|
|
|
this->command=i.command;
|
|
|
|
|
this->reply=i.reply;
|
|
|
|
|
this->req=i.req;
|
|
|
|
|
this->value=i.value;
|
|
|
|
|
return *this;
|
|
|
|
|
}
|
2026-01-02 18:59:51 +00:00
|
|
|
*/
|
2023-05-15 10:53:52 +01:00
|
|
|
};
|
|
|
|
|
|
2023-05-12 00:24:01 +01:00
|
|
|
class cachingQueue : public QThread
|
|
|
|
|
{
|
|
|
|
|
Q_OBJECT
|
|
|
|
|
|
|
|
|
|
signals:
|
2024-03-30 20:40:27 +00:00
|
|
|
void haveCommand(funcs func, QVariant param, uchar receiver);
|
2026-06-02 21:03:57 +01:00
|
|
|
void haveRawCommand(QByteArray data, uchar receiver);
|
2023-05-15 10:53:52 +01:00
|
|
|
void sendValue(cacheItem item);
|
2024-04-30 09:42:54 +01:00
|
|
|
void sendMessage(QString msg);
|
2023-07-06 10:36:11 +01:00
|
|
|
void cacheUpdated(cacheItem item);
|
2023-12-18 10:47:16 +00:00
|
|
|
void rigCapsUpdated(rigCapabilities* caps);
|
2025-01-06 12:51:56 +00:00
|
|
|
void intervalUpdated(qint64 val);
|
2023-05-15 10:53:52 +01:00
|
|
|
|
|
|
|
|
public slots:
|
|
|
|
|
// Can be called directly or via emit.
|
2024-03-30 20:40:27 +00:00
|
|
|
void receiveValue(funcs func, QVariant value, uchar receiver);
|
2023-05-12 00:24:01 +01:00
|
|
|
|
|
|
|
|
private:
|
2023-05-15 10:53:52 +01:00
|
|
|
|
2023-05-12 00:24:01 +01:00
|
|
|
static cachingQueue *instance;
|
2023-05-15 12:34:24 +01:00
|
|
|
static QMutex instanceMutex;
|
2023-05-15 10:53:52 +01:00
|
|
|
|
2023-05-15 11:15:35 +01:00
|
|
|
QMutex mutex;
|
2023-05-15 10:53:52 +01:00
|
|
|
|
2024-10-25 11:39:04 +01:00
|
|
|
QMultiMap <queuePriority,queueItem> queue;
|
|
|
|
|
QMultiMap<funcs,cacheItem> cache;
|
|
|
|
|
QQueue<cacheItem> items;
|
|
|
|
|
QQueue<QString> messages;
|
|
|
|
|
QWaitCondition waiting;
|
2023-05-12 00:24:01 +01:00
|
|
|
|
|
|
|
|
// Command to set cache value
|
2024-03-30 20:40:27 +00:00
|
|
|
void setCache(funcs func, QVariant val, uchar receiver=0);
|
|
|
|
|
queuePriority isRecurring(funcs func, uchar receiver=0);
|
2023-07-06 10:36:11 +01:00
|
|
|
bool compare(QVariant a, QVariant b);
|
2023-05-15 10:53:52 +01:00
|
|
|
|
|
|
|
|
// Various other values
|
2026-01-02 18:59:51 +00:00
|
|
|
std::atomic_bool aborted{false};
|
2024-05-20 14:35:36 +01:00
|
|
|
qint64 queueInterval=-1; // Don't start the timer!
|
2023-12-18 10:47:16 +00:00
|
|
|
|
2026-01-02 18:59:51 +00:00
|
|
|
rigCapabilities* rigCaps = nullptr; // Must be NULL until a radio is connected
|
2023-12-18 10:47:16 +00:00
|
|
|
|
2023-05-15 10:53:52 +01:00
|
|
|
// Functions
|
|
|
|
|
void run();
|
2024-03-30 20:40:27 +00:00
|
|
|
funcs checkCommandAvailable(funcs cmd, bool set=false);
|
2025-01-09 00:35:26 +00:00
|
|
|
rigStateType rigState;
|
2025-07-19 08:41:16 +01:00
|
|
|
QByteArray yaesuData;
|
2023-05-15 10:53:52 +01:00
|
|
|
|
2023-05-12 00:24:01 +01:00
|
|
|
protected:
|
2026-01-02 18:59:51 +00:00
|
|
|
cachingQueue(QObject* parent = nullptr) : QThread(parent) {};
|
2023-05-12 00:24:01 +01:00
|
|
|
~cachingQueue();
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
cachingQueue(cachingQueue &other) = delete;
|
|
|
|
|
void operator=(const cachingQueue &) = delete;
|
|
|
|
|
|
2026-01-02 18:59:51 +00:00
|
|
|
static cachingQueue *getInstance(QObject* parent = nullptr);
|
2023-05-12 00:24:01 +01:00
|
|
|
void message(QString msg);
|
2025-07-19 08:41:16 +01:00
|
|
|
void putYaesuData(QByteArray data) { yaesuData = data;}
|
|
|
|
|
QByteArray getYaesuData() { return yaesuData; }
|
2025-01-18 12:29:34 +00:00
|
|
|
|
2024-03-30 20:40:27 +00:00
|
|
|
void add(queuePriority prio ,funcs func, bool recurring=false, uchar receiver=0);
|
2025-01-18 12:29:34 +00:00
|
|
|
void add(queuePriority prio,queueItem item, bool unique=false);
|
2024-03-30 20:40:27 +00:00
|
|
|
void addUnique(queuePriority prio ,funcs func, bool recurring=false, uchar receiver=0);
|
2025-01-18 12:29:34 +00:00
|
|
|
void addUnique(queuePriority prio, queueItem item);
|
|
|
|
|
|
2026-05-27 18:37:28 +01:00
|
|
|
queuePriority del(funcs func, uchar receiver=0, bool includePending=false);
|
2023-05-12 00:24:01 +01:00
|
|
|
void clear();
|
2026-01-18 12:19:55 +00:00
|
|
|
void clearCache();
|
|
|
|
|
|
2024-05-20 14:35:36 +01:00
|
|
|
void interval(qint64 val);
|
|
|
|
|
qint64 interval() {return queueInterval;}
|
2023-06-05 09:27:37 +01:00
|
|
|
void updateCache(bool reply, queueItem item);
|
2024-03-30 20:40:27 +00:00
|
|
|
void updateCache(bool reply, funcs func, QVariant value=QVariant(), uchar receiver=0);
|
2023-05-15 10:53:52 +01:00
|
|
|
|
2024-03-30 20:40:27 +00:00
|
|
|
cacheItem getCache(funcs func, uchar receiver=0);
|
2023-05-15 10:53:52 +01:00
|
|
|
|
2024-11-02 13:43:59 +00:00
|
|
|
queuePriority getQueued(funcs func, uchar receiver=0);
|
|
|
|
|
|
2024-11-05 18:46:21 +00:00
|
|
|
queuePriority changePriority(queuePriority prio, funcs func, uchar receiver=0);
|
|
|
|
|
|
2024-07-10 13:12:24 +01:00
|
|
|
QMultiMap <funcs,cacheItem>* getCacheItems();
|
|
|
|
|
QMultiMap <queuePriority,queueItem>* getQueueItems();
|
2023-07-06 10:36:11 +01:00
|
|
|
void lockMutex() {mutex.lock();}
|
|
|
|
|
void unlockMutex() {mutex.unlock();}
|
2024-03-25 12:42:08 +00:00
|
|
|
void setRigCaps(rigCapabilities* caps) { if (rigCaps != caps) { rigCaps = caps; emit rigCapsUpdated(rigCaps);} }
|
2023-12-18 10:47:16 +00:00
|
|
|
rigCapabilities* getRigCaps() { return rigCaps; }
|
2025-01-09 00:35:26 +00:00
|
|
|
vfoCommandType getVfoCommand(vfo_t vfo, uchar rx, bool set=false);
|
2025-01-09 21:29:44 +00:00
|
|
|
rigStateType getState() { QMutexLocker locker(&mutex); return rigState ;}
|
2023-05-12 00:24:01 +01:00
|
|
|
};
|
|
|
|
|
|
2023-05-15 14:32:46 +01:00
|
|
|
Q_DECLARE_METATYPE(queueItem)
|
|
|
|
|
Q_DECLARE_METATYPE(cacheItem)
|
2023-05-12 00:24:01 +01:00
|
|
|
#endif // CACHINGQUEUE_H
|