File: cachingqueue.h

package info (click to toggle)
wfview 2.11-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 15,256 kB
  • sloc: cpp: 43,386; ansic: 3,196; sh: 32; xml: 29; makefile: 11
file content (154 lines) | stat: -rw-r--r-- 5,675 bytes parent folder | download
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