wfview/include/cachingqueue.h

162 lines
5.8 KiB
C
Raw Permalink Normal View History

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>
#include <QRandomGenerator>
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 {
2023-06-05 09:27:37 +01:00
queueItem () {}
2024-12-27 13:26:26 +00:00
queueItem (queueItem const &q): command(q.command), param(q.param), receiver(q.receiver), recurring(q.recurring) {};
queueItem (funcs command, QVariant param, bool recurring, uchar receiver) : command(command), param(param), receiver(receiver), recurring(recurring){};
queueItem (funcs command, QVariant param, bool recurring) : command(command), param(param), receiver(false), recurring(recurring){};
queueItem (funcs command, QVariant param) : command(command), param(param),receiver(0), recurring(false){};
queueItem (funcs command, bool recurring, uchar receiver) : command(command), param(QVariant()), receiver(receiver), recurring(recurring) {};
queueItem (funcs command, bool recurring) : command(command), param(QVariant()), receiver(0), recurring(recurring) {};
queueItem (funcs command) : command(command), param(QVariant()), receiver(0), recurring(false){};
2023-06-05 09:27:37 +01:00
funcs command;
QVariant param;
uchar receiver;
2023-06-05 09:27:37 +01:00
bool recurring;
qint64 id = QDateTime::currentMSecsSinceEpoch();
2026-04-10 14:17:11 +01:00
2024-06-12 17:11:01 +01:00
bool operator==(const queueItem& lhs)
{
2026-04-10 14:17:11 +01:00
return (lhs.command == command &&
lhs.receiver == receiver &&
lhs.recurring == recurring &&
lhs.param.isValid() == param.isValid());
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 {
cacheItem () {};
2024-12-27 13:26:26 +00:00
cacheItem (cacheItem const &c): command(c.command), req(c.req), reply(c.reply), value(c.value), receiver(c.receiver) {};
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
2023-06-05 09:27:37 +01:00
funcs command;
QDateTime req;
QDateTime reply;
QVariant value;
uchar receiver;
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;
}
2023-05-15 10:53:52 +01:00
};
2023-05-12 00:24:01 +01:00
class cachingQueue : public QThread
{
Q_OBJECT
signals:
void haveCommand(funcs func, QVariant param, 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);
void cacheUpdated(cacheItem item);
2023-12-18 10:47:16 +00:00
void rigCapsUpdated(rigCapabilities* caps);
void intervalUpdated(qint64 val);
2023-05-15 10:53:52 +01:00
public slots:
// Can be called directly or via emit.
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
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
void setCache(funcs func, QVariant val, uchar receiver=0);
queuePriority isRecurring(funcs func, uchar receiver=0);
bool compare(QVariant a, QVariant b);
2023-05-15 10:53:52 +01:00
// Various other values
2023-05-15 11:15:35 +01:00
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
rigCapabilities* rigCaps = Q_NULLPTR; // Must be NULL until a radio is connected
2023-05-15 10:53:52 +01:00
// Functions
void run();
funcs checkCommandAvailable(funcs cmd, bool set=false);
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:
cachingQueue(QObject* parent = Q_NULLPTR) : QThread(parent) {};
~cachingQueue();
public:
cachingQueue(cachingQueue &other) = delete;
void operator=(const cachingQueue &) = delete;
static cachingQueue *getInstance(QObject* parent = Q_NULLPTR);
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
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);
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);
queuePriority del(funcs func, uchar receiver=0);
2023-05-12 00:24:01 +01:00
void clear();
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);
void updateCache(bool reply, funcs func, QVariant value=QVariant(), uchar receiver=0);
2023-05-15 10:53:52 +01:00
cacheItem getCache(funcs func, uchar receiver=0);
2023-05-15 10:53:52 +01: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);
QMultiMap <funcs,cacheItem>* getCacheItems();
QMultiMap <queuePriority,queueItem>* getQueueItems();
void lockMutex() {mutex.lock();}
void unlockMutex() {mutex.unlock();}
void setRigCaps(rigCapabilities* caps) { if (rigCaps != caps) { rigCaps = caps; emit rigCapsUpdated(rigCaps);} }
2023-12-18 10:47:16 +00:00
rigCapabilities* getRigCaps() { return rigCaps; }
vfoCommandType getVfoCommand(vfo_t vfo, uchar rx, bool set=false);
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