mirror of
https://github.com/libretro/RetroArch
synced 2025-03-29 22:20:21 +00:00
Qt: remove mutex, defer loading of grid items into layout, use guarded pointers for exec() operations, misc cleanup
This commit is contained in:
parent
de71a4dee7
commit
2a784ae1bc
@ -336,7 +336,8 @@ OBJ += ui/drivers/ui_qt.o \
|
||||
ui/drivers/qt/flowlayout.o
|
||||
|
||||
MOC_HEADERS += ui/drivers/ui_qt.h \
|
||||
ui/drivers/qt/ui_qt_load_core_window.h
|
||||
ui/drivers/qt/ui_qt_load_core_window.h \
|
||||
ui/drivers/qt/flowlayout.h
|
||||
|
||||
DEFINES += $(QT5CORE_CFLAGS) $(QT5GUI_CFLAGS) $(QT5WIDGETS_CFLAGS) $(QT5CONCURRENT_CFLAGS) -DHAVE_MAIN
|
||||
#DEFINES += $(QT5WEBENGINE_CFLAGS)
|
||||
|
@ -60,6 +60,8 @@ FlowLayout::FlowLayout(QWidget *parent, int margin, int hSpacing, int vSpacing)
|
||||
: QLayout(parent), m_hSpace(hSpacing), m_vSpace(vSpacing)
|
||||
{
|
||||
setContentsMargins(margin, margin, margin, margin);
|
||||
|
||||
connect(this, SIGNAL(signalAddWidgetDeferred(QWidget*)), this, SLOT(onAddWidgetDeferred(QWidget*)), Qt::QueuedConnection);
|
||||
}
|
||||
|
||||
FlowLayout::FlowLayout(int margin, int hSpacing, int vSpacing)
|
||||
@ -70,9 +72,9 @@ FlowLayout::FlowLayout(int margin, int hSpacing, int vSpacing)
|
||||
|
||||
FlowLayout::~FlowLayout()
|
||||
{
|
||||
QLayoutItem *item;
|
||||
QLayoutItem *item = NULL;
|
||||
|
||||
while ((item = takeAt(0)))
|
||||
while ((item = takeAt(0)) != NULL)
|
||||
delete item;
|
||||
}
|
||||
|
||||
@ -229,3 +231,13 @@ int FlowLayout::smartSpacing(QStyle::PixelMetric pm) const
|
||||
else
|
||||
return static_cast<const QLayout*>(parentObj)->spacing();
|
||||
}
|
||||
|
||||
void FlowLayout::addWidgetDeferred(QWidget *widget)
|
||||
{
|
||||
emit signalAddWidgetDeferred(widget);
|
||||
}
|
||||
|
||||
void FlowLayout::onAddWidgetDeferred(QWidget *widget)
|
||||
{
|
||||
addWidget(widget);
|
||||
}
|
||||
|
@ -65,6 +65,7 @@
|
||||
|
||||
class FlowLayout : public QLayout
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit FlowLayout(QWidget *parent, int margin = -1, int hSpacing = -1, int vSpacing = -1);
|
||||
explicit FlowLayout(int margin = -1, int hSpacing = -1, int vSpacing = -1);
|
||||
@ -82,6 +83,13 @@ public:
|
||||
void setGeometry(const QRect &rect);
|
||||
QSize sizeHint() const;
|
||||
QLayoutItem* takeAt(int index);
|
||||
void addWidgetDeferred(QWidget *widget);
|
||||
|
||||
signals:
|
||||
void signalAddWidgetDeferred(QWidget *widget);
|
||||
|
||||
private slots:
|
||||
void onAddWidgetDeferred(QWidget *widget);
|
||||
|
||||
private:
|
||||
int doLayout(const QRect &rect, bool testOnly) const;
|
||||
|
@ -111,6 +111,10 @@ static void scan_finished_handler(void *task_data, void *user_data, const char *
|
||||
menu_environ.type = MENU_ENVIRON_RESET_HORIZONTAL_LIST;
|
||||
menu_environ.data = NULL;
|
||||
|
||||
(void)task_data;
|
||||
(void)user_data;
|
||||
(void)err;
|
||||
|
||||
menu_driver_ctl(RARCH_MENU_CTL_ENVIRONMENT, &menu_environ);
|
||||
|
||||
if (!ui_window.qtWindow->settings()->value("scan_finish_confirm", true).toBool())
|
||||
@ -128,7 +132,6 @@ GridItem::GridItem() :
|
||||
,image()
|
||||
,pixmap()
|
||||
,imageWatcher()
|
||||
,mutex()
|
||||
{
|
||||
}
|
||||
|
||||
@ -740,7 +743,6 @@ MainWindow::~MainWindow()
|
||||
|
||||
inline void MainWindow::calcGridItemSize(GridItem *item, int zoomValue)
|
||||
{
|
||||
QMutexLocker lock(&item->mutex);
|
||||
int newSize = 0;
|
||||
|
||||
if (zoomValue < 50)
|
||||
@ -850,12 +852,12 @@ void MainWindow::setCustomThemeString(QString qss)
|
||||
|
||||
bool MainWindow::showMessageBox(QString msg, MessageBoxType msgType, Qt::WindowModality modality)
|
||||
{
|
||||
QScopedPointer<QMessageBox> msgBoxPtr;
|
||||
QPointer<QScopedPointer<QMessageBox> > msgBoxPtr;
|
||||
QMessageBox *msgBox = NULL;
|
||||
QCheckBox *checkBox = NULL;
|
||||
|
||||
msgBoxPtr.reset(new QMessageBox(this));
|
||||
msgBox = msgBoxPtr.data();
|
||||
msgBoxPtr.data()->reset(new QMessageBox(this));
|
||||
msgBox = msgBoxPtr.data()->data();
|
||||
checkBox = new QCheckBox(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_DONT_SHOW_AGAIN), msgBox);
|
||||
|
||||
msgBox->setWindowModality(modality);
|
||||
@ -891,6 +893,9 @@ bool MainWindow::showMessageBox(QString msg, MessageBoxType msgType, Qt::WindowM
|
||||
msgBox->setText(msg);
|
||||
msgBox->exec();
|
||||
|
||||
if (!msgBoxPtr)
|
||||
return true;
|
||||
|
||||
if (checkBox->isChecked())
|
||||
return false;
|
||||
|
||||
@ -904,7 +909,7 @@ void MainWindow::onPlaylistWidgetContextMenuRequested(const QPoint&)
|
||||
QScopedPointer<QMenu> associateMenu;
|
||||
QScopedPointer<QMenu> hiddenPlaylistsMenu;
|
||||
QScopedPointer<QAction> hideAction;
|
||||
QAction *selectedAction = NULL;
|
||||
QPointer<QAction> selectedAction;
|
||||
QPoint cursorPos = QCursor::pos();
|
||||
QListWidgetItem *selectedItem = m_listWidget->itemAt(m_listWidget->viewport()->mapFromGlobal(cursorPos));
|
||||
QDir playlistDir(settings->paths.directory_playlist);
|
||||
@ -1103,7 +1108,7 @@ end:
|
||||
void MainWindow::onFileBrowserTreeContextMenuRequested(const QPoint&)
|
||||
{
|
||||
#ifdef HAVE_LIBRETRODB
|
||||
QAction *action = NULL;
|
||||
QPointer<QAction> action;
|
||||
QList<QAction*> actions;
|
||||
QScopedPointer<QAction> scanAction;
|
||||
QDir dir;
|
||||
@ -1153,6 +1158,8 @@ void MainWindow::onGotStatusMessage(QString msg, unsigned priority, unsigned dur
|
||||
QScreen *screen = qApp->primaryScreen();
|
||||
QStatusBar *status = statusBar();
|
||||
|
||||
Q_UNUSED(priority)
|
||||
|
||||
if (msg.isEmpty())
|
||||
return;
|
||||
|
||||
@ -2831,23 +2838,21 @@ void MainWindow::removeGridItems()
|
||||
{
|
||||
QMutableListIterator<GridItem*> items(m_gridItems);
|
||||
|
||||
m_pendingItemUpdates.clear();
|
||||
|
||||
while (items.hasNext())
|
||||
{
|
||||
GridItem *item = items.next();
|
||||
|
||||
if (item)
|
||||
{
|
||||
item->mutex.lock();
|
||||
item->imageWatcher.waitForFinished();
|
||||
|
||||
items.remove();
|
||||
|
||||
m_gridLayout->removeWidget(item->widget);
|
||||
m_pendingItemUpdates.removeAll(item);
|
||||
|
||||
delete item->widget;
|
||||
|
||||
item->mutex.unlock();
|
||||
|
||||
delete item;
|
||||
}
|
||||
}
|
||||
@ -2867,15 +2872,14 @@ void MainWindow::onDeferredImageLoaded()
|
||||
if (!item)
|
||||
return;
|
||||
|
||||
item->mutex.lock();
|
||||
|
||||
if (!item->image.isNull())
|
||||
if (m_gridItems.contains(item))
|
||||
{
|
||||
m_pendingItemUpdates.append(item);
|
||||
QTimer::singleShot(0, this, SLOT(onPendingItemUpdates()));
|
||||
if (!item->image.isNull())
|
||||
{
|
||||
m_pendingItemUpdates.append(item);
|
||||
QTimer::singleShot(0, this, SLOT(onPendingItemUpdates()));
|
||||
}
|
||||
}
|
||||
|
||||
item->mutex.unlock();
|
||||
}
|
||||
|
||||
void MainWindow::onPendingItemUpdates()
|
||||
@ -2889,7 +2893,8 @@ void MainWindow::onPendingItemUpdates()
|
||||
if (!item)
|
||||
continue;
|
||||
|
||||
onUpdateGridItemPixmapFromImage(item);
|
||||
if (m_gridItems.contains(item))
|
||||
onUpdateGridItemPixmapFromImage(item);
|
||||
|
||||
list.remove();
|
||||
}
|
||||
@ -2900,6 +2905,9 @@ void MainWindow::onUpdateGridItemPixmapFromImage(GridItem *item)
|
||||
if (!item)
|
||||
return;
|
||||
|
||||
if (!m_gridItems.contains(item))
|
||||
return;
|
||||
|
||||
item->label->setPixmap(QPixmap::fromImage(item->image));
|
||||
item->label->update();
|
||||
}
|
||||
@ -2916,12 +2924,11 @@ GridItem* MainWindow::doDeferredImageLoad(GridItem *item, QString path)
|
||||
if (!item)
|
||||
return NULL;
|
||||
|
||||
item->mutex.lock();
|
||||
|
||||
/* While we are indeed writing across thread boundaries here, the image is never accessed until after
|
||||
* its thread finishes, and the item is never deleted without first waiting for the thread to finish.
|
||||
*/
|
||||
item->image = QImage(path);
|
||||
|
||||
item->mutex.unlock();
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
@ -2992,12 +2999,10 @@ void MainWindow::addPlaylistItemsToGrid(const QString &pathString)
|
||||
item->widget->layout()->addWidget(newLabel);
|
||||
qobject_cast<QVBoxLayout*>(item->widget->layout())->setStretchFactor(label, 1);
|
||||
|
||||
m_gridLayout->addWidget(item->widget);
|
||||
m_gridLayout->addWidgetDeferred(item->widget);
|
||||
m_gridItems.append(item);
|
||||
|
||||
loadImageDeferred(item, imagePath);
|
||||
|
||||
qApp->processEvents();
|
||||
}
|
||||
}
|
||||
|
||||
@ -3178,12 +3183,6 @@ void MainWindow::addPlaylistItemsToTable(QString pathString)
|
||||
|
||||
for (i = 0; i < items.count(); i++)
|
||||
{
|
||||
const char *path = NULL;
|
||||
const char *label = NULL;
|
||||
const char *core_path = NULL;
|
||||
const char *core_name = NULL;
|
||||
const char *crc32 = NULL;
|
||||
const char *db_name = NULL;
|
||||
QTableWidgetItem *labelItem = NULL;
|
||||
const QHash<QString, QString> &hash = items.at(i);
|
||||
|
||||
|
@ -75,7 +75,6 @@ struct GridItem
|
||||
QImage image;
|
||||
QPixmap pixmap;
|
||||
QFutureWatcher<GridItem*> imageWatcher;
|
||||
QMutex mutex;
|
||||
};
|
||||
|
||||
class ThumbnailWidget : public QWidget
|
||||
|
Loading…
x
Reference in New Issue
Block a user