mirror of
https://github.com/YACReader/yacreader
synced 2026-04-12 15:49:53 -04:00
Extract the comic and page flow classes to their own files
This commit is contained in:
@ -110,6 +110,8 @@ HEADERS += ../common/comic.h \
|
|||||||
|
|
||||||
greaterThan(QT_MAJOR_VERSION, 5):greaterThan(QT_MINOR_VERSION, 6) {
|
greaterThan(QT_MAJOR_VERSION, 5):greaterThan(QT_MINOR_VERSION, 6) {
|
||||||
HEADERS += ../common/rhi/yacreader_flow_rhi.h
|
HEADERS += ../common/rhi/yacreader_flow_rhi.h
|
||||||
|
HEADERS += ../common/rhi/yacreader_comic_flow_rhi.h \
|
||||||
|
../common/rhi/yacreader_page_flow_rhi.h
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -153,6 +155,8 @@ SOURCES += ../common/comic.cpp \
|
|||||||
|
|
||||||
greaterThan(QT_MAJOR_VERSION, 5):greaterThan(QT_MINOR_VERSION, 6) {
|
greaterThan(QT_MAJOR_VERSION, 5):greaterThan(QT_MINOR_VERSION, 6) {
|
||||||
SOURCES += ../common/rhi/yacreader_flow_rhi.cpp
|
SOURCES += ../common/rhi/yacreader_flow_rhi.cpp
|
||||||
|
SOURCES += ../common/rhi/yacreader_comic_flow_rhi.cpp \
|
||||||
|
../common/rhi/yacreader_page_flow_rhi.cpp
|
||||||
RESOURCES += ../common/rhi/shaders/shaders.qrc
|
RESOURCES += ../common/rhi/shaders/shaders.qrc
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
// Conditional include based on Qt version and RHI availability
|
// Conditional include based on Qt version and RHI availability
|
||||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 7, 0) && defined(YACREADER_USE_RHI)
|
#if QT_VERSION >= QT_VERSION_CHECK(6, 7, 0) && defined(YACREADER_USE_RHI)
|
||||||
#include "yacreader_flow_rhi.h"
|
#include "yacreader_page_flow_rhi.h"
|
||||||
using YACReaderPageFlowImpl = YACReaderPageFlow3D;
|
using YACReaderPageFlowImpl = YACReaderPageFlow3D;
|
||||||
#else
|
#else
|
||||||
#include "yacreader_flow_gl.h"
|
#include "yacreader_flow_gl.h"
|
||||||
|
|||||||
@ -157,6 +157,8 @@ HEADERS += comic_flow.h \
|
|||||||
|
|
||||||
greaterThan(QT_MAJOR_VERSION, 5):greaterThan(QT_MINOR_VERSION, 6) {
|
greaterThan(QT_MAJOR_VERSION, 5):greaterThan(QT_MINOR_VERSION, 6) {
|
||||||
HEADERS += ../common/rhi/yacreader_flow_rhi.h
|
HEADERS += ../common/rhi/yacreader_flow_rhi.h
|
||||||
|
HEADERS += ../common/rhi/yacreader_comic_flow_rhi.h \
|
||||||
|
../common/rhi/yacreader_page_flow_rhi.h
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -249,6 +251,8 @@ SOURCES += comic_flow.cpp \
|
|||||||
|
|
||||||
greaterThan(QT_MAJOR_VERSION, 5):greaterThan(QT_MINOR_VERSION, 6) {
|
greaterThan(QT_MAJOR_VERSION, 5):greaterThan(QT_MINOR_VERSION, 6) {
|
||||||
SOURCES += ../common/rhi/yacreader_flow_rhi.cpp
|
SOURCES += ../common/rhi/yacreader_flow_rhi.cpp
|
||||||
|
SOURCES += ../common/rhi/yacreader_comic_flow_rhi.cpp \
|
||||||
|
../common/rhi/yacreader_page_flow_rhi.cpp
|
||||||
RESOURCES += ../common/rhi/shaders/shaders.qrc
|
RESOURCES += ../common/rhi/shaders/shaders.qrc
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -8,7 +8,7 @@
|
|||||||
#ifndef NO_OPENGL
|
#ifndef NO_OPENGL
|
||||||
// Conditional include based on Qt version and RHI availability
|
// Conditional include based on Qt version and RHI availability
|
||||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 7, 0) && defined(YACREADER_USE_RHI)
|
#if QT_VERSION >= QT_VERSION_CHECK(6, 7, 0) && defined(YACREADER_USE_RHI)
|
||||||
#include "yacreader_flow_rhi.h"
|
#include "yacreader_comic_flow_rhi.h"
|
||||||
using YACReaderComicFlowImpl = YACReaderComicFlow3D;
|
using YACReaderComicFlowImpl = YACReaderComicFlow3D;
|
||||||
#else
|
#else
|
||||||
#include "yacreader_flow_gl.h"
|
#include "yacreader_flow_gl.h"
|
||||||
|
|||||||
246
common/rhi/yacreader_comic_flow_rhi.cpp
Normal file
246
common/rhi/yacreader_comic_flow_rhi.cpp
Normal file
@ -0,0 +1,246 @@
|
|||||||
|
#include "yacreader_comic_flow_rhi.h"
|
||||||
|
#include <QImage>
|
||||||
|
|
||||||
|
// YACReaderComicFlow3D implementation
|
||||||
|
YACReaderComicFlow3D::YACReaderComicFlow3D(QWidget *parent, struct Preset p)
|
||||||
|
: YACReaderFlow3D(parent, p)
|
||||||
|
{
|
||||||
|
worker = new ImageLoader3D(this);
|
||||||
|
worker->flow = this;
|
||||||
|
}
|
||||||
|
|
||||||
|
void YACReaderComicFlow3D::setImagePaths(QStringList paths)
|
||||||
|
{
|
||||||
|
worker->reset();
|
||||||
|
reset();
|
||||||
|
numObjects = 0;
|
||||||
|
|
||||||
|
if (hasBeenInitialized) {
|
||||||
|
YACReaderFlow3D::populate(paths.size());
|
||||||
|
} else {
|
||||||
|
lazyPopulateObjects = paths.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
this->paths = paths;
|
||||||
|
}
|
||||||
|
|
||||||
|
void YACReaderComicFlow3D::updateImageData()
|
||||||
|
{
|
||||||
|
if (worker->busy())
|
||||||
|
return;
|
||||||
|
|
||||||
|
int idx = worker->index();
|
||||||
|
if (idx >= 0 && !worker->result().isNull()) {
|
||||||
|
if (!loaded[idx]) {
|
||||||
|
float x = 1;
|
||||||
|
QImage img = worker->result();
|
||||||
|
|
||||||
|
// Create QRhiTexture from the loaded image
|
||||||
|
if (m_rhi) {
|
||||||
|
QRhiTexture *texture = m_rhi->newTexture(QRhiTexture::BGRA8, img.size(), 1,
|
||||||
|
(performance == high || performance == ultraHigh) ? QRhiTexture::MipMapped : QRhiTexture::UsedAsTransferSource);
|
||||||
|
|
||||||
|
if (texture->create()) {
|
||||||
|
PendingTextureUpload upload;
|
||||||
|
upload.index = idx;
|
||||||
|
upload.image = img;
|
||||||
|
upload.x = x;
|
||||||
|
upload.y = 1 * (float(img.height()) / img.width());
|
||||||
|
pendingTextureUploads.append(upload);
|
||||||
|
|
||||||
|
QString s = "cover";
|
||||||
|
replace(s.toLocal8Bit().data(), texture, upload.x, upload.y, idx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int count = 8;
|
||||||
|
switch (performance) {
|
||||||
|
case low:
|
||||||
|
count = 8;
|
||||||
|
break;
|
||||||
|
case medium:
|
||||||
|
count = 10;
|
||||||
|
break;
|
||||||
|
case high:
|
||||||
|
count = 12;
|
||||||
|
break;
|
||||||
|
case ultraHigh:
|
||||||
|
count = 16;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
int *indexes = new int[2 * count + 1];
|
||||||
|
int center = currentSelected;
|
||||||
|
indexes[0] = center;
|
||||||
|
for (int j = 0; j < count; j++) {
|
||||||
|
indexes[j * 2 + 1] = center + j + 1;
|
||||||
|
indexes[j * 2 + 2] = center - j - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int c = 0; c < 2 * count + 1; c++) {
|
||||||
|
int i = indexes[c];
|
||||||
|
if ((i >= 0) && (i < numObjects))
|
||||||
|
if (!loaded[i]) {
|
||||||
|
if (paths.size() > 0) {
|
||||||
|
QString fname = paths.at(i);
|
||||||
|
worker->generate(i, fname);
|
||||||
|
}
|
||||||
|
delete[] indexes;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
delete[] indexes;
|
||||||
|
}
|
||||||
|
|
||||||
|
void YACReaderComicFlow3D::remove(int item)
|
||||||
|
{
|
||||||
|
worker->lock();
|
||||||
|
worker->reset();
|
||||||
|
YACReaderFlow3D::remove(item);
|
||||||
|
if (item >= 0 && item < paths.size()) {
|
||||||
|
paths.removeAt(item);
|
||||||
|
}
|
||||||
|
worker->unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
void YACReaderComicFlow3D::add(const QString &path, int index)
|
||||||
|
{
|
||||||
|
worker->lock();
|
||||||
|
worker->reset();
|
||||||
|
paths.insert(index, path);
|
||||||
|
YACReaderFlow3D::add(index);
|
||||||
|
worker->unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
void YACReaderComicFlow3D::resortCovers(QList<int> newOrder)
|
||||||
|
{
|
||||||
|
worker->lock();
|
||||||
|
worker->reset();
|
||||||
|
startAnimationTimer();
|
||||||
|
|
||||||
|
QList<QString> pathsNew;
|
||||||
|
QVector<bool> loadedNew;
|
||||||
|
QVector<YACReaderComicReadStatus> marksNew;
|
||||||
|
QVector<YACReader3DImageRHI> imagesNew;
|
||||||
|
|
||||||
|
int index = 0;
|
||||||
|
foreach (int i, newOrder) {
|
||||||
|
if (i < 0 || i >= images.size()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
pathsNew << paths.at(i);
|
||||||
|
loadedNew << loaded.at(i);
|
||||||
|
marksNew << marks.at(i);
|
||||||
|
imagesNew << images.at(i);
|
||||||
|
imagesNew.last().index = index++;
|
||||||
|
}
|
||||||
|
|
||||||
|
paths = pathsNew;
|
||||||
|
loaded = loadedNew;
|
||||||
|
marks = marksNew;
|
||||||
|
images = imagesNew;
|
||||||
|
|
||||||
|
worker->unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
// ImageLoader3D implementation
|
||||||
|
QImage ImageLoader3D::loadImage(const QString &fileName)
|
||||||
|
{
|
||||||
|
QImage image;
|
||||||
|
|
||||||
|
if (!image.load(fileName)) {
|
||||||
|
return QImage();
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (flow->performance) {
|
||||||
|
case low:
|
||||||
|
image = image.scaledToWidth(200, Qt::SmoothTransformation);
|
||||||
|
break;
|
||||||
|
case medium:
|
||||||
|
image = image.scaledToWidth(256, Qt::SmoothTransformation);
|
||||||
|
break;
|
||||||
|
case high:
|
||||||
|
image = image.scaledToWidth(320, Qt::SmoothTransformation);
|
||||||
|
break;
|
||||||
|
case ultraHigh:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return image;
|
||||||
|
}
|
||||||
|
|
||||||
|
ImageLoader3D::ImageLoader3D(YACReaderFlow3D *flow)
|
||||||
|
: QThread(), flow(flow), restart(false), working(false), idx(-1)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
ImageLoader3D::~ImageLoader3D()
|
||||||
|
{
|
||||||
|
mutex.lock();
|
||||||
|
condition.wakeOne();
|
||||||
|
mutex.unlock();
|
||||||
|
wait();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ImageLoader3D::busy() const
|
||||||
|
{
|
||||||
|
return isRunning() ? working : false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImageLoader3D::generate(int index, const QString &fileName)
|
||||||
|
{
|
||||||
|
mutex.lock();
|
||||||
|
this->idx = index;
|
||||||
|
this->fileName = fileName;
|
||||||
|
this->img = QImage();
|
||||||
|
mutex.unlock();
|
||||||
|
|
||||||
|
if (!isRunning())
|
||||||
|
start();
|
||||||
|
else {
|
||||||
|
restart = true;
|
||||||
|
condition.wakeOne();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImageLoader3D::lock()
|
||||||
|
{
|
||||||
|
mutex.lock();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImageLoader3D::unlock()
|
||||||
|
{
|
||||||
|
mutex.unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImageLoader3D::run()
|
||||||
|
{
|
||||||
|
for (;;) {
|
||||||
|
mutex.lock();
|
||||||
|
this->working = true;
|
||||||
|
QString fileName = this->fileName;
|
||||||
|
mutex.unlock();
|
||||||
|
|
||||||
|
QImage image = loadImage(fileName);
|
||||||
|
|
||||||
|
mutex.lock();
|
||||||
|
this->working = false;
|
||||||
|
this->img = image;
|
||||||
|
mutex.unlock();
|
||||||
|
|
||||||
|
mutex.lock();
|
||||||
|
if (!this->restart)
|
||||||
|
condition.wait(&mutex);
|
||||||
|
restart = false;
|
||||||
|
mutex.unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QImage ImageLoader3D::result()
|
||||||
|
{
|
||||||
|
return img;
|
||||||
|
}
|
||||||
59
common/rhi/yacreader_comic_flow_rhi.h
Normal file
59
common/rhi/yacreader_comic_flow_rhi.h
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
#ifndef __YACREADER_COMIC_FLOW_RHI_H
|
||||||
|
#define __YACREADER_COMIC_FLOW_RHI_H
|
||||||
|
|
||||||
|
#include "yacreader_flow_rhi.h"
|
||||||
|
|
||||||
|
class ImageLoader3D;
|
||||||
|
|
||||||
|
class YACReaderComicFlow3D : public YACReaderFlow3D
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
YACReaderComicFlow3D(QWidget *parent = nullptr, struct Preset p = defaultYACReaderFlowConfig);
|
||||||
|
void setImagePaths(QStringList paths);
|
||||||
|
void updateImageData() override;
|
||||||
|
void remove(int item) override;
|
||||||
|
void add(const QString &path, int index);
|
||||||
|
void resortCovers(QList<int> newOrder);
|
||||||
|
friend class ImageLoader3D;
|
||||||
|
|
||||||
|
private:
|
||||||
|
ImageLoader3D *worker;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
QList<QString> paths;
|
||||||
|
};
|
||||||
|
|
||||||
|
class ImageLoader3D : public QThread
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ImageLoader3D(YACReaderFlow3D *flow);
|
||||||
|
~ImageLoader3D();
|
||||||
|
bool busy() const;
|
||||||
|
void generate(int index, const QString &fileName);
|
||||||
|
void reset()
|
||||||
|
{
|
||||||
|
idx = -1;
|
||||||
|
fileName = "";
|
||||||
|
}
|
||||||
|
int index() const { return idx; }
|
||||||
|
void lock();
|
||||||
|
void unlock();
|
||||||
|
QImage result();
|
||||||
|
YACReaderFlow3D *flow;
|
||||||
|
QImage loadImage(const QString &fileName);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void run() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QMutex mutex;
|
||||||
|
QWaitCondition condition;
|
||||||
|
|
||||||
|
bool restart;
|
||||||
|
bool working;
|
||||||
|
int idx;
|
||||||
|
QString fileName;
|
||||||
|
QImage img;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // __YACREADER_COMIC_FLOW_RHI_H
|
||||||
@ -1259,446 +1259,6 @@ QSize YACReaderFlow3D::minimumSizeHint() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
// YACReaderComicFlow3D implementation
|
// YACReaderComicFlow3D implementation
|
||||||
YACReaderComicFlow3D::YACReaderComicFlow3D(QWidget *parent, struct Preset p)
|
// YACReaderComicFlow3D implementation moved to common/rhi/yacreader_comic_flow_rhi.*
|
||||||
: YACReaderFlow3D(parent, p)
|
|
||||||
{
|
|
||||||
worker = new ImageLoader3D(this);
|
|
||||||
worker->flow = this;
|
|
||||||
}
|
|
||||||
|
|
||||||
void YACReaderComicFlow3D::setImagePaths(QStringList paths)
|
// Implementations for derived flows and loaders live in their own files.
|
||||||
{
|
|
||||||
worker->reset();
|
|
||||||
reset();
|
|
||||||
numObjects = 0;
|
|
||||||
|
|
||||||
if (hasBeenInitialized) {
|
|
||||||
YACReaderFlow3D::populate(paths.size());
|
|
||||||
} else {
|
|
||||||
lazyPopulateObjects = paths.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
this->paths = paths;
|
|
||||||
}
|
|
||||||
|
|
||||||
void YACReaderComicFlow3D::updateImageData()
|
|
||||||
{
|
|
||||||
if (worker->busy())
|
|
||||||
return;
|
|
||||||
|
|
||||||
int idx = worker->index();
|
|
||||||
if (idx >= 0 && !worker->result().isNull()) {
|
|
||||||
if (!loaded[idx]) {
|
|
||||||
float x = 1;
|
|
||||||
QImage img = worker->result();
|
|
||||||
|
|
||||||
// // Ensure the loaded image is in RGBA8888 layout so QRhi interprets channels correctly
|
|
||||||
// if (img.format() != QImage::Format_RGBA8888)
|
|
||||||
// img = img.convertToFormat(QImage::Format_RGBA8888);
|
|
||||||
|
|
||||||
// Create QRhiTexture from the loaded image
|
|
||||||
if (m_rhi) {
|
|
||||||
QRhiTexture *texture = m_rhi->newTexture(QRhiTexture::BGRA8, img.size(), 1,
|
|
||||||
(performance == high || performance == ultraHigh) ? QRhiTexture::MipMapped : QRhiTexture::UsedAsTransferSource);
|
|
||||||
|
|
||||||
if (texture->create()) {
|
|
||||||
// Queue texture upload (image already converted to RGBA8888)
|
|
||||||
PendingTextureUpload upload;
|
|
||||||
upload.index = idx;
|
|
||||||
upload.image = img;
|
|
||||||
upload.x = x;
|
|
||||||
upload.y = 1 * (float(img.height()) / img.width());
|
|
||||||
pendingTextureUploads.append(upload);
|
|
||||||
|
|
||||||
QString s = "cover";
|
|
||||||
replace(s.toLocal8Bit().data(), texture, upload.x, upload.y, idx);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int count = 8;
|
|
||||||
switch (performance) {
|
|
||||||
case low:
|
|
||||||
count = 8;
|
|
||||||
break;
|
|
||||||
case medium:
|
|
||||||
count = 10;
|
|
||||||
break;
|
|
||||||
case high:
|
|
||||||
count = 12;
|
|
||||||
break;
|
|
||||||
case ultraHigh:
|
|
||||||
count = 16;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
int *indexes = new int[2 * count + 1];
|
|
||||||
int center = currentSelected;
|
|
||||||
indexes[0] = center;
|
|
||||||
for (int j = 0; j < count; j++) {
|
|
||||||
indexes[j * 2 + 1] = center + j + 1;
|
|
||||||
indexes[j * 2 + 2] = center - j - 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int c = 0; c < 2 * count + 1; c++) {
|
|
||||||
int i = indexes[c];
|
|
||||||
if ((i >= 0) && (i < numObjects))
|
|
||||||
if (!loaded[i]) {
|
|
||||||
if (paths.size() > 0) {
|
|
||||||
QString fname = paths.at(i);
|
|
||||||
worker->generate(i, fname);
|
|
||||||
}
|
|
||||||
delete[] indexes;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
delete[] indexes;
|
|
||||||
}
|
|
||||||
|
|
||||||
void YACReaderComicFlow3D::remove(int item)
|
|
||||||
{
|
|
||||||
worker->lock();
|
|
||||||
worker->reset();
|
|
||||||
YACReaderFlow3D::remove(item);
|
|
||||||
if (item >= 0 && item < paths.size()) {
|
|
||||||
paths.removeAt(item);
|
|
||||||
}
|
|
||||||
worker->unlock();
|
|
||||||
}
|
|
||||||
|
|
||||||
void YACReaderComicFlow3D::add(const QString &path, int index)
|
|
||||||
{
|
|
||||||
worker->lock();
|
|
||||||
worker->reset();
|
|
||||||
paths.insert(index, path);
|
|
||||||
YACReaderFlow3D::add(index);
|
|
||||||
worker->unlock();
|
|
||||||
}
|
|
||||||
|
|
||||||
void YACReaderComicFlow3D::resortCovers(QList<int> newOrder)
|
|
||||||
{
|
|
||||||
worker->lock();
|
|
||||||
worker->reset();
|
|
||||||
startAnimationTimer();
|
|
||||||
|
|
||||||
QList<QString> pathsNew;
|
|
||||||
QVector<bool> loadedNew;
|
|
||||||
QVector<YACReaderComicReadStatus> marksNew;
|
|
||||||
QVector<YACReader3DImageRHI> imagesNew;
|
|
||||||
|
|
||||||
int index = 0;
|
|
||||||
foreach (int i, newOrder) {
|
|
||||||
if (i < 0 || i >= images.size()) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
pathsNew << paths.at(i);
|
|
||||||
loadedNew << loaded.at(i);
|
|
||||||
marksNew << marks.at(i);
|
|
||||||
imagesNew << images.at(i);
|
|
||||||
imagesNew.last().index = index++;
|
|
||||||
}
|
|
||||||
|
|
||||||
paths = pathsNew;
|
|
||||||
loaded = loadedNew;
|
|
||||||
marks = marksNew;
|
|
||||||
images = imagesNew;
|
|
||||||
|
|
||||||
worker->unlock();
|
|
||||||
}
|
|
||||||
|
|
||||||
// YACReaderPageFlow3D implementation
|
|
||||||
YACReaderPageFlow3D::YACReaderPageFlow3D(QWidget *parent, struct Preset p)
|
|
||||||
: YACReaderFlow3D(parent, p)
|
|
||||||
{
|
|
||||||
worker = new ImageLoaderByteArray3D(this);
|
|
||||||
worker->flow = this;
|
|
||||||
}
|
|
||||||
|
|
||||||
YACReaderPageFlow3D::~YACReaderPageFlow3D()
|
|
||||||
{
|
|
||||||
if (timerId != -1) {
|
|
||||||
this->killTimer(timerId);
|
|
||||||
timerId = -1;
|
|
||||||
}
|
|
||||||
rawImages.clear();
|
|
||||||
|
|
||||||
// Clean up textures and clear images to prevent double-delete in base destructor
|
|
||||||
for (auto &image : images) {
|
|
||||||
if (image.texture != scene.defaultTexture.get()) {
|
|
||||||
delete image.texture;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
images.clear();
|
|
||||||
numObjects = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void YACReaderPageFlow3D::updateImageData()
|
|
||||||
{
|
|
||||||
if (worker->busy())
|
|
||||||
return;
|
|
||||||
|
|
||||||
int idx = worker->index();
|
|
||||||
if (idx >= 0 && !worker->result().isNull()) {
|
|
||||||
if (!loaded[idx]) {
|
|
||||||
float x = 1;
|
|
||||||
QImage img = worker->result();
|
|
||||||
|
|
||||||
// Create QRhiTexture from the loaded image
|
|
||||||
if (m_rhi) {
|
|
||||||
QRhiTexture *texture = m_rhi->newTexture(QRhiTexture::BGRA8, img.size(), 1,
|
|
||||||
(performance == high || performance == ultraHigh) ? QRhiTexture::MipMapped : QRhiTexture::UsedAsTransferSource);
|
|
||||||
|
|
||||||
if (texture->create()) {
|
|
||||||
float y = 1 * (float(img.height()) / img.width());
|
|
||||||
QString s = "cover";
|
|
||||||
replace(s.toLocal8Bit().data(), texture, x, y, idx);
|
|
||||||
loaded[idx] = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int count = 8;
|
|
||||||
switch (performance) {
|
|
||||||
case low:
|
|
||||||
count = 8;
|
|
||||||
break;
|
|
||||||
case medium:
|
|
||||||
count = 10;
|
|
||||||
break;
|
|
||||||
case high:
|
|
||||||
count = 12;
|
|
||||||
break;
|
|
||||||
case ultraHigh:
|
|
||||||
count = 14;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
int *indexes = new int[2 * count + 1];
|
|
||||||
int center = currentSelected;
|
|
||||||
indexes[0] = center;
|
|
||||||
for (int j = 0; j < count; j++) {
|
|
||||||
indexes[j * 2 + 1] = center + j + 1;
|
|
||||||
indexes[j * 2 + 2] = center - j - 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int c = 0; c < 2 * count + 1; c++) {
|
|
||||||
int i = indexes[c];
|
|
||||||
if ((i >= 0) && (i < numObjects))
|
|
||||||
if (rawImages.size() > 0)
|
|
||||||
if (!loaded[i] && imagesReady[i]) {
|
|
||||||
worker->generate(i, rawImages.at(i));
|
|
||||||
delete[] indexes;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
delete[] indexes;
|
|
||||||
}
|
|
||||||
|
|
||||||
void YACReaderPageFlow3D::populate(int n)
|
|
||||||
{
|
|
||||||
worker->reset();
|
|
||||||
|
|
||||||
if (hasBeenInitialized) {
|
|
||||||
YACReaderFlow3D::populate(n);
|
|
||||||
} else {
|
|
||||||
lazyPopulateObjects = n;
|
|
||||||
}
|
|
||||||
|
|
||||||
imagesReady = QVector<bool>(n, false);
|
|
||||||
rawImages = QVector<QByteArray>(n);
|
|
||||||
imagesSetted = QVector<bool>(n, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ImageLoader3D implementation
|
|
||||||
QImage ImageLoader3D::loadImage(const QString &fileName)
|
|
||||||
{
|
|
||||||
QImage image;
|
|
||||||
|
|
||||||
if (!image.load(fileName)) {
|
|
||||||
return QImage();
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (flow->performance) {
|
|
||||||
case low:
|
|
||||||
image = image.scaledToWidth(200, Qt::SmoothTransformation);
|
|
||||||
break;
|
|
||||||
case medium:
|
|
||||||
image = image.scaledToWidth(256, Qt::SmoothTransformation);
|
|
||||||
break;
|
|
||||||
case high:
|
|
||||||
image = image.scaledToWidth(320, Qt::SmoothTransformation);
|
|
||||||
break;
|
|
||||||
case ultraHigh:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return image;
|
|
||||||
}
|
|
||||||
|
|
||||||
ImageLoader3D::ImageLoader3D(YACReaderFlow3D *flow)
|
|
||||||
: QThread(), flow(flow), restart(false), working(false), idx(-1)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
ImageLoader3D::~ImageLoader3D()
|
|
||||||
{
|
|
||||||
mutex.lock();
|
|
||||||
condition.wakeOne();
|
|
||||||
mutex.unlock();
|
|
||||||
wait();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ImageLoader3D::busy() const
|
|
||||||
{
|
|
||||||
return isRunning() ? working : false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ImageLoader3D::generate(int index, const QString &fileName)
|
|
||||||
{
|
|
||||||
mutex.lock();
|
|
||||||
this->idx = index;
|
|
||||||
this->fileName = fileName;
|
|
||||||
this->size = size;
|
|
||||||
this->img = QImage();
|
|
||||||
mutex.unlock();
|
|
||||||
|
|
||||||
if (!isRunning())
|
|
||||||
start();
|
|
||||||
else {
|
|
||||||
restart = true;
|
|
||||||
condition.wakeOne();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ImageLoader3D::lock()
|
|
||||||
{
|
|
||||||
mutex.lock();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ImageLoader3D::unlock()
|
|
||||||
{
|
|
||||||
mutex.unlock();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ImageLoader3D::run()
|
|
||||||
{
|
|
||||||
for (;;) {
|
|
||||||
mutex.lock();
|
|
||||||
this->working = true;
|
|
||||||
QString fileName = this->fileName;
|
|
||||||
mutex.unlock();
|
|
||||||
|
|
||||||
QImage image = loadImage(fileName);
|
|
||||||
|
|
||||||
mutex.lock();
|
|
||||||
this->working = false;
|
|
||||||
this->img = image;
|
|
||||||
mutex.unlock();
|
|
||||||
|
|
||||||
mutex.lock();
|
|
||||||
if (!this->restart)
|
|
||||||
condition.wait(&mutex);
|
|
||||||
restart = false;
|
|
||||||
mutex.unlock();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QImage ImageLoader3D::result()
|
|
||||||
{
|
|
||||||
return img;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ImageLoaderByteArray3D implementation
|
|
||||||
QImage ImageLoaderByteArray3D::loadImage(const QByteArray &raw)
|
|
||||||
{
|
|
||||||
QImage image;
|
|
||||||
|
|
||||||
if (!image.loadFromData(raw)) {
|
|
||||||
return QImage();
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (flow->performance) {
|
|
||||||
case low:
|
|
||||||
image = image.scaledToWidth(128, Qt::SmoothTransformation);
|
|
||||||
break;
|
|
||||||
case medium:
|
|
||||||
image = image.scaledToWidth(196, Qt::SmoothTransformation);
|
|
||||||
break;
|
|
||||||
case high:
|
|
||||||
image = image.scaledToWidth(256, Qt::SmoothTransformation);
|
|
||||||
break;
|
|
||||||
case ultraHigh:
|
|
||||||
image = image.scaledToWidth(320, Qt::SmoothTransformation);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return image;
|
|
||||||
}
|
|
||||||
|
|
||||||
ImageLoaderByteArray3D::ImageLoaderByteArray3D(YACReaderFlow3D *flow)
|
|
||||||
: QThread(), flow(flow), restart(false), working(false), idx(-1)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
ImageLoaderByteArray3D::~ImageLoaderByteArray3D()
|
|
||||||
{
|
|
||||||
mutex.lock();
|
|
||||||
condition.wakeOne();
|
|
||||||
mutex.unlock();
|
|
||||||
wait();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ImageLoaderByteArray3D::busy() const
|
|
||||||
{
|
|
||||||
return isRunning() ? working : false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ImageLoaderByteArray3D::generate(int index, const QByteArray &raw)
|
|
||||||
{
|
|
||||||
mutex.lock();
|
|
||||||
this->idx = index;
|
|
||||||
this->rawData = raw;
|
|
||||||
this->size = size;
|
|
||||||
this->img = QImage();
|
|
||||||
mutex.unlock();
|
|
||||||
|
|
||||||
if (!isRunning())
|
|
||||||
start();
|
|
||||||
else {
|
|
||||||
restart = true;
|
|
||||||
condition.wakeOne();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ImageLoaderByteArray3D::run()
|
|
||||||
{
|
|
||||||
for (;;) {
|
|
||||||
mutex.lock();
|
|
||||||
this->working = true;
|
|
||||||
QByteArray raw = this->rawData;
|
|
||||||
mutex.unlock();
|
|
||||||
|
|
||||||
QImage image = loadImage(raw);
|
|
||||||
|
|
||||||
mutex.lock();
|
|
||||||
this->working = false;
|
|
||||||
this->img = image;
|
|
||||||
mutex.unlock();
|
|
||||||
|
|
||||||
mutex.lock();
|
|
||||||
if (!this->restart)
|
|
||||||
condition.wait(&mutex);
|
|
||||||
restart = false;
|
|
||||||
mutex.unlock();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QImage ImageLoaderByteArray3D::result()
|
|
||||||
{
|
|
||||||
return img;
|
|
||||||
}
|
|
||||||
|
|||||||
@ -81,6 +81,8 @@ extern struct Preset pressetYACReaderFlowDownConfig;
|
|||||||
|
|
||||||
class ImageLoader3D;
|
class ImageLoader3D;
|
||||||
class ImageLoaderByteArray3D;
|
class ImageLoaderByteArray3D;
|
||||||
|
class YACReaderComicFlow3D;
|
||||||
|
class YACReaderPageFlow3D;
|
||||||
|
|
||||||
class YACReaderFlow3D : public QRhiWidget, public ScrollManagement
|
class YACReaderFlow3D : public QRhiWidget, public ScrollManagement
|
||||||
{
|
{
|
||||||
@ -312,105 +314,10 @@ signals:
|
|||||||
void selected(unsigned int);
|
void selected(unsigned int);
|
||||||
};
|
};
|
||||||
|
|
||||||
class YACReaderComicFlow3D : public YACReaderFlow3D
|
/* Derived flow & loader classes moved to dedicated files:
|
||||||
{
|
- common/rhi/yacreader_comic_flow_rhi.h/.cpp
|
||||||
public:
|
- common/rhi/yacreader_page_flow_rhi.h/.cpp
|
||||||
YACReaderComicFlow3D(QWidget *parent = nullptr, struct Preset p = defaultYACReaderFlowConfig);
|
*/
|
||||||
void setImagePaths(QStringList paths);
|
|
||||||
void updateImageData() override;
|
|
||||||
void remove(int item) override;
|
|
||||||
void add(const QString &path, int index);
|
|
||||||
void resortCovers(QList<int> newOrder);
|
|
||||||
friend class ImageLoader3D;
|
|
||||||
|
|
||||||
private:
|
|
||||||
ImageLoader3D *worker;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
QList<QString> paths;
|
|
||||||
};
|
|
||||||
|
|
||||||
class YACReaderPageFlow3D : public YACReaderFlow3D
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
YACReaderPageFlow3D(QWidget *parent = nullptr, struct Preset p = defaultYACReaderFlowConfig);
|
|
||||||
~YACReaderPageFlow3D();
|
|
||||||
void updateImageData() override;
|
|
||||||
void populate(int n);
|
|
||||||
QVector<bool> imagesReady;
|
|
||||||
QVector<QByteArray> rawImages;
|
|
||||||
QVector<bool> imagesSetted;
|
|
||||||
friend class ImageLoaderByteArray3D;
|
|
||||||
|
|
||||||
private:
|
|
||||||
ImageLoaderByteArray3D *worker;
|
|
||||||
};
|
|
||||||
|
|
||||||
class ImageLoader3D : public QThread
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
ImageLoader3D(YACReaderFlow3D *flow);
|
|
||||||
~ImageLoader3D();
|
|
||||||
bool busy() const;
|
|
||||||
void generate(int index, const QString &fileName);
|
|
||||||
void reset()
|
|
||||||
{
|
|
||||||
idx = -1;
|
|
||||||
fileName = "";
|
|
||||||
}
|
|
||||||
int index() const { return idx; }
|
|
||||||
void lock();
|
|
||||||
void unlock();
|
|
||||||
QImage result();
|
|
||||||
YACReaderFlow3D *flow;
|
|
||||||
QImage loadImage(const QString &fileName);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void run() override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
QMutex mutex;
|
|
||||||
QWaitCondition condition;
|
|
||||||
|
|
||||||
bool restart;
|
|
||||||
bool working;
|
|
||||||
int idx;
|
|
||||||
QString fileName;
|
|
||||||
QSize size;
|
|
||||||
QImage img;
|
|
||||||
};
|
|
||||||
|
|
||||||
class ImageLoaderByteArray3D : public QThread
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
ImageLoaderByteArray3D(YACReaderFlow3D *flow);
|
|
||||||
~ImageLoaderByteArray3D();
|
|
||||||
bool busy() const;
|
|
||||||
void generate(int index, const QByteArray &raw);
|
|
||||||
void reset()
|
|
||||||
{
|
|
||||||
idx = -1;
|
|
||||||
rawData.clear();
|
|
||||||
}
|
|
||||||
int index() const { return idx; }
|
|
||||||
QImage result();
|
|
||||||
YACReaderFlow3D *flow;
|
|
||||||
QImage loadImage(const QByteArray &rawData);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void run() override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
QMutex mutex;
|
|
||||||
QWaitCondition condition;
|
|
||||||
|
|
||||||
bool restart;
|
|
||||||
bool working;
|
|
||||||
int idx;
|
|
||||||
QByteArray rawData;
|
|
||||||
QSize size;
|
|
||||||
QImage img;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // QT_VERSION >= QT_VERSION_CHECK(6, 7, 0)
|
#endif // QT_VERSION >= QT_VERSION_CHECK(6, 7, 0)
|
||||||
|
|
||||||
|
|||||||
204
common/rhi/yacreader_page_flow_rhi.cpp
Normal file
204
common/rhi/yacreader_page_flow_rhi.cpp
Normal file
@ -0,0 +1,204 @@
|
|||||||
|
#include "yacreader_page_flow_rhi.h"
|
||||||
|
#include <QImage>
|
||||||
|
|
||||||
|
// YACReaderPageFlow3D implementation
|
||||||
|
YACReaderPageFlow3D::YACReaderPageFlow3D(QWidget *parent, struct Preset p)
|
||||||
|
: YACReaderFlow3D(parent, p)
|
||||||
|
{
|
||||||
|
worker = new ImageLoaderByteArray3D(this);
|
||||||
|
worker->flow = this;
|
||||||
|
}
|
||||||
|
|
||||||
|
YACReaderPageFlow3D::~YACReaderPageFlow3D()
|
||||||
|
{
|
||||||
|
if (timerId != -1) {
|
||||||
|
this->killTimer(timerId);
|
||||||
|
timerId = -1;
|
||||||
|
}
|
||||||
|
rawImages.clear();
|
||||||
|
|
||||||
|
// Clean up textures and clear images to prevent double-delete in base destructor
|
||||||
|
for (auto &image : images) {
|
||||||
|
if (image.texture != scene.defaultTexture.get()) {
|
||||||
|
delete image.texture;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
images.clear();
|
||||||
|
numObjects = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void YACReaderPageFlow3D::updateImageData()
|
||||||
|
{
|
||||||
|
if (worker->busy())
|
||||||
|
return;
|
||||||
|
|
||||||
|
int idx = worker->index();
|
||||||
|
if (idx >= 0 && !worker->result().isNull()) {
|
||||||
|
if (!loaded[idx]) {
|
||||||
|
float x = 1;
|
||||||
|
QImage img = worker->result();
|
||||||
|
|
||||||
|
// Create QRhiTexture from the loaded image and queue the pixel upload
|
||||||
|
if (m_rhi) {
|
||||||
|
QRhiTexture *texture = m_rhi->newTexture(QRhiTexture::BGRA8, img.size(), 1,
|
||||||
|
(performance == high || performance == ultraHigh) ? QRhiTexture::MipMapped : QRhiTexture::UsedAsTransferSource);
|
||||||
|
|
||||||
|
if (texture->create()) {
|
||||||
|
// Queue the image upload so it happens together with other resource updates
|
||||||
|
PendingTextureUpload upload;
|
||||||
|
upload.index = idx;
|
||||||
|
upload.image = img;
|
||||||
|
upload.x = x;
|
||||||
|
upload.y = 1 * (float(img.height()) / img.width());
|
||||||
|
pendingTextureUploads.append(upload);
|
||||||
|
|
||||||
|
QString s = "cover";
|
||||||
|
replace(s.toLocal8Bit().data(), texture, upload.x, upload.y, idx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int count = 8;
|
||||||
|
switch (performance) {
|
||||||
|
case low:
|
||||||
|
count = 8;
|
||||||
|
break;
|
||||||
|
case medium:
|
||||||
|
count = 10;
|
||||||
|
break;
|
||||||
|
case high:
|
||||||
|
count = 12;
|
||||||
|
break;
|
||||||
|
case ultraHigh:
|
||||||
|
count = 14;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
int *indexes = new int[2 * count + 1];
|
||||||
|
int center = currentSelected;
|
||||||
|
indexes[0] = center;
|
||||||
|
for (int j = 0; j < count; j++) {
|
||||||
|
indexes[j * 2 + 1] = center + j + 1;
|
||||||
|
indexes[j * 2 + 2] = center - j - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int c = 0; c < 2 * count + 1; c++) {
|
||||||
|
int i = indexes[c];
|
||||||
|
if ((i >= 0) && (i < numObjects))
|
||||||
|
if (rawImages.size() > 0)
|
||||||
|
if (!loaded[i] && imagesReady[i]) {
|
||||||
|
worker->generate(i, rawImages.at(i));
|
||||||
|
delete[] indexes;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
delete[] indexes;
|
||||||
|
}
|
||||||
|
|
||||||
|
void YACReaderPageFlow3D::populate(int n)
|
||||||
|
{
|
||||||
|
worker->reset();
|
||||||
|
reset();
|
||||||
|
numObjects = 0;
|
||||||
|
|
||||||
|
if (hasBeenInitialized) {
|
||||||
|
YACReaderFlow3D::populate(n);
|
||||||
|
} else {
|
||||||
|
lazyPopulateObjects = n;
|
||||||
|
}
|
||||||
|
|
||||||
|
imagesReady = QVector<bool>(n, false);
|
||||||
|
rawImages = QVector<QByteArray>(n);
|
||||||
|
imagesSetted = QVector<bool>(n, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ImageLoaderByteArray3D implementation
|
||||||
|
QImage ImageLoaderByteArray3D::loadImage(const QByteArray &raw)
|
||||||
|
{
|
||||||
|
QImage image;
|
||||||
|
|
||||||
|
if (!image.loadFromData(raw)) {
|
||||||
|
return QImage();
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (flow->performance) {
|
||||||
|
case low:
|
||||||
|
image = image.scaledToWidth(128, Qt::SmoothTransformation);
|
||||||
|
break;
|
||||||
|
case medium:
|
||||||
|
image = image.scaledToWidth(196, Qt::SmoothTransformation);
|
||||||
|
break;
|
||||||
|
case high:
|
||||||
|
image = image.scaledToWidth(256, Qt::SmoothTransformation);
|
||||||
|
break;
|
||||||
|
case ultraHigh:
|
||||||
|
image = image.scaledToWidth(320, Qt::SmoothTransformation);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return image;
|
||||||
|
}
|
||||||
|
|
||||||
|
ImageLoaderByteArray3D::ImageLoaderByteArray3D(YACReaderFlow3D *flow)
|
||||||
|
: QThread(), flow(flow), restart(false), working(false), idx(-1)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
ImageLoaderByteArray3D::~ImageLoaderByteArray3D()
|
||||||
|
{
|
||||||
|
mutex.lock();
|
||||||
|
condition.wakeOne();
|
||||||
|
mutex.unlock();
|
||||||
|
wait();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ImageLoaderByteArray3D::busy() const
|
||||||
|
{
|
||||||
|
return isRunning() ? working : false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImageLoaderByteArray3D::generate(int index, const QByteArray &raw)
|
||||||
|
{
|
||||||
|
mutex.lock();
|
||||||
|
this->idx = index;
|
||||||
|
this->rawData = raw;
|
||||||
|
this->img = QImage();
|
||||||
|
mutex.unlock();
|
||||||
|
|
||||||
|
if (!isRunning())
|
||||||
|
start();
|
||||||
|
else {
|
||||||
|
restart = true;
|
||||||
|
condition.wakeOne();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImageLoaderByteArray3D::run()
|
||||||
|
{
|
||||||
|
for (;;) {
|
||||||
|
mutex.lock();
|
||||||
|
this->working = true;
|
||||||
|
QByteArray raw = this->rawData;
|
||||||
|
mutex.unlock();
|
||||||
|
|
||||||
|
QImage image = loadImage(raw);
|
||||||
|
|
||||||
|
mutex.lock();
|
||||||
|
this->working = false;
|
||||||
|
this->img = image;
|
||||||
|
mutex.unlock();
|
||||||
|
|
||||||
|
mutex.lock();
|
||||||
|
if (!this->restart)
|
||||||
|
condition.wait(&mutex);
|
||||||
|
restart = false;
|
||||||
|
mutex.unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QImage ImageLoaderByteArray3D::result()
|
||||||
|
{
|
||||||
|
return img;
|
||||||
|
}
|
||||||
55
common/rhi/yacreader_page_flow_rhi.h
Normal file
55
common/rhi/yacreader_page_flow_rhi.h
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
#ifndef __YACREADER_PAGE_FLOW_RHI_H
|
||||||
|
#define __YACREADER_PAGE_FLOW_RHI_H
|
||||||
|
|
||||||
|
#include "yacreader_flow_rhi.h"
|
||||||
|
|
||||||
|
class ImageLoaderByteArray3D;
|
||||||
|
|
||||||
|
class YACReaderPageFlow3D : public YACReaderFlow3D
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
YACReaderPageFlow3D(QWidget *parent = nullptr, struct Preset p = defaultYACReaderFlowConfig);
|
||||||
|
~YACReaderPageFlow3D();
|
||||||
|
void updateImageData() override;
|
||||||
|
void populate(int n);
|
||||||
|
QVector<bool> imagesReady;
|
||||||
|
QVector<QByteArray> rawImages;
|
||||||
|
QVector<bool> imagesSetted;
|
||||||
|
friend class ImageLoaderByteArray3D;
|
||||||
|
|
||||||
|
private:
|
||||||
|
ImageLoaderByteArray3D *worker;
|
||||||
|
};
|
||||||
|
|
||||||
|
class ImageLoaderByteArray3D : public QThread
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ImageLoaderByteArray3D(YACReaderFlow3D *flow);
|
||||||
|
~ImageLoaderByteArray3D();
|
||||||
|
bool busy() const;
|
||||||
|
void generate(int index, const QByteArray &raw);
|
||||||
|
void reset()
|
||||||
|
{
|
||||||
|
idx = -1;
|
||||||
|
rawData.clear();
|
||||||
|
}
|
||||||
|
int index() const { return idx; }
|
||||||
|
QImage result();
|
||||||
|
YACReaderFlow3D *flow;
|
||||||
|
QImage loadImage(const QByteArray &rawData);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void run() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QMutex mutex;
|
||||||
|
QWaitCondition condition;
|
||||||
|
|
||||||
|
bool restart;
|
||||||
|
bool working;
|
||||||
|
int idx;
|
||||||
|
QByteArray rawData;
|
||||||
|
QImage img;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // __YACREADER_PAGE_FLOW_RHI_H
|
||||||
Reference in New Issue
Block a user