1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154
|
#ifndef CACHINGQUEUE_H
#define CACHINGQUEUE_H
#include <QCoreApplication>
#include <QObject>
#include <QThread>
#include <QMutex>
#include <QMutexLocker>
#include <QMap>
#include <QMultiMap>
#include <QVariant>
#include <QQueue>
#include <QRect>
#include <QWaitCondition>
#include <QDateTime>
#include <QRandomGenerator>
#include "wfviewtypes.h"
#include "rigidentities.h"
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
};
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}};
// Command with no param is a get by default
struct queueItem {
queueItem () {}
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){};
funcs command;
QVariant param;
uchar receiver;
bool recurring;
qint64 id = QDateTime::currentMSecsSinceEpoch();
bool operator==(const queueItem& lhs)
{
return (lhs.command == command && lhs.receiver == receiver && lhs.recurring == recurring);
}
};
struct cacheItem {
cacheItem () {};
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){};
funcs command;
QDateTime req;
QDateTime reply;
QVariant value;
uchar receiver;
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;
}
};
class cachingQueue : public QThread
{
Q_OBJECT
signals:
void haveCommand(funcs func, QVariant param, uchar receiver);
void sendValue(cacheItem item);
void sendMessage(QString msg);
void cacheUpdated(cacheItem item);
void rigCapsUpdated(rigCapabilities* caps);
void intervalUpdated(qint64 val);
public slots:
// Can be called directly or via emit.
void receiveValue(funcs func, QVariant value, uchar receiver);
private:
static cachingQueue *instance;
static QMutex instanceMutex;
QMutex mutex;
QMultiMap <queuePriority,queueItem> queue;
QMultiMap<funcs,cacheItem> cache;
QQueue<cacheItem> items;
QQueue<QString> messages;
QWaitCondition waiting;
// 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);
// Various other values
bool aborted=false;
qint64 queueInterval=-1; // Don't start the timer!
rigCapabilities* rigCaps = Q_NULLPTR; // Must be NULL until a radio is connected
// Functions
void run();
funcs checkCommandAvailable(funcs cmd, bool set=false);
rigStateType rigState;
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);
void add(queuePriority prio ,funcs func, bool recurring=false, uchar receiver=0);
void add(queuePriority prio,queueItem item, bool unique=false);
void addUnique(queuePriority prio ,funcs func, bool recurring=false, uchar receiver=0);
void addUnique(queuePriority prio, queueItem item);
queuePriority del(funcs func, uchar receiver=0);
void clear();
void interval(qint64 val);
qint64 interval() {return queueInterval;}
void updateCache(bool reply, queueItem item);
void updateCache(bool reply, funcs func, QVariant value=QVariant(), uchar receiver=0);
cacheItem getCache(funcs func, uchar receiver=0);
queuePriority getQueued(funcs func, uchar receiver=0);
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);} }
rigCapabilities* getRigCaps() { return rigCaps; }
vfoCommandType getVfoCommand(vfo_t vfo, uchar rx, bool set=false);
rigStateType getState() { QMutexLocker locker(&mutex); return rigState ;}
};
Q_DECLARE_METATYPE(queueItem)
Q_DECLARE_METATYPE(cacheItem)
#endif // CACHINGQUEUE_H
|