Compare commits

5 Commits

Author SHA1 Message Date
Digital Artifex d79997e883 Merge branch 'dev' 2026-08-25 05:20:11 -04:00
Digital Artifex b4a1e1bbf4 Renamed Controls and Kero modules 2026-08-25 04:45:09 -04:00
Digital Artifex 2fab4f209f Added private libs to get rhi class QShaderBaker 2026-08-25 04:43:35 -04:00
Digital Artifex 6541cedc67 Changed exceptions to std bases 2026-08-25 04:42:43 -04:00
Digital Artifex f3adc14a6e Reworked PackCompiler
PackCompiler now processes everything in memory to reduce file writes. Will also be able to expand error handling later
2026-08-25 04:35:15 -04:00
12 changed files with 915 additions and 1083 deletions
+3 -2
View File
@@ -4,7 +4,7 @@ cmake_minimum_required(VERSION 3.21.1)
option(LINK_INSIGHT "Link Qt Insight Tracker library" ON) option(LINK_INSIGHT "Link Qt Insight Tracker library" ON)
option(BUILD_QDS_COMPONENTS "Build design studio components" ON) option(BUILD_QDS_COMPONENTS "Build design studio components" ON)
project(KomplexHub LANGUAGES CXX) project(KomplexHub VERSION 1.0 LANGUAGES CXX)
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}/cmake") list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
@@ -21,7 +21,7 @@ set(QML_IMPORT_PATH ${QT_QML_OUTPUT_DIRECTORY}
) )
find_package( find_package(
Qt6 6.8 Qt6
REQUIRED COMPONENTS REQUIRED COMPONENTS
Core Core
Gui Gui
@@ -38,6 +38,7 @@ qt_standard_project_setup()
qt_add_executable(${CMAKE_PROJECT_NAME} qt_add_executable(${CMAKE_PROJECT_NAME}
) )
set_target_properties(${CMAKE_PROJECT_NAME} PROPERTIES VERSION "1.0")
qt_add_resources(${CMAKE_PROJECT_NAME} "configuration" qt_add_resources(${CMAKE_PROJECT_NAME} "configuration"
PREFIX "/" PREFIX "/"
+1
View File
@@ -18,5 +18,6 @@ qt6_add_qml_module(KomplexHubModule
"WallpaperModelData.qml" "WallpaperModelData.qml"
) )
set_target_properties(KomplexHubModule PROPERTIES VERSION "1.0")
add_subdirectory("Controls") add_subdirectory("Controls")
add_subdirectory("Kero") add_subdirectory("Kero")
+3 -3
View File
@@ -63,7 +63,7 @@ QtObject {
readonly property int normalAnimationDuration: 250 readonly property int normalAnimationDuration: 250
readonly property int fastAnimationDuration: 125 readonly property int fastAnimationDuration: 125
property StudioApplication application: StudioApplication { // property StudioApplication application: StudioApplication {
fontPath: Qt.resolvedUrl("../KomplexHubContent/" + relativeFontDirectory) // fontPath: Qt.resolvedUrl("../KomplexHubContent/" + relativeFontDirectory)
} // }
} }
+3 -2
View File
@@ -1,8 +1,8 @@
### This file is automatically generated by Qt Design Studio. ### This file is automatically generated by Qt Design Studio.
### Do not change ### Do not change
qt_add_library(KomplexHubModule_Controls STATIC) qt_add_library(KomplexHubControls STATIC)
qt6_add_qml_module(KomplexHubModule_Controls qt6_add_qml_module(KomplexHubControls
URI "KomplexHub.Controls" URI "KomplexHub.Controls"
VERSION 1.0 VERSION 1.0
RESOURCE_PREFIX "/qt/qml" RESOURCE_PREFIX "/qt/qml"
@@ -22,3 +22,4 @@ qt6_add_qml_module(KomplexHubModule_Controls
"BackgroundImage.qml" "BackgroundImage.qml"
) )
#set_target_properties(KomplexHubControls PROPERTIES VERSION "1.0")
+4 -3
View File
@@ -1,5 +1,5 @@
qt_add_library(KomplexHubModule_Kero STATIC) qt_add_library(KomplexHubKero STATIC)
qt6_add_qml_module(KomplexHubModule_Kero qt6_add_qml_module(KomplexHubKero
URI "KomplexHub.Kero" URI "KomplexHub.Kero"
VERSION 1.0 VERSION 1.0
RESOURCE_PREFIX "/qt/qml" RESOURCE_PREFIX "/qt/qml"
@@ -13,4 +13,5 @@ qt6_add_qml_module(KomplexHubModule_Kero
"KeroWarningAvatar.qml" "KeroWarningAvatar.qml"
"KeroHeader.qml" "KeroHeader.qml"
"KeroSuccessAvatar.qml" "KeroSuccessAvatar.qml"
) )
#set_target_properties(KomplexHubKero PROPERTIES VERSION "1.0")
+34 -2
View File
@@ -1,8 +1,34 @@
find_package(
Qt6
REQUIRED COMPONENTS
Core
Gui
GuiPrivate
Widgets
Qml
Quick
QuickControls2
QuickTimeline
ShaderTools
ShaderToolsPrivate
Concurrent
)
find_package(
OpenGL REQUIRED COMPONENTS OpenGL
)
find_package(
Vulkan REQUIRED COMPONENTS glslang SPIRV-Tools
)
add_library( add_library(
KomplexHubPlugin KomplexHubPlugin
STATIC STATIC
) )
set_target_properties(KomplexHubPlugin PROPERTIES VERSION "1.0")
qt_add_qml_module( qt_add_qml_module(
KomplexHubPlugin KomplexHubPlugin
URI URI
@@ -62,6 +88,7 @@ qt_add_qml_module(
common/qwallet.cpp common/qwallet.cpp
usermodel.h usermodel.h
usermodel.cpp usermodel.cpp
SOURCES
) )
target_compile_definitions( target_compile_definitions(
@@ -73,8 +100,13 @@ target_compile_definitions(
add_subdirectory(3rdparty/qtkeychain) add_subdirectory(3rdparty/qtkeychain)
target_link_libraries(KomplexHubPlugin PRIVATE target_link_libraries(KomplexHubPlugin PRIVATE
Qt${QT_VERSION_MAJOR}::Core Qt6::Core
Qt${QT_VERSION_MAJOR}::Gui Qt6::Concurrent
Qt6::Gui
Qt6::GuiPrivate
Qt6::ShaderTools
Qt6::ShaderToolsPrivate
Vulkan::Vulkan
qt6keychain qt6keychain
) )
+178 -17
View File
@@ -19,36 +19,197 @@
#ifndef EXCEPTIONS_H #ifndef EXCEPTIONS_H
#define EXCEPTIONS_H #define EXCEPTIONS_H
#include <QString> #include <QString>
#include <exception> #include <string>
#include <filesystem>
#include "komplex_global.h" #include "komplex_global.h"
struct KOMPLEX_EXPORT Exception : std::exception struct KOMPLEX_EXPORT network_exception : std::ios_base::failure
{ {
explicit Exception(const QString &message, quint16 errorCode = 0) network_exception(const std::string &message, const std::string &details, const std::error_code &code) :
: std::exception(), message(message), errorCode(errorCode){} details(details),
std::ios_base::failure(message, code) { }
const QString message; network_exception(const std::string &message, const std::error_code &code) :
const quint16 errorCode; std::ios_base::failure(message, code) { }
network_exception(const QString &message, const QString &details, const std::error_code &code) :
details(details.toStdString()),
std::ios_base::failure(message.toStdString(), code) { }
network_exception(const QString &message, const int code = errno) :
std::ios_base::failure
(
message.toStdString(),
std::error_code
(
code,
std::system_category()
)
) { }
const std::string details;
}; };
struct KOMPLEX_EXPORT NetworkException : Exception struct KOMPLEX_EXPORT file_exception : std::filesystem::filesystem_error
{ {
NetworkException(const QString &message, qsizetype errorCode = 0) : Exception(message, errorCode) {} file_exception(const std::string &message, const std::string &details, const std::error_code &code) :
details(details),
std::filesystem::filesystem_error(message, code) { }
file_exception(const std::string &message, const std::error_code &code) :
std::filesystem::filesystem_error(message, code) { }
file_exception(const std::string &message, const int code = errno) :
std::filesystem::filesystem_error
(
message,
std::error_code
(
code,
std::system_category()
)
) { }
file_exception(const std::string &message, const std::string &details, const int code = errno) :
details(details),
std::filesystem::filesystem_error
(
message,
std::error_code
(
code,
std::system_category()
)
) { }
const std::string details;
}; };
struct KOMPLEX_EXPORT FileException : Exception
struct KOMPLEX_EXPORT sql_exception : std::ios_base::failure
{ {
FileException(const QString &message, qsizetype errorCode = 0) : Exception(message, errorCode) {} sql_exception(const std::string &message, const std::string &details, const std::error_code &code) :
details(details),
std::ios_base::failure(message, code) { }
sql_exception(const std::string &message, const std::error_code &code) :
std::ios_base::failure(message, code) { }
sql_exception(const std::string &message, const int code = errno) :
std::ios_base::failure
(
message,
std::error_code
(
code,
std::system_category()
)
) { }
const std::string details;
}; };
struct KOMPLEX_EXPORT SqlException : Exception
struct KOMPLEX_EXPORT wallet_exception : std::ios_base::failure
{ {
SqlException(const QString &message, qsizetype errorCode = 0) : Exception(message, errorCode) {} wallet_exception(const std::string &message, const std::string &details, const std::error_code &code) :
details(details),
std::ios_base::failure(message, code) { }
wallet_exception(const std::string &message, const std::error_code &code) :
std::ios_base::failure(message, code) { }
wallet_exception(const std::string &message, const std::string &details, const int code = errno) :
details(details),
std::ios_base::failure
(
message,
std::error_code
(
code,
std::system_category()
)
) { }
wallet_exception(const std::string &message, const int code = errno) :
std::ios_base::failure
(
message,
std::error_code
(
code,
std::system_category()
)
) { }
const std::string details;
}; };
struct KOMPLEX_EXPORT WalletException : Exception
struct KOMPLEX_EXPORT process_exception : std::runtime_error
{ {
WalletException(const QString &message, qsizetype errorCode = 0) : Exception(message, errorCode) {} process_exception(const std::string &message, const std::string &details, const std::error_code &code) :
details(details),
code(code),
std::runtime_error(message) { }
process_exception(const std::string &message, const std::error_code &code) :
code(code),
std::runtime_error(message) { }
process_exception(const std::string &message, const int code = errno) :
code
(
std::error_code
(
code,
std::system_category()
)
),
std::runtime_error
(
message
) { }
process_exception(const std::string &message, const std::string &details, const int code = errno) :
details(details),
code
(
std::error_code
(
code,
std::system_category()
)
),
std::runtime_error (message) { }
const std::string details;
const std::error_code code;
}; };
struct KOMPLEX_EXPORT ShaderCompilerException : Exception
namespace shader
{ {
ShaderCompilerException(const QString &message, qsizetype errorCode = 0) : Exception(message, errorCode) {} struct KOMPLEX_EXPORT logic_error : std::logic_error
}; {
logic_error(const std::string &message, const std::string &details, const std::error_code &code) :
details(details),
code(code),
std::logic_error(message) { }
logic_error(const std::string &message, const std::error_code &code) :
code(code),
std::logic_error(message) { }
logic_error(const std::string &message, const std::string &details = {}, const int code = errno) :
code
(
std::error_code
(
code,
std::system_category()
)
),
std::logic_error(message) { }
const std::string details;
const std::error_code code;
};
}
#endif // EXCEPTIONS_H #endif // EXCEPTIONS_H
+13 -4
View File
@@ -1,5 +1,6 @@
#include "qwallet.h" #include "qwallet.h"
#include "../3rdparty/qtkeychain/qtkeychain/keychain.h" #include "../3rdparty/qtkeychain/qtkeychain/keychain.h"
#include "common/exceptions.h"
auto QWallet::read(const QString &service, const QString &key) const -> QFuture<QByteArray> auto QWallet::read(const QString &service, const QString &key) const -> QFuture<QByteArray>
{ {
@@ -29,7 +30,11 @@ auto QWallet::read(const QString &service, const QString &key) const -> QFuture<
else else
{ {
m_errorString = qPrintable(j->errorString()); m_errorString = qPrintable(j->errorString());
throw std::exception(); throw wallet_exception
(
QStringLiteral("Wallet read error").toStdString(),
errorString().toStdString()
);
} }
loop.quit(); loop.quit();
@@ -65,11 +70,15 @@ auto QWallet::write(const QString &service, const QString &key, const QByteArray
this, this,
[this, key, &loop, &success](QKeychain::Job *job) [this, key, &loop, &success](QKeychain::Job *job)
{ {
auto j = static_cast<QKeychain::ReadPasswordJob*>(job); auto j = static_cast<QKeychain::WritePasswordJob*>(job);
if (j->error() != QKeychain::NoError) if (j->error() != QKeychain::NoError)
{ {
setErrorString(qPrintable(j->errorString())); setErrorString(qPrintable(j->errorString()));
throw std::exception(); throw wallet_exception
(
QStringLiteral("Wallet write error").toStdString(),
errorString().toStdString()
);
} }
loop.quit(); loop.quit();
@@ -102,7 +111,7 @@ auto QWallet::remove(const QString &service, const QString &key) -> QFuture<void
this, this,
[this, key, &loop, &value](QKeychain::Job *job) [this, key, &loop, &value](QKeychain::Job *job)
{ {
auto j = static_cast<QKeychain::ReadPasswordJob*>(job); auto j = static_cast<QKeychain::DeletePasswordJob*>(job);
if (j->error() != QKeychain::NoError) if (j->error() != QKeychain::NoError)
{ {
m_errorString = qPrintable(j->errorString()); m_errorString = qPrintable(j->errorString());
+19 -15
View File
@@ -130,7 +130,7 @@ auto DownloadManager::downloadImage(const QString &author, const QString &author
if(!packDirectory.mkpath(packUri.toLocalFile())) if(!packDirectory.mkpath(packUri.toLocalFile()))
{ {
throw FileException(QStringLiteral("Could not create directory")); throw file_exception(QStringLiteral("Could not create directory").toStdString());
} }
packDirectory.mkdir(QStringLiteral("images")); packDirectory.mkdir(QStringLiteral("images"));
@@ -148,7 +148,7 @@ auto DownloadManager::downloadImage(const QString &author, const QString &author
if(!packFile.open(QFile::ReadWrite)) if(!packFile.open(QFile::ReadWrite))
{ {
setError(QStringLiteral("File Error"), packFile.errorString()); setError(QStringLiteral("File Error"), packFile.errorString());
throw FileException(packFile.errorString()); throw file_exception(packFile.errorString().toStdString());
} }
QByteArray data = metadata.json().toJson(QJsonDocument::Indented); QByteArray data = metadata.json().toJson(QJsonDocument::Indented);
@@ -156,7 +156,7 @@ auto DownloadManager::downloadImage(const QString &author, const QString &author
if(packFile.write(data) != data.length()) if(packFile.write(data) != data.length())
{ {
setError(QStringLiteral("File Error"), packFile.errorString()); setError(QStringLiteral("File Error"), packFile.errorString());
throw FileException(packFile.errorString()); throw file_exception(packFile.errorString().toStdString());
} }
packFile.close(); packFile.close();
@@ -239,6 +239,8 @@ auto DownloadManager::downloadVideo(const QString &author, const QString &author
( (
[this, author, id](QUrl result) -> QUrl [this, author, id](QUrl result) -> QUrl
{ {
setState(Installing);
ShaderPack metadata; ShaderPack metadata;
metadata.setAuthor(author); metadata.setAuthor(author);
metadata.setType(ShaderPack::Video); metadata.setType(ShaderPack::Video);
@@ -282,7 +284,7 @@ auto DownloadManager::downloadVideo(const QString &author, const QString &author
if(!packFile.open(QFile::ReadWrite)) if(!packFile.open(QFile::ReadWrite))
{ {
setError(QStringLiteral("File Error"), packFile.errorString()); setError(QStringLiteral("File Error"), packFile.errorString());
throw FileException(packFile.errorString()); throw file_exception(packFile.errorString().toStdString());
} }
QByteArray data = metadata.json().toJson(QJsonDocument::Compact); QByteArray data = metadata.json().toJson(QJsonDocument::Compact);
@@ -290,7 +292,7 @@ auto DownloadManager::downloadVideo(const QString &author, const QString &author
if(packFile.write(data) != data.length()) if(packFile.write(data) != data.length())
{ {
setError(QStringLiteral("File Error"), packFile.errorString()); setError(QStringLiteral("File Error"), packFile.errorString());
throw FileException(packFile.errorString()); throw file_exception(packFile.errorString().toStdString());
} }
packFile.close(); packFile.close();
@@ -369,6 +371,7 @@ auto DownloadManager::downloadPack(const QString &id) -> void
QNetworkRequest request(downloadUrl); QNetworkRequest request(downloadUrl);
request.setRawHeader(QByteArray("uuid"), id.toUtf8()); request.setRawHeader(QByteArray("uuid"), id.toUtf8());
QString tempFile(QString("%1.tar.gz").arg(id)); QString tempFile(QString("%1.tar.gz").arg(id));
setState(Downloading);
QFuture<QUrl> downloadUri = download(request, id, Post, tempFile); QFuture<QUrl> downloadUri = download(request, id, Post, tempFile);
@@ -377,7 +380,8 @@ auto DownloadManager::downloadPack(const QString &id) -> void
( (
[this](QUrl result) -> QUrl [this](QUrl result) -> QUrl
{ {
return m_compiler->process(result).result(); setState(Compiling);
return m_compiler->build(result);
} }
) )
.then .then
@@ -414,11 +418,11 @@ auto DownloadManager::downloadPack(const QString &id) -> void
) )
.onFailed .onFailed
( (
[this, tempFile] (const std::logic_error &e) [this, tempFile] (const shader::logic_error &e)
{ {
QFile::remove(QStringLiteral("/tmp/") + tempFile); QFile::remove(QStringLiteral("/tmp/") + tempFile);
reset(); reset();
setError(QStringLiteral("Logic Exception %1"), e.what()); setError(e.what(), QString::fromStdString(e.details));
} }
) )
.onFailed .onFailed
@@ -427,7 +431,7 @@ auto DownloadManager::downloadPack(const QString &id) -> void
{ {
QFile::remove(QStringLiteral("/tmp/") + tempFile); QFile::remove(QStringLiteral("/tmp/") + tempFile);
reset(); reset();
setError(QStringLiteral("Logic Exception %1"), e.what()); setError(QStringLiteral("Exception %1"), e.what());
} }
) )
.onFailed .onFailed
@@ -554,13 +558,13 @@ auto DownloadManager::install(const QUrl &uri) noexcept(false) -> QUrl
if(!m_moveProcess.waitForStarted(3000)) if(!m_moveProcess.waitForStarted(3000))
{ {
qWarning() << QStringLiteral("Could not start copy process: %1").arg(m_moveProcess.readAllStandardError()); qWarning() << QStringLiteral("Could not start copy process: %1").arg(m_moveProcess.readAllStandardError());
throw FileException(QStringLiteral("Could not start install process")); throw file_exception(QStringLiteral("Could not start install process").toStdString());
} }
if(!m_moveProcess.waitForFinished()) if(!m_moveProcess.waitForFinished())
{ {
qWarning() << QStringLiteral("Copy process took longer than expected (>30s)"); qWarning() << QStringLiteral("Copy process took longer than expected (>30s)");
throw FileException(QStringLiteral("Install process took longer than expected (>30s)")); throw file_exception(QStringLiteral("Install process took longer than expected (>30s)").toStdString());
} }
return installLocation; return installLocation;
@@ -594,7 +598,7 @@ auto DownloadManager::download(const QNetworkRequest &request, const QString &id
if(manager == nullptr) if(manager == nullptr)
{ {
throw NetworkException throw network_exception
{ {
QStringLiteral("Network Manager reference has already been deleted") QStringLiteral("Network Manager reference has already been deleted")
}; };
@@ -604,7 +608,7 @@ auto DownloadManager::download(const QNetworkRequest &request, const QString &id
if(downloadFile.exists() && !downloadFile.remove()) if(downloadFile.exists() && !downloadFile.remove())
{ {
throw FileException(downloadFile.errorString()); throw file_exception(downloadFile.errorString().toStdString());
} }
QNetworkReply *reply = nullptr; QNetworkReply *reply = nullptr;
@@ -629,7 +633,7 @@ auto DownloadManager::download(const QNetworkRequest &request, const QString &id
{ {
loop.quit(); loop.quit();
throw NetworkException throw network_exception
( (
QStringLiteral("Network Error %1").arg QStringLiteral("Network Error %1").arg
( (
@@ -664,7 +668,7 @@ auto DownloadManager::download(const QNetworkRequest &request, const QString &id
if(!downloadFile.open(QFile::ReadWrite | QFile::Append)) if(!downloadFile.open(QFile::ReadWrite | QFile::Append))
{ {
throw FileException(QStringLiteral("Could not open temp file location")); throw file_exception(QStringLiteral("Could not open temp file location").toStdString());
} }
QNetworkReply *reply = qobject_cast<QNetworkReply*>(sender()); QNetworkReply *reply = qobject_cast<QNetworkReply*>(sender());
File diff suppressed because it is too large Load Diff
+239 -116
View File
@@ -36,6 +36,8 @@
#include <qobject.h> #include <qobject.h>
#include <qtmetamacros.h> #include <qtmetamacros.h>
#include <QPainter> #include <QPainter>
#include <QtShaderTools>
#include <QtShaderTools/rhi/qshaderbaker.h>
#include <QtConcurrent/qtconcurrentrun.h> #include <QtConcurrent/qtconcurrentrun.h>
#include <qcontainerfwd.h> #include <qcontainerfwd.h>
#include <qmargins.h> #include <qmargins.h>
@@ -43,21 +45,42 @@
#include <qtmetamacros.h> #include <qtmetamacros.h>
#include <qurl.h> #include <qurl.h>
#include "common/komplex_global.h" #include "common/komplex_global.h"
#if __has_include("vulkan/vulkan_core.h")
#define HAS_VULKAN
#include <vulkan/vulkan_core.h>
#endif
#if __has_include("GL/gl.h")
#define HAS_OPENGL
#include <GL/gl.h>
#endif
struct KOMPLEX_EXPORT BuildContext
{
QMap<QByteArray, QByteArray> commonData;
QPromise<QUrl> promise;
};
/** /**
* @brief The PackCompiler class * @brief The PackCompiler class
* [1] Extract Pack (GZip) * [1] Extract Pack (GZip)
* [2] Verify directory is a pack and has shaders * [2] Verify directory is a pack and has shaders
* [3] Load shader code * [3] Load Common shader code
* [4] Append Common and Global files, if they exist * [4] Walk the shader directory
* [5] Add uniform and replace variable use * [5] Load shader code
* [6] Run C Preprocessor (cpp -P) to process macros * [6] Append type specific common code and global code
* [7] Append version macro * [7] Replace uniform variable use
* [8] Compile with Qt Shader Baker * [8] Add uniform header
* [9] Add uniform footer
* [10] Run preprocessor to process macros
* [11] Append version macro
* [12] Compile with QShaderBaker
* [13] Save
*/ */
class KOMPLEX_EXPORT PackCompiler : public QObject class PackCompiler : public QObject
{ {
Q_OBJECT Q_OBJECT
QML_ELEMENT
public: public:
enum State enum State
@@ -70,7 +93,6 @@ public:
Q_ENUM(State) Q_ENUM(State)
explicit PackCompiler(QObject *parent = nullptr); explicit PackCompiler(QObject *parent = nullptr);
~PackCompiler() override;
auto compilerOutput() const -> const QString & { return m_compilerOutput; } auto compilerOutput() const -> const QString & { return m_compilerOutput; }
auto progress() -> qreal { return m_progress; } auto progress() -> qreal { return m_progress; }
@@ -78,65 +100,11 @@ public:
auto totalSteps() -> qint64 { return m_totalSteps; } auto totalSteps() -> qint64 { return m_totalSteps; }
auto errorTitle() const -> const QString & { return m_errorTitle; } auto errorTitle() const -> const QString & { return m_errorTitle; }
auto errorMessage() const -> const QString & { return m_errorMessage; } auto errorMessage() const -> const QString & { return m_errorMessage; }
auto reset() -> void;
auto process(const QUrl &uri) -> QFuture<QUrl>;
auto status() const -> const QString & { return m_status; } auto status() const -> const QString & { return m_status; }
auto state() const -> State { return m_state; } auto state() const -> State { return m_state; }
auto reset() -> void;
protected: auto build(const QUrl &uri) -> QUrl;
/**
* @brief prepareShaders
* Scans the pack's shader directory and sends each file to
* prepareFile()
* @param uri
* Directory to prepare
*/
auto prepareShaders(const QUrl &uri) noexcept(false) -> void;
/**
* @brief prepareFile
* Prepares the individual file by appending the header, footer,
* common files and replacing standard variable names
* @param uri
*/
auto prepareFile(const QUrl &uri) noexcept(false) -> void;
/**
* @brief validateDirectory
*
* @param uri
* @return true
* @return false
*/
auto validateDirectory(const QUrl &uri) -> bool;
auto createDirectory(const QUrl &uri) -> void;
auto validateUri(const QUrl &uri) noexcept(false) -> void;
auto extract(const QUrl &sourceUri) noexcept(false) -> QUrl;
auto copyFile(const QUrl &sourceUri, const QUrl &destinationUri) noexcept(false) -> void;
auto compile(const QUrl &uri) noexcept(false) -> void;
auto preprocess(const QUrl &uri) noexcept(false) -> void;
auto appendVersion(const QUrl &uri) noexcept(false) -> void;
auto compileShader(const QUrl &uri) noexcept(false) -> void;
auto loadCommonFragmentData(const QUrl &uri) -> QByteArray;
auto loadCommonVertexData(const QUrl &uri) -> QByteArray;
auto loadGlobalData(const QUrl &uri) -> QByteArray;
auto setError(const QString &title, const QString &message, const QUrl &uri = {}) -> void;
auto setCompilerOutput(const QString &compilerOutput) -> void;
auto setState(State state) -> void;
auto setProgress(qreal progress) -> void;
auto setTotalSteps(qint64 steps) -> void;
auto setCurrentStep(qint64 step) -> void;
auto setStatus(const QString &status) -> void;
auto incrementCompileStep() -> void;
auto removeDirectory(const QUrl &uri) -> bool;
signals: signals:
auto compilerOutputChanged() -> void; auto compilerOutputChanged() -> void;
@@ -147,38 +115,213 @@ signals:
auto progressChanged() -> void; auto progressChanged() -> void;
auto currentStepChanged() -> void; auto currentStepChanged() -> void;
auto totalStepsChanged() -> void; auto totalStepsChanged() -> void;
auto compileComplete(const QUrl &uri) -> void; auto compileComplete(const QUrl &uri) -> void;
auto statusChanged() -> void; auto statusChanged() -> void;
auto packReady(const QString &) -> void; auto packReady(const QString &) -> void;
auto errorStepChanged() -> void; auto errorStepChanged() -> void;
auto errorRatingChanged() -> void; auto errorRatingChanged() -> void;
private: private:
//[1]
/**
* @brief extract
* Extracts the packfile and deletes the source
* @param uri of the tar.gz pack
* @return uri of the extracted directory
*/
auto extract(const QUrl &uri) noexcept(false) -> const QUrl;
//[2]
/**
* @brief validatePack
* Validates that the directory is a valid pack and has shaders to compile
* @param uri of the directory provided by extract
*/
auto validatePack(const QUrl &uri) const noexcept(false) -> void;
//[3]
/**
* @brief loadCommonData
* Loads the common and global shader code from the shader directory of the uri
* @param uri
*/
auto loadCommonData(const QUrl &uri) -> QMap<QByteArray,QByteArray>;
//[4-5]
/**
* @brief processShaders
* Walks the shader directory, loads the code and calls 6-13 for each
* @param uri
* @param context
*/
auto processShaders(const QUrl &uri, BuildContext *context) -> void;
//[6]
/**
* @brief appendCommonData
* Appends the type specific common code to the shader data
* @param data
* Pointer to shader data
* @param suffix
* Shader file suffix
* @param context
* Pointer to build context object
*/
auto appendCommonData(QByteArray *data, const QByteArray &suffix, BuildContext *context) noexcept(true) -> void;
//[7]
/**
* @brief replaceUniformVariables
* Replaces standard variables such as iFrame with their uniform buffer name
* @param data
* Pointer to the shader data
*/
auto replaceUniformVariables(QByteArray *data) noexcept(true) -> void;
//[8]
/**
* @brief appendUniformHeader
* Adds header and uniform buffer to the shader data
* @param data
* Pointer to the shader data
*/
auto appendUniformHeader(QByteArray *data) noexcept(true) -> void;
//[9]
/**
* @brief appendUniformFooter
* Adds the uniform footer to the shader data
* @param data
* Pointer to the shader data
*/
auto appendUniformFooter(QByteArray *data) noexcept(true) -> void;
//[10]
/**
* @brief preprocess
* I have had issues with defines in code so passing it to a c/c++
* preprocessor is required. I am now using clang for this as clang
* is more modern and can use stdin
* @param data
*/
auto preprocess(QByteArray *data) noexcept(false) -> void;
//[11]
/**
* @brief appendVersion
* The version header confuses the preprocessor, so add it at the end
* @param data
*/
auto appendVersion(QByteArray *data) noexcept(true) -> void;
//[12]
/**
* @brief compile
* Compiles the shader data in memory and returns the shader object.
* @param data
* Shader data
* @param filename
* Filename of the shader
* @param stage
* Type of shader, based on suffix of original file
* @return
* Compiled shader object
*/
auto compile(const QByteArray &data, const QString &filename, const QShader::Stage stage) noexcept(false) -> QShader;
//[13]
auto save(const QUrl &uri, const QShader &shader) noexcept(false) -> void;
//helpers
auto validateUri(const QUrl &uri) const noexcept(false) -> void;
auto run(const QString &command, const QStringList &arguments, const QByteArray &data = {}) noexcept(false) -> QByteArray;
auto readFile(const QUrl &uri) noexcept(false) -> QByteArray;
auto writeFile(const QUrl &uri, const QByteArray &data) noexcept(false) -> void;
auto copyFile(const QUrl &sourceUri, const QUrl &destinationUri) noexcept(false) -> void;
auto createDirectory(const QUrl &uri) noexcept(false) -> void;
auto removeDirectory(const QUrl &uri) noexcept(false) -> void;
auto getStageFromSuffix(const QString &suffix) const -> QShader::Stage;
auto setError(const QString &title, const QString &message, const QUrl &uri = {}) -> void;
auto setCompilerOutput(const QString &compilerOutput) -> void;
auto setState(State state) -> void;
auto setProgress(qreal progress) -> void;
auto setTotalSteps(qint64 steps) -> void;
auto setCurrentStep(qint64 step) -> void;
auto setStatus(const QString &status) -> void;
auto incrementCompileStep() -> void;
#ifdef HAS_VULKAN
auto vulkanVersion() const -> qint32;
#endif
#ifdef HAS_OPENGL
auto openGlVersion() const -> qint32;
#endif
//members
static inline const QStringList m_updateVariables static inline const QStringList m_updateVariables
{
QStringLiteral("iTime"),
QStringLiteral("iTimeDelta"),
QStringLiteral("iFrameRate"),
QStringLiteral("iSampleRate"),
QStringLiteral("iFrame"),
QStringLiteral("iDate"),
QStringLiteral("iMouse"),
QStringLiteral("iResolution"),
QStringLiteral("iColorTheme"),
QStringLiteral("iChannelTime"),
QStringLiteral("iChannelResolution")
};
static inline const QStringList m_shaderNameFilters
{
QStringLiteral("*.frag"),
QStringLiteral("*.vert"),
QStringLiteral("*.tese"),
QStringLiteral("*.tesc"),
QStringLiteral("*.geom"),
QStringLiteral("*.comp"),
QStringLiteral("*.glsl")
};
static inline const QMap<QString, QShader::Stage> m_shaderStages
{
{ {
QStringLiteral("iTime"), QStringLiteral("frag"),
QStringLiteral("iTimeDelta"), QShader::FragmentStage
QStringLiteral("iFrameRate"), },
QStringLiteral("iSampleRate"), {
QStringLiteral("iFrame"), QStringLiteral("vert"),
QStringLiteral("iDate"), QShader::VertexStage
QStringLiteral("iMouse"), },
QStringLiteral("iResolution"), {
QStringLiteral("iColorTheme"), QStringLiteral("tese"),
QStringLiteral("iChannelTime"), QShader::TessellationEvaluationStage
QStringLiteral("iChannelResolution") },
}; {
QStringLiteral("tesc"),
QShader::TessellationControlStage
},
{
QStringLiteral("geom"),
QShader::GeometryStage
},
{
QStringLiteral("comp"),
QShader::ComputeStage
}
};
static inline const QByteArray m_version static inline const QByteArray m_version
{ {
R"(#version 450)" R"(#version 450)"
}; };
static inline const QString m_header static inline const QByteArray m_header
{ {
R"(layout(location = 0) in vec2 qt_TexCoord0; R"(layout(location = 0) in vec2 qt_TexCoord0;
layout(location = 0) out vec4 fragColor; layout(location = 0) out vec4 fragColor;
layout(std140, binding = 0) uniform buf { layout(std140, binding = 0) uniform buf {
@@ -203,16 +346,20 @@ layout(binding = 3) uniform sampler2D iChannel2;
layout(binding = 4) uniform sampler2D iChannel3; layout(binding = 4) uniform sampler2D iChannel3;
vec2 fragCoord = vec2(qt_TexCoord0.x, 1.0 - qt_TexCoord0.y) * ubuf.iResolution.xy;)" vec2 fragCoord = vec2(qt_TexCoord0.x, 1.0 - qt_TexCoord0.y) * ubuf.iResolution.xy;)"
}; };
static inline const QString m_footer static inline const QByteArray m_footer
{ {
R"(void main() { R"(
void main() {
vec4 color = vec4(0.0); vec4 color = vec4(0.0);
mainImage(color, fragCoord); mainImage(color, fragCoord);
fragColor = color; fragColor = color;
})" })"
}; };
QMap<QByteArray, QByteArray> m_commonData;
QMap<QByteArray, QShaderBaker> m_shaders;
QString m_compilerOutput; QString m_compilerOutput;
QString m_errorMessage; QString m_errorMessage;
@@ -227,34 +374,10 @@ vec2 fragCoord = vec2(qt_TexCoord0.x, 1.0 - qt_TexCoord0.y) * ubuf.iResolution.x
QMutex m_downloadMutex; QMutex m_downloadMutex;
QFuture<QUrl> m_buildFuture;
static inline QList<QRegularExpression> m_variableExpressions; static inline QList<QRegularExpression> m_variableExpressions;
static inline const QRegularExpression m_commonFragmentExpression = QRegularExpression
(
QString("^common\\.frag$"),
QRegularExpression::CaseInsensitiveOption
);
static inline const QRegularExpression m_commonVertexExpression = QRegularExpression
(
QString("^common\\.vert$"),
QRegularExpression::CaseInsensitiveOption
);
static inline const QRegularExpression m_fragmentExpression = QRegularExpression
(
QString("^.{1,}\\.frag$"),
QRegularExpression::CaseInsensitiveOption |
QRegularExpression::DotMatchesEverythingOption
);
static inline const QRegularExpression m_vertexExpression = QRegularExpression
(
QString("^.{1,}\\.vert$"),
QRegularExpression::CaseInsensitiveOption |
QRegularExpression::DotMatchesEverythingOption
);
Q_PROPERTY(QString compilerOutput READ compilerOutput WRITE setCompilerOutput NOTIFY compilerOutputChanged FINAL) Q_PROPERTY(QString compilerOutput READ compilerOutput WRITE setCompilerOutput NOTIFY compilerOutputChanged FINAL)
Q_PROPERTY(QString errorTitle READ errorTitle NOTIFY errorTitleChanged FINAL) Q_PROPERTY(QString errorTitle READ errorTitle NOTIFY errorTitleChanged FINAL)
Q_PROPERTY(QString errorMessage READ errorMessage NOTIFY errorMessageChanged FINAL) Q_PROPERTY(QString errorMessage READ errorMessage NOTIFY errorMessageChanged FINAL)
+2 -2
View File
@@ -11,8 +11,8 @@ target_link_libraries(${CMAKE_PROJECT_NAME} PRIVATE
KomplexHubModuleplugin KomplexHubModuleplugin
KomplexHubContentplugin KomplexHubContentplugin
KomplexHubPluginplugin KomplexHubPluginplugin
KomplexHubModule_Controlsplugin KomplexHubControlsplugin
KomplexHubModule_Keroplugin KomplexHubKeroplugin
Qt6::Quick Qt6::Quick
Qt6::Core Qt6::Core
Qt6::Gui Qt6::Gui