WingHexPy/PythonQt/PythonQtMisc.h

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