179 lines
6.0 KiB
C++
179 lines
6.0 KiB
C++
#ifndef PYTHONQTMISC_H
|
|
#define PYTHONQTMISC_H
|
|
|
|
/*
|
|
*
|
|
* Copyright (C) 2010 MeVis Medical Solutions AG All Rights Reserved.
|
|
*
|
|
* This library is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
* License as published by the Free Software Foundation; either
|
|
* version 2.1 of the License, or (at your option) any later version.
|
|
*
|
|
* This library 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
|
|
* Lesser General Public License for more details.
|
|
*
|
|
* Further, this software is distributed without any warranty that it is
|
|
* free of the rightful claim of any third person regarding infringement
|
|
* or the like. Any license provided herein, whether implied or
|
|
* otherwise, applies only to this software file. Patent licenses, if
|
|
* any, provided herein do not apply to combinations of this program with
|
|
* other software, or any other product whatsoever.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
* License along with this library; if not, write to the Free Software
|
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
*
|
|
* Contact information: MeVis Medical Solutions AG, Universitaetsallee 29,
|
|
* 28359 Bremen, Germany or:
|
|
*
|
|
* http://www.mevis.de
|
|
*
|
|
*/
|
|
|
|
//----------------------------------------------------------------------------------
|
|
/*!
|
|
// \file PythonQtMisc.h
|
|
// \author Florian Link
|
|
// \author Last changed by $Author: florian $
|
|
// \date 2006-05
|
|
*/
|
|
//----------------------------------------------------------------------------------
|
|
|
|
#include <QList>
|
|
|
|
#define PythonQtValueStorage_ADD_VALUE(store, type, value, ptr) \
|
|
{ \
|
|
type *item = (type *)store.nextValuePtr(); \
|
|
*item = value; \
|
|
ptr = (void *)item; \
|
|
}
|
|
|
|
#define PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedPtr, store, \
|
|
type, value, ptr) \
|
|
{ \
|
|
type *item = (type *)(alreadyAllocatedPtr ? alreadyAllocatedPtr \
|
|
: store.nextValuePtr()); \
|
|
*item = value; \
|
|
ptr = (void *)item; \
|
|
}
|
|
|
|
//! stores a position in the PythonQtValueStorage
|
|
class PythonQtValueStoragePosition {
|
|
|
|
public:
|
|
PythonQtValueStoragePosition() {
|
|
chunkIdx = 0;
|
|
chunkOffset = 0;
|
|
}
|
|
|
|
int chunkIdx;
|
|
int chunkOffset;
|
|
};
|
|
|
|
//! a helper class that stores basic C++ value types in chunks
|
|
template <typename T, int chunkEntries> class PythonQtValueStorage {
|
|
public:
|
|
PythonQtValueStorage() {
|
|
_chunkIdx = 0;
|
|
_chunkOffset = 0;
|
|
_currentChunk = new T[chunkEntries];
|
|
_chunks.append(_currentChunk);
|
|
}
|
|
|
|
//! clear all memory
|
|
void clear() {
|
|
T *chunk;
|
|
Q_FOREACH (chunk, _chunks) { delete[] chunk; }
|
|
_chunks.clear();
|
|
}
|
|
|
|
//! get the current position to be restored with setPos
|
|
void getPos(PythonQtValueStoragePosition &pos) {
|
|
pos.chunkIdx = _chunkIdx;
|
|
pos.chunkOffset = _chunkOffset;
|
|
}
|
|
|
|
//! set the current position (without freeing memory, thus caching old entries
|
|
//! for reuse)
|
|
void setPos(const PythonQtValueStoragePosition &pos) {
|
|
_chunkOffset = pos.chunkOffset;
|
|
if (_chunkIdx != pos.chunkIdx) {
|
|
_chunkIdx = pos.chunkIdx;
|
|
_currentChunk = _chunks.at(_chunkIdx);
|
|
}
|
|
}
|
|
|
|
//! add one default constructed value and return the pointer to it
|
|
T *nextValuePtr() {
|
|
if (_chunkOffset >= chunkEntries) {
|
|
_chunkIdx++;
|
|
if (_chunkIdx >= _chunks.size()) {
|
|
T *newChunk = new T[chunkEntries];
|
|
_chunks.append(newChunk);
|
|
_currentChunk = newChunk;
|
|
} else {
|
|
_currentChunk = _chunks.at(_chunkIdx);
|
|
}
|
|
_chunkOffset = 0;
|
|
}
|
|
T *newEntry = _currentChunk + _chunkOffset;
|
|
_chunkOffset++;
|
|
return newEntry;
|
|
}
|
|
|
|
protected:
|
|
QList<T *> _chunks;
|
|
|
|
int _chunkIdx;
|
|
int _chunkOffset;
|
|
T *_currentChunk;
|
|
};
|
|
|
|
//! a helper class that stores basic C++ value types in chunks and clears the
|
|
//! unused values on setPos() usage.
|
|
template <typename T, int chunkEntries>
|
|
class PythonQtValueStorageWithCleanup
|
|
: public PythonQtValueStorage<T, chunkEntries> {
|
|
public:
|
|
void setPos(const PythonQtValueStoragePosition &pos) {
|
|
if (_chunkIdx > pos.chunkIdx) {
|
|
T *firstChunk = _chunks.at(pos.chunkIdx);
|
|
// clear region in first chunk
|
|
for (int i = pos.chunkOffset; i < chunkEntries; i++) {
|
|
firstChunk[i] = T();
|
|
}
|
|
for (int chunk = pos.chunkIdx + 1; chunk < _chunkIdx; chunk++) {
|
|
// clear the full chunks between the first and last chunk
|
|
T *fullChunk = _chunks.at(chunk);
|
|
for (int i = 0; i < chunkEntries; i++) {
|
|
fullChunk[i] = T();
|
|
}
|
|
}
|
|
// clear region in last chunk
|
|
T *lastChunk = _chunks.at(_chunkIdx);
|
|
for (int i = 0; i < _chunkOffset; i++) {
|
|
lastChunk[i] = T();
|
|
}
|
|
} else if (_chunkIdx == pos.chunkIdx) {
|
|
// clear the region in the last chunk only
|
|
T *lastChunk = _chunks.at(_chunkIdx);
|
|
for (int i = pos.chunkOffset; i < _chunkOffset; i++) {
|
|
lastChunk[i] = T();
|
|
}
|
|
}
|
|
|
|
PythonQtValueStorage<T, chunkEntries>::setPos(pos);
|
|
}
|
|
|
|
private:
|
|
using PythonQtValueStorage<T, chunkEntries>::_chunks;
|
|
using PythonQtValueStorage<T, chunkEntries>::_chunkIdx;
|
|
using PythonQtValueStorage<T, chunkEntries>::_chunkOffset;
|
|
using PythonQtValueStorage<T, chunkEntries>::_currentChunk;
|
|
};
|
|
|
|
#endif
|