|
- /*
- * Simple Queue, specially developed for Atom types
- * Copyright (C) 2012-2013 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 GPL.txt file
- */
-
- #ifndef __LV2_ATOM_QUEUE_HPP__
- #define __LV2_ATOM_QUEUE_HPP__
-
- #include "CarlaLv2Utils.hpp"
- #include "CarlaMutex.hpp"
-
- class Lv2AtomQueue
- {
- public:
- Lv2AtomQueue()
- : fIndex(0),
- fIndexPool(0),
- fEmpty(true),
- fFull(false)
- {
- std::memset(fDataPool, 0, sizeof(unsigned char)*MAX_POOL_SIZE);
- }
-
- void copyDataFrom(Lv2AtomQueue* const queue)
- {
- // lock mutexes
- queue->lock();
- lock();
-
- // copy data from queue
- std::memcpy(fData, queue->fData, sizeof(DataType)*MAX_SIZE);
- std::memcpy(fDataPool, queue->fDataPool, sizeof(unsigned char)*MAX_POOL_SIZE);
- fIndex = queue->fIndex;
- fIndexPool = queue->fIndexPool;
- fEmpty = queue->fEmpty;
- fFull = queue->fFull;
-
- // unlock our mutex, no longer needed
- unlock();
-
- // reset queque
- std::memset(queue->fData, 0, sizeof(DataType)*MAX_SIZE);
- std::memset(queue->fDataPool, 0, sizeof(unsigned char)*MAX_POOL_SIZE);
- queue->fIndex = queue->fIndexPool = 0;
- queue->fEmpty = true;
- queue->fFull = false;
-
- // unlock queque mutex
- queue->unlock();
- }
-
- bool isEmpty() const
- {
- return fEmpty;
- }
-
- bool isFull() const
- {
- return fFull;
- }
-
- void lock()
- {
- fMutex.lock();
- }
-
- bool tryLock()
- {
- return fMutex.tryLock();
- }
-
- void unlock()
- {
- fMutex.unlock();
- }
-
- bool put(const uint32_t portIndex, const LV2_Atom* const atom)
- {
- CARLA_ASSERT(atom != nullptr && atom->size > 0);
- CARLA_ASSERT(fIndexPool + atom->size < MAX_POOL_SIZE); // overflow
-
- if (fFull || atom == nullptr || fIndexPool + atom->size >= MAX_POOL_SIZE)
- return false;
- if (atom->size == 0)
- return true;
-
- bool ret = false;
-
- lock();
-
- for (unsigned short i=0; i < MAX_SIZE; ++i)
- {
- if (fData[i].size == 0)
- {
- fData[i].portIndex = portIndex;
- fData[i].size = atom->size;
- fData[i].type = atom->type;
- fData[i].poolOffset = fIndexPool;
- std::memcpy(fDataPool + fIndexPool, LV2NV_ATOM_BODY_CONST(atom), atom->size);
- fEmpty = false;
- fFull = (i == MAX_SIZE-1);
- fIndexPool += atom->size;
- ret = true;
- break;
- }
- }
-
- unlock();
-
- return ret;
- }
-
- // needs to be locked first!
- bool get(uint32_t* const portIndex, const LV2_Atom** const atom)
- {
- CARLA_ASSERT(portIndex != nullptr && atom != nullptr);
-
- if (fEmpty || portIndex == nullptr || atom == nullptr)
- return false;
-
- fFull = false;
-
- if (fData[fIndex].size == 0)
- {
- fIndex = fIndexPool = 0;
- fEmpty = true;
-
- unlock();
- return false;
- }
-
- fRetAtom.atom.size = fData[fIndex].size;
- fRetAtom.atom.type = fData[fIndex].type;
- std::memcpy(fRetAtom.data, fDataPool + fData[fIndex].poolOffset, fData[fIndex].size);
-
- *portIndex = fData[fIndex].portIndex;
- *atom = (LV2_Atom*)&fRetAtom;
-
- fData[fIndex].portIndex = 0;
- fData[fIndex].size = 0;
- fData[fIndex].type = 0;
- fData[fIndex].poolOffset = 0;
- fEmpty = false;
- ++fIndex;
-
- return true;
- }
-
- private:
- struct DataType {
- size_t size;
- uint32_t type;
- uint32_t portIndex;
- uint32_t poolOffset;
-
- DataType()
- : size(0),
- type(0),
- portIndex(0),
- poolOffset(0) {}
- };
-
- static const unsigned short MAX_SIZE = 128;
- static const unsigned short MAX_POOL_SIZE = 8192;
-
- DataType fData[MAX_SIZE];
- unsigned char fDataPool[MAX_POOL_SIZE];
-
- struct RetAtom {
- LV2_Atom atom;
- unsigned char data[MAX_POOL_SIZE];
- } fRetAtom;
-
- unsigned short fIndex, fIndexPool;
- bool fEmpty, fFull;
-
- CarlaMutex fMutex;
- };
-
- #endif // __LV2_ATOM_QUEUE_HPP__
|