|
- /*
- * Simple Queue, specially developed for MIDI messages
- * Copyright (C) 2012 Filipe Coelho <falktx@falktx.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * For a full copy of the GNU General Public License see the COPYING file
- */
-
- #ifndef MIDI_QUEUE_HPP
- #define MIDI_QUEUE_HPP
-
- #include <cstring>
- #include <QtCore/QMutex>
-
- class Queue
- {
- public:
- Queue()
- {
- index = 0;
- empty = true;
- full = false;
- }
-
- void copyDataFrom(Queue* queue)
- {
- // lock mutexes
- queue->mutex.lock();
- mutex.lock();
-
- // copy data from queue
- ::memcpy(data, queue->data, sizeof(datatype)*MAX_SIZE);
- index = queue->index;
- empty = queue->empty;
- full = queue->full;
-
- // unlock our mutex, no longer needed
- mutex.unlock();
-
- // reset queque
- ::memset(queue->data, 0, sizeof(datatype)*MAX_SIZE);
- queue->index = 0;
- queue->empty = true;
- queue->full = false;
-
- // unlock queque mutex
- queue->mutex.unlock();
- }
-
- bool isEmpty()
- {
- return empty;
- }
-
- bool isFull()
- {
- return full;
- }
-
- void lock()
- {
- mutex.lock();
- }
-
- void unlock()
- {
- mutex.unlock();
- }
-
- void put(unsigned char d1, unsigned char d2, unsigned char d3, bool lock = true)
- {
- Q_ASSERT(d1 != 0);
-
- if (full || d1 == 0)
- return;
-
- if (lock)
- mutex.lock();
-
- for (unsigned short i=0; i < MAX_SIZE; i++)
- {
- if (data[i].d1 == 0)
- {
- data[i].d1 = d1;
- data[i].d2 = d2;
- data[i].d3 = d3;
- empty = false;
- full = (i == MAX_SIZE-1);
- break;
- }
- }
-
- if (lock)
- mutex.unlock();
- }
-
- bool get(unsigned char* d1, unsigned char* d2, unsigned char* d3, bool lock = true)
- {
- Q_ASSERT(d1 && d2 && d3);
-
- if (empty || ! (d1 && d2 && d3))
- return false;
-
- if (lock)
- mutex.lock();
-
- full = false;
-
- if (data[index].d1 == 0)
- {
- index = 0;
- empty = true;
-
- if (lock)
- mutex.unlock();
-
- return false;
- }
-
- *d1 = data[index].d1;
- *d2 = data[index].d2;
- *d3 = data[index].d3;
-
- data[index].d1 = data[index].d2 = data[index].d3 = 0;
- index++;
- empty = false;
-
- if (lock)
- mutex.unlock();
-
- return true;
- }
-
- private:
- struct datatype {
- unsigned char d1, d2, d3;
-
- datatype()
- : d1(0), d2(0), d3(0) {}
- };
-
- static const unsigned short MAX_SIZE = 512;
- datatype data[MAX_SIZE];
- unsigned short index;
- bool empty, full;
-
- QMutex mutex;
- };
-
- #endif // MIDI_QUEUE_HPP
|