Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 48 additions & 28 deletions gallery/hotreload.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,14 @@
#include <QProcess>
#include <QTimer>

// TODO: not needed to sync dirs every second, just when a file was changed
QString HotReload::syncScript() const
{
return "#!/bin/sh \n\
echo running hot reload sync directories ... \n\
while true; do \n\
rsync -ra " GALLERY_SOURCE_DIR "/qml/ HotReload/qml/ \n\
rsync -ra " GALLERY_SOURCE_DIR "/../app/qml/ HotReload/app/qml/ \n\
sleep 1 \n\
done";
return QString( "#!/bin/sh \n"
"echo 'Syncing modified files...' \n"
"rsync -rau \"%1/qml/\" HotReload/qml/ \n"
"rsync -rau \"%1/../app/qml/\" HotReload/app/qml/ \n" )
.arg( GALLERY_SOURCE_DIR );
}

HotReload::HotReload( QQmlApplicationEngine &engine, QObject *parent ):
_engine( engine )
{
Expand Down Expand Up @@ -66,28 +62,52 @@ void HotReload::clearCache()

void HotReload::startHotReload()
{
_debounceTimer = new QTimer( this );
_debounceTimer->setSingleShot( true );
_debounceTimer->setInterval( 300 );

// when the timer starts, run the sync script ONCE, then reload
connect( _debounceTimer, &QTimer::timeout, this, [this]()
{
// run the sync synchronously so it finishes before reloading
QProcess::execute( "./syncGallery.sh" );
emit watchedSourceChanged();
} );

_watcher = new QFileSystemWatcher( this );
_watcher->addPath( "HotReload/qml" );
_watcher->addPath( "HotReload/qml/Pages" );
_watcher->addPath( "HotReload/app/qml/account" );
_watcher->addPath( "HotReload/app/qml/account/components" );
_watcher->addPath( "HotReload/app/qml/components" );
_watcher->addPath( "HotReload/app/qml/dialogs" );
_watcher->addPath( "HotReload/app/qml/form" );
_watcher->addPath( "HotReload/app/qml/form/components" );
_watcher->addPath( "HotReload/app/qml/form/editors" );
_watcher->addPath( "HotReload/app/qml/gps" );
_watcher->addPath( "HotReload/app/qml/inputs" );
_watcher->addPath( "HotReload/app/qml/layers" );
_watcher->addPath( "HotReload/app/qml/map" );
_watcher->addPath( "HotReload/app/qml/project" );
_watcher->addPath( "HotReload/app/qml/project/components" );
_watcher->addPath( "HotReload/app/qml/settings" );
_watcher->addPath( "HotReload/app/qml/settings/components" );

// send signal for hot reloading
// Set up base paths for your source code
QString gallerySrc = QString( GALLERY_SOURCE_DIR ) + "/qml";
QString appSrc = QString( GALLERY_SOURCE_DIR ) + "/../app/qml";

// Watch the SOURCE directories instead of the destination
_watcher->addPath( gallerySrc );
_watcher->addPath( gallerySrc + "/Pages" );

_watcher->addPath( appSrc + "/account" );
_watcher->addPath( appSrc + "/account/components" );
_watcher->addPath( appSrc + "/components" );
_watcher->addPath( appSrc + "/dialogs" );
_watcher->addPath( appSrc + "/form" );
_watcher->addPath( appSrc + "/form/components" );
_watcher->addPath( appSrc + "/form/editors" );
_watcher->addPath( appSrc + "/gps" );
_watcher->addPath( appSrc + "/inputs" );
_watcher->addPath( appSrc + "/layers" );
_watcher->addPath( appSrc + "/map" );
_watcher->addPath( appSrc + "/project" );
_watcher->addPath( appSrc + "/project/components" );
_watcher->addPath( appSrc + "/settings" );
_watcher->addPath( appSrc + "/settings/components" );

// when you save the file, start the debounce timer
connect( _watcher, &QFileSystemWatcher::directoryChanged, this, [this]( const QString & path )
{
emit watchedSourceChanged();
_debounceTimer->start();
} );

connect( _watcher, &QFileSystemWatcher::fileChanged, this, [this]( const QString & path )
{
_debounceTimer->start();
} );
}
2 changes: 2 additions & 0 deletions gallery/hotreload.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

#include <QObject>
#include <QQmlApplicationEngine>
#include <QTimer>

class QFileSystemWatcher;

Expand All @@ -34,6 +35,7 @@ class HotReload : public QObject
private:
QFileSystemWatcher *_watcher;
QQmlApplicationEngine &_engine;
QTimer *_debounceTimer = nullptr;
};

#endif // HOTRELOAD_H
20 changes: 17 additions & 3 deletions gallery/qml/Main.qml
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,29 @@ ApplicationWindow {

property string currentPageSource: "InitialGalleryPage.qml"

Timer {
id: reloadTimer
interval: 50
onTriggered: {
// delete the cache after 50ms
_hotReload.clearCache()

mainLoader.source = Qt.binding(function () {
return (__isMobile ? "qrc:/qml/pages/" : ("file://" + _qmlWrapperPath)) + window.currentPageSource
})
mainLoader.active = true

console.log(new Date().toLocaleTimeString().split(' ')[0] + " ------ App reloaded 🔥 ------ ")
}
}
Connections {
target: __isMobile ? null : _hotReload
enabled: !__isMobile
function onWatchedSourceChanged() {
mainLoader.active = false
mainLoader.setSource("")
_hotReload.clearCache()
mainLoader.setSource("file:///" + _qmlWrapperPath + currentPageSource)
mainLoader.active = true
console.log( new Date().toLocaleTimeString().split(' ')[0] + " ------ App reloaded 🔥 ------ ")
reloadTimer.start()
}
}

Expand Down
Loading