Преглед на файлове

chore: apply clang-format to the project and run clang-format checks on actions

Almamu преди 7 месеца
родител
ревизия
baf10b3851
променени са 100 файла, в които са добавени 4342 реда и са изтрити 4425 реда
  1. 114 42
      .clang-format
  2. 13 0
      .github/workflows/cmake.yml
  3. 16 12
      src/Steam/FileSystem/FileSystem.cpp
  4. 406 398
      src/WallpaperEngine/Application/ApplicationContext.cpp
  5. 117 116
      src/WallpaperEngine/Application/ApplicationContext.h
  6. 5 5
      src/WallpaperEngine/Application/ApplicationState.h
  7. 379 426
      src/WallpaperEngine/Application/WallpaperApplication.cpp
  8. 20 19
      src/WallpaperEngine/Application/WallpaperApplication.h
  9. 2 2
      src/WallpaperEngine/Assets/AssetLoadException.cpp
  10. 1 1
      src/WallpaperEngine/Assets/AssetLoadException.h
  11. 29 30
      src/WallpaperEngine/Assets/AssetLocator.cpp
  12. 2 2
      src/WallpaperEngine/Assets/AssetLocator.h
  13. 7 19
      src/WallpaperEngine/Audio/AudioContext.cpp
  14. 47 47
      src/WallpaperEngine/Audio/AudioContext.h
  15. 302 265
      src/WallpaperEngine/Audio/AudioStream.cpp
  16. 13 13
      src/WallpaperEngine/Audio/AudioStream.h
  17. 4 13
      src/WallpaperEngine/Audio/Drivers/AudioDriver.cpp
  18. 61 60
      src/WallpaperEngine/Audio/Drivers/AudioDriver.h
  19. 5 10
      src/WallpaperEngine/Audio/Drivers/Detectors/AudioPlayingDetector.cpp
  20. 45 44
      src/WallpaperEngine/Audio/Drivers/Detectors/AudioPlayingDetector.h
  21. 31 22
      src/WallpaperEngine/Audio/Drivers/Detectors/PulseAudioPlayingDetector.cpp
  22. 4 3
      src/WallpaperEngine/Audio/Drivers/Detectors/PulseAudioPlayingDetector.h
  23. 1 1
      src/WallpaperEngine/Audio/Drivers/Recorders/PlaybackRecorder.cpp
  24. 4 4
      src/WallpaperEngine/Audio/Drivers/Recorders/PlaybackRecorder.h
  25. 131 109
      src/WallpaperEngine/Audio/Drivers/Recorders/PulseAudioPlaybackRecorder.cpp
  26. 13 15
      src/WallpaperEngine/Audio/Drivers/Recorders/PulseAudioPlaybackRecorder.h
  27. 89 98
      src/WallpaperEngine/Audio/Drivers/SDLAudioDriver.cpp
  28. 6 5
      src/WallpaperEngine/Audio/Drivers/SDLAudioDriver.h
  29. 44 49
      src/WallpaperEngine/Data/Assets/Texture.h
  30. 7 7
      src/WallpaperEngine/Data/Assets/Types.h
  31. 8 9
      src/WallpaperEngine/Data/Builders/UserSettingBuilder.h
  32. 79 120
      src/WallpaperEngine/Data/Builders/VectorBuilder.h
  33. 124 130
      src/WallpaperEngine/Data/Dumpers/StringPrinter.cpp
  34. 3 3
      src/WallpaperEngine/Data/Dumpers/StringPrinter.h
  35. 63 80
      src/WallpaperEngine/Data/JSON.h
  36. 139 175
      src/WallpaperEngine/Data/Model/DynamicValue.cpp
  37. 22 22
      src/WallpaperEngine/Data/Model/DynamicValue.h
  38. 8 11
      src/WallpaperEngine/Data/Model/Effect.h
  39. 4 8
      src/WallpaperEngine/Data/Model/Material.h
  40. 1 1
      src/WallpaperEngine/Data/Model/Model.h
  41. 162 96
      src/WallpaperEngine/Data/Model/Object.h
  42. 2 7
      src/WallpaperEngine/Data/Model/Project.h
  43. 135 149
      src/WallpaperEngine/Data/Model/Property.h
  44. 25 25
      src/WallpaperEngine/Data/Model/Types.h
  45. 1 1
      src/WallpaperEngine/Data/Model/UserSetting.h
  46. 69 69
      src/WallpaperEngine/Data/Model/Wallpaper.h
  47. 54 44
      src/WallpaperEngine/Data/Parsers/EffectParser.cpp
  48. 6 6
      src/WallpaperEngine/Data/Parsers/EffectParser.h
  49. 44 44
      src/WallpaperEngine/Data/Parsers/MaterialParser.cpp
  50. 4 4
      src/WallpaperEngine/Data/Parsers/MaterialParser.h
  51. 12 12
      src/WallpaperEngine/Data/Parsers/ModelParser.cpp
  52. 1 1
      src/WallpaperEngine/Data/Parsers/ModelParser.h
  53. 446 447
      src/WallpaperEngine/Data/Parsers/ObjectParser.cpp
  54. 8 6
      src/WallpaperEngine/Data/Parsers/ObjectParser.h
  55. 8 10
      src/WallpaperEngine/Data/Parsers/PackageParser.cpp
  56. 1 1
      src/WallpaperEngine/Data/Parsers/PackageParser.h
  57. 27 27
      src/WallpaperEngine/Data/Parsers/ProjectParser.cpp
  58. 4 4
      src/WallpaperEngine/Data/Parsers/ProjectParser.h
  59. 79 59
      src/WallpaperEngine/Data/Parsers/PropertyParser.cpp
  60. 2 2
      src/WallpaperEngine/Data/Parsers/PropertyParser.h
  61. 3 3
      src/WallpaperEngine/Data/Parsers/ShaderConstantParser.cpp
  62. 1 1
      src/WallpaperEngine/Data/Parsers/ShaderConstantParser.h
  63. 186 181
      src/WallpaperEngine/Data/Parsers/TextureParser.cpp
  64. 10 7
      src/WallpaperEngine/Data/Parsers/TextureParser.h
  65. 47 46
      src/WallpaperEngine/Data/Parsers/UserSettingParser.cpp
  66. 1 1
      src/WallpaperEngine/Data/Parsers/UserSettingParser.h
  67. 16 18
      src/WallpaperEngine/Data/Parsers/WallpaperParser.cpp
  68. 2 2
      src/WallpaperEngine/Data/Parsers/WallpaperParser.h
  69. 9 27
      src/WallpaperEngine/Data/Utils/BinaryReader.cpp
  70. 3 3
      src/WallpaperEngine/Data/Utils/BinaryReader.h
  71. 14 21
      src/WallpaperEngine/Data/Utils/MemoryStream.h
  72. 4 8
      src/WallpaperEngine/Data/Utils/SFINAE.h
  73. 11 13
      src/WallpaperEngine/Data/Utils/TypeCaster.h
  74. 152 162
      src/WallpaperEngine/Debugging/CallStack.cpp
  75. 13 13
      src/WallpaperEngine/Debugging/CallStack.h
  76. 22 23
      src/WallpaperEngine/FileSystem/Adapters/Directory.cpp
  77. 3 3
      src/WallpaperEngine/FileSystem/Adapters/Directory.h
  78. 12 12
      src/WallpaperEngine/FileSystem/Adapters/Package.cpp
  79. 2 2
      src/WallpaperEngine/FileSystem/Adapters/Package.h
  80. 1 1
      src/WallpaperEngine/FileSystem/Adapters/Types.h
  81. 8 16
      src/WallpaperEngine/FileSystem/Adapters/Virtual.cpp
  82. 2 2
      src/WallpaperEngine/FileSystem/Adapters/Virtual.h
  83. 22 21
      src/WallpaperEngine/FileSystem/Container.cpp
  84. 2 2
      src/WallpaperEngine/FileSystem/Container.h
  85. 8 15
      src/WallpaperEngine/Input/Drivers/GLFWMouseInput.cpp
  86. 2 2
      src/WallpaperEngine/Input/Drivers/GLFWMouseInput.h
  87. 13 10
      src/WallpaperEngine/Input/Drivers/WaylandMouseInput.cpp
  88. 2 2
      src/WallpaperEngine/Input/Drivers/WaylandMouseInput.h
  89. 3 7
      src/WallpaperEngine/Input/InputContext.cpp
  90. 2 2
      src/WallpaperEngine/Input/InputContext.h
  91. 4 7
      src/WallpaperEngine/Input/MouseInput.h
  92. 4 10
      src/WallpaperEngine/Logging/Log.cpp
  93. 36 31
      src/WallpaperEngine/Logging/Log.h
  94. 37 66
      src/WallpaperEngine/Render/CFBO.cpp
  95. 6 4
      src/WallpaperEngine/Render/CFBO.h
  96. 4 12
      src/WallpaperEngine/Render/CObject.cpp
  97. 12 14
      src/WallpaperEngine/Render/CObject.h
  98. 120 145
      src/WallpaperEngine/Render/CTexture.cpp
  99. 2 2
      src/WallpaperEngine/Render/CTexture.h
  100. 82 98
      src/WallpaperEngine/Render/CWallpaper.cpp

+ 114 - 42
.clang-format

@@ -1,56 +1,97 @@
 ---
 Language:        Cpp
-# BasedOnStyle:  LLVM
-AccessModifierOffset: -2
-AlignAfterOpenBracket: Align
+AccessModifierOffset: -4
+AlignAfterOpenBracket: BlockIndent
 AlignArrayOfStructures: None
 AlignConsecutiveAssignments:
   Enabled:         false
   AcrossEmptyLines: false
   AcrossComments:  false
   AlignCompound:   false
+  AlignFunctionDeclarations: false
+  AlignFunctionPointers: false
   PadOperators:    true
 AlignConsecutiveBitFields:
   Enabled:         false
   AcrossEmptyLines: false
   AcrossComments:  false
   AlignCompound:   false
+  AlignFunctionDeclarations: false
+  AlignFunctionPointers: false
   PadOperators:    false
 AlignConsecutiveDeclarations:
   Enabled:         false
   AcrossEmptyLines: false
   AcrossComments:  false
   AlignCompound:   false
+  AlignFunctionDeclarations: true
+  AlignFunctionPointers: false
   PadOperators:    false
 AlignConsecutiveMacros:
   Enabled:         false
   AcrossEmptyLines: false
   AcrossComments:  false
   AlignCompound:   false
+  AlignFunctionDeclarations: false
+  AlignFunctionPointers: false
+  PadOperators:    false
+AlignConsecutiveShortCaseStatements:
+  Enabled:         false
+  AcrossEmptyLines: false
+  AcrossComments:  false
+  AlignCaseArrows: false
+  AlignCaseColons: false
+AlignConsecutiveTableGenBreakingDAGArgColons:
+  Enabled:         false
+  AcrossEmptyLines: false
+  AcrossComments:  false
+  AlignCompound:   false
+  AlignFunctionDeclarations: false
+  AlignFunctionPointers: false
+  PadOperators:    false
+AlignConsecutiveTableGenCondOperatorColons:
+  Enabled:         false
+  AcrossEmptyLines: false
+  AcrossComments:  false
+  AlignCompound:   false
+  AlignFunctionDeclarations: false
+  AlignFunctionPointers: false
+  PadOperators:    false
+AlignConsecutiveTableGenDefinitionColons:
+  Enabled:         false
+  AcrossEmptyLines: false
+  AcrossComments:  false
+  AlignCompound:   false
+  AlignFunctionDeclarations: false
+  AlignFunctionPointers: false
   PadOperators:    false
 AlignEscapedNewlines: Right
-AlignOperands:   Align
+AlignOperands:   DontAlign
 AlignTrailingComments:
-  Kind:            Always
+  Kind:            Never
   OverEmptyLines:  0
 AllowAllArgumentsOnNextLine: true
 AllowAllParametersOfDeclarationOnNextLine: true
+AllowBreakBeforeNoexceptSpecifier: Never
 AllowShortBlocksOnASingleLine: Empty
-AllowShortCaseLabelsOnASingleLine: true
-AllowShortEnumsOnASingleLine: false
-AllowShortFunctionsOnASingleLine: Empty
+AllowShortCaseExpressionOnASingleLine: true
+AllowShortCaseLabelsOnASingleLine: false
+AllowShortCompoundRequirementOnASingleLine: true
+AllowShortEnumsOnASingleLine: true
+AllowShortFunctionsOnASingleLine: All
 AllowShortIfStatementsOnASingleLine: Never
 AllowShortLambdasOnASingleLine: All
 AllowShortLoopsOnASingleLine: false
+AllowShortNamespacesOnASingleLine: false
 AlwaysBreakAfterDefinitionReturnType: None
-AlwaysBreakAfterReturnType: None
 AlwaysBreakBeforeMultilineStrings: false
-AlwaysBreakTemplateDeclarations: MultiLine
 AttributeMacros:
   - __capability
 BinPackArguments: true
-BinPackParameters: true
+BinPackLongBracedList: true
+BinPackParameters: BinPack
 BitFieldColonSpacing: Both
+BracedInitializerIndentWidth: -1
 BraceWrapping:
   AfterCaseLabel:  false
   AfterClass:      false
@@ -70,29 +111,36 @@ BraceWrapping:
   SplitEmptyFunction: true
   SplitEmptyRecord: true
   SplitEmptyNamespace: true
-BreakAfterAttributes: Never
+BreakAdjacentStringLiterals: true
+BreakAfterAttributes: Leave
 BreakAfterJavaFieldAnnotations: false
+BreakAfterReturnType: None
 BreakArrays:     true
-BreakBeforeBinaryOperators: None
+BreakBeforeBinaryOperators: All
 BreakBeforeConceptDeclarations: Always
 BreakBeforeBraces: Attach
 BreakBeforeInlineASMColon: OnlyMultiline
+BreakBeforeTemplateCloser: false
 BreakBeforeTernaryOperators: true
+BreakBinaryOperations: Never
 BreakConstructorInitializers: AfterColon
+BreakFunctionDefinitionParameters: false
 BreakInheritanceList: BeforeColon
-BreakStringLiterals: false
+BreakStringLiterals: true
+BreakTemplateDeclarations: MultiLine
 ColumnLimit:     120
 CommentPragmas:  '^ IWYU pragma:'
 CompactNamespaces: false
 ConstructorInitializerIndentWidth: 4
 ContinuationIndentWidth: 4
-Cpp11BracedListStyle: true
+Cpp11BracedListStyle: false
 DerivePointerAlignment: false
 DisableFormat:   false
 EmptyLineAfterAccessModifier: Never
 EmptyLineBeforeAccessModifier: LogicalBlock
+EnumTrailingComma: Leave
 ExperimentalAutoDetectBinPacking: false
-FixNamespaceComments: true
+FixNamespaceComments: false
 ForEachMacros:
   - foreach
   - Q_FOREACH
@@ -116,15 +164,16 @@ IncludeCategories:
 IncludeIsMainRegex: '(Test)?$'
 IncludeIsMainSourceRegex: ''
 IndentAccessModifiers: false
-IndentCaseBlocks: false
+IndentCaseBlocks: true
 IndentCaseLabels: true
+IndentExportBlock: true
 IndentExternBlock: AfterExternBlock
 IndentGotoLabels: true
 IndentPPDirectives: None
 IndentRequiresClause: true
 IndentWidth:     4
 IndentWrappedFunctionNames: false
-InsertBraces:    false
+InsertBraces:    true
 InsertNewlineAtEOF: false
 InsertTrailingCommas: None
 IntegerLiteralSeparator:
@@ -136,45 +185,59 @@ IntegerLiteralSeparator:
   HexMinDigits:    0
 JavaScriptQuotes: Leave
 JavaScriptWrapImports: true
-KeepEmptyLinesAtTheStartOfBlocks: true
+KeepEmptyLines:
+  AtEndOfFile:     false
+  AtStartOfBlock:  true
+  AtStartOfFile:   true
+KeepFormFeed:    false
 LambdaBodyIndentation: Signature
 LineEnding:      DeriveLF
 MacroBlockBegin: ''
 MacroBlockEnd:   ''
+MainIncludeChar: Quote
 MaxEmptyLinesToKeep: 1
-NamespaceIndentation: None
+NamespaceIndentation: Inner
 ObjCBinPackProtocolList: Auto
-ObjCBlockIndentWidth: 2
+ObjCBlockIndentWidth: 4
 ObjCBreakBeforeNestedBlockParam: true
-ObjCSpaceAfterProperty: false
+ObjCSpaceAfterProperty: true
 ObjCSpaceBeforeProtocolList: true
-PackConstructorInitializers: CurrentLine
+OneLineFormatOffRegex: ''
+PackConstructorInitializers: BinPack
 PenaltyBreakAssignment: 2
 PenaltyBreakBeforeFirstCallParameter: 19
+PenaltyBreakBeforeMemberAccess: 150
 PenaltyBreakComment: 300
 PenaltyBreakFirstLessLess: 120
 PenaltyBreakOpenParenthesis: 0
+PenaltyBreakScopeResolution: 500
 PenaltyBreakString: 1000
 PenaltyBreakTemplateDeclaration: 10
 PenaltyExcessCharacter: 1000000
 PenaltyIndentedWhitespace: 0
-PenaltyReturnTypeOnItsOwnLine: 1000
+PenaltyReturnTypeOnItsOwnLine: 60
 PointerAlignment: Left
 PPIndentWidth:   -1
-QualifierAlignment: Left
+QualifierAlignment: Leave
 ReferenceAlignment: Pointer
-ReflowComments:  true
+ReflowComments:  Always
 RemoveBracesLLVM: false
+RemoveEmptyLinesInUnwrappedLines: false
+RemoveParentheses: Leave
 RemoveSemicolon: false
 RequiresClausePosition: OwnLine
 RequiresExpressionIndentation: OuterScope
-SeparateDefinitionBlocks: Always
+SeparateDefinitionBlocks: Leave
 ShortNamespaceLines: 1
-SortIncludes:    CaseSensitive
+SkipMacroDefinitionBody: false
+SortIncludes:
+  Enabled:         true
+  IgnoreCase:      false
 SortJavaStaticImport: Before
 SortUsingDeclarations: LexicographicNumeric
-SpaceAfterCStyleCast: true
+SpaceAfterCStyleCast: false
 SpaceAfterLogicalNot: false
+SpaceAfterOperatorKeyword: false
 SpaceAfterTemplateKeyword: true
 SpaceAroundPointerQualifiers: Default
 SpaceBeforeAssignmentOperators: true
@@ -182,30 +245,36 @@ SpaceBeforeCaseColon: false
 SpaceBeforeCpp11BracedList: true
 SpaceBeforeCtorInitializerColon: true
 SpaceBeforeInheritanceColon: true
+SpaceBeforeJsonColon: false
 SpaceBeforeParens: Always
 SpaceBeforeParensOptions:
   AfterControlStatements: true
   AfterForeachMacros: true
-  AfterFunctionDefinitionName: true
-  AfterFunctionDeclarationName: true
+  AfterFunctionDefinitionName: false
+  AfterFunctionDeclarationName: false
   AfterIfMacros:   true
-  AfterOverloadedOperator: true
-  AfterRequiresInClause: true
-  AfterRequiresInExpression: true
-  BeforeNonEmptyParentheses: true
+  AfterNot:        false
+  AfterOverloadedOperator: false
+  AfterPlacementOperator: true
+  AfterRequiresInClause: false
+  AfterRequiresInExpression: false
+  BeforeNonEmptyParentheses: false
 SpaceBeforeRangeBasedForLoopColon: true
-SpaceBeforeSquareBrackets: true
-SpaceInEmptyBlock: false
-SpaceInEmptyParentheses: false
+SpaceBeforeSquareBrackets: false
+SpaceInEmptyBlock: true
 SpacesBeforeTrailingComments: 1
 SpacesInAngles:  Never
-SpacesInConditionalStatement: false
 SpacesInContainerLiterals: true
-SpacesInCStyleCastParentheses: false
 SpacesInLineCommentPrefix:
   Minimum:         1
   Maximum:         -1
-SpacesInParentheses: false
+SpacesInParens:  Never
+SpacesInParensOptions:
+  ExceptDoubleParentheses: false
+  InCStyleCasts:   false
+  InConditionalStatements: false
+  InEmptyParentheses: false
+  Other:           false
 SpacesInSquareBrackets: false
 Standard:        Latest
 StatementAttributeLikeMacros:
@@ -213,13 +282,16 @@ StatementAttributeLikeMacros:
 StatementMacros:
   - Q_UNUSED
   - QT_REQUIRE_VERSION
+TableGenBreakInsideDAGArg: DontBreak
 TabWidth:        8
-UseTab:          Never
+UseTab:          ForContinuationAndIndentation
+VerilogBreakBetweenInstancePorts: true
 WhitespaceSensitiveMacros:
   - BOOST_PP_STRINGIZE
   - CF_SWIFT_NAME
   - NS_SWIFT_NAME
   - PP_STRINGIZE
   - STRINGIZE
+WrapNamespaceBodyWithEmptyLines: Leave
 ...
 

+ 13 - 0
.github/workflows/cmake.yml

@@ -20,7 +20,20 @@ on:
   workflow_dispatch:
 
 jobs:
+  formatting:
+    name: Formatting check
+    runs-on: ubuntu-latest
+    steps:
+      - uses: actions/checkout@v4
+      - name: Run clang-format style check for C/C++ programs.
+        uses: jidicula/clang-format-action@v4.16.0
+        with:
+          check-path: "src"
+          exclude-regex: "(src/External)"
+      - run: echo "Formatted with clang-format version ${{ steps.clang-format.outputs.clang-format-version }}"
+
   tests:
+    needs: formatting
     env:
       BUILD_TYPE: Release
 

+ 16 - 12
src/Steam/FileSystem/FileSystem.cpp

@@ -23,13 +23,15 @@ std::vector<std::string> workshopDirectoryPaths = {
 std::filesystem::path detectHomepath () {
     char* home = getenv ("HOME");
 
-    if (home == nullptr)
-        sLog.exception ("Cannot find home directory for the current user");
+    if (home == nullptr) {
+	sLog.exception ("Cannot find home directory for the current user");
+    }
 
     const std::filesystem::path path = home;
 
-    if (!std::filesystem::is_directory (path))
-        sLog.exception ("Cannot find home directory for current user, ", home, " is not a directory");
+    if (!std::filesystem::is_directory (path)) {
+	sLog.exception ("Cannot find home directory for current user, ", home, " is not a directory");
+    }
 
     return path;
 }
@@ -38,12 +40,13 @@ std::filesystem::path Steam::FileSystem::workshopDirectory (int appID, const std
     auto homepath = detectHomepath ();
 
     for (const auto& current : workshopDirectoryPaths) {
-        auto currentpath = std::filesystem::path (homepath) / current / std::to_string (appID) / contentID;
+	auto currentpath = std::filesystem::path (homepath) / current / std::to_string (appID) / contentID;
 
-        if (!std::filesystem::exists (currentpath) || !std::filesystem::is_directory (currentpath))
-            continue;
+	if (!std::filesystem::exists (currentpath) || !std::filesystem::is_directory (currentpath)) {
+	    continue;
+	}
 
-        return currentpath;
+	return currentpath;
     }
 
     sLog.exception ("Cannot find workshop directory for steam app ", appID, " and content ", contentID);
@@ -53,12 +56,13 @@ std::filesystem::path Steam::FileSystem::appDirectory (const std::string& appDir
     auto homepath = detectHomepath ();
 
     for (const auto& current : appDirectoryPaths) {
-        auto currentpath = std::filesystem::path (homepath) / current / appDirectory / path;
+	auto currentpath = std::filesystem::path (homepath) / current / appDirectory / path;
 
-        if (!std::filesystem::exists (currentpath) || !std::filesystem::is_directory (currentpath))
-            continue;
+	if (!std::filesystem::exists (currentpath) || !std::filesystem::is_directory (currentpath)) {
+	    continue;
+	}
 
-        return currentpath;
+	return currentpath;
     }
 
     sLog.exception ("Cannot find directory for steam app ", appDirectory, ": ", path);

+ 406 - 398
src/WallpaperEngine/Application/ApplicationContext.cpp

@@ -1,8 +1,8 @@
 #include "ApplicationContext.h"
 
 #include "Steam/FileSystem/FileSystem.h"
-#include "WallpaperEngine/Logging/Log.h"
 #include "WallpaperEngine/Data/JSON.h"
+#include "WallpaperEngine/Logging/Log.h"
 
 #include <algorithm>
 #include <cstdlib>
@@ -20,59 +20,63 @@ using namespace WallpaperEngine::Application;
 using WallpaperEngine::Data::JSON::JSON;
 
 std::filesystem::path ApplicationContext::resolvePlaylistItemPath (const std::string& raw) const {
-    if (raw.empty ())
-        return {};
+    if (raw.empty ()) {
+	return {};
+    }
 
     std::string cleaned = raw;
 
-    
-
     constexpr std::string_view windowsPrefix = "\\\\?\\";
 
-    if (cleaned.rfind (windowsPrefix, 0) == 0)
-        cleaned = cleaned.substr (windowsPrefix.length ());
+    if (cleaned.rfind (windowsPrefix, 0) == 0) {
+	cleaned = cleaned.substr (windowsPrefix.length ());
+    }
 
     std::replace (cleaned.begin (), cleaned.end (), '\\', '/');
 
-    if (cleaned.size () > 1 && cleaned[1] == ':')
-        cleaned = cleaned.substr (2);
+    if (cleaned.size () > 1 && cleaned[1] == ':') {
+	cleaned = cleaned.substr (2);
+    }
 
-    if (!cleaned.empty () && cleaned.front () != '/')
-        cleaned.insert (cleaned.begin (), '/');
+    if (!cleaned.empty () && cleaned.front () != '/') {
+	cleaned.insert (cleaned.begin (), '/');
+    }
 
     std::filesystem::path path = std::filesystem::path (cleaned).lexically_normal ();
 
-    if (std::filesystem::is_regular_file (path))
-        path = path.parent_path ();
+    if (std::filesystem::is_regular_file (path)) {
+	path = path.parent_path ();
+    }
 
     return path;
 }
 
 std::filesystem::path ApplicationContext::configFilePath () const {
     try {
-        return Steam::FileSystem::appDirectory (APP_DIRECTORY, "") / "config.json";
+	return Steam::FileSystem::appDirectory (APP_DIRECTORY, "") / "config.json";
     } catch (std::runtime_error&) {
-        sLog.exception ("Cannot locate wallpaper engine installation to read config.json");
-        return {};
+	sLog.exception ("Cannot locate wallpaper engine installation to read config.json");
+	return {};
     }
 }
 
 std::optional<JSON> ApplicationContext::parseConfigJson (const std::filesystem::path& path) const {
-    if (path.empty ())
-        return std::nullopt;
+    if (path.empty ()) {
+	return std::nullopt;
+    }
 
     std::ifstream configFile (path);
 
     if (!configFile.is_open ()) {
-        sLog.exception ("Cannot open wallpaper engine config file at ", path);
-        return std::nullopt;
+	sLog.exception ("Cannot open wallpaper engine config file at ", path);
+	return std::nullopt;
     }
 
     try {
-        return JSON::parse (configFile);
+	return JSON::parse (configFile);
     } catch (const std::exception& e) {
-        sLog.error ("Failed parsing wallpaper engine config.json: ", e.what ());
-        return std::nullopt;
+	sLog.error ("Failed parsing wallpaper engine config.json: ", e.what ());
+	return std::nullopt;
     }
 }
 
@@ -81,19 +85,20 @@ ApplicationContext::buildPlaylistDefinition (const JSON& playlistJson, const std
     PlaylistDefinition definition;
     definition.name = playlistJson.optional<std::string> ("name", fallbackName);
     definition.settings = this->parsePlaylistSettings (playlistJson);
-    definition.items = this->collectPlaylistItems (playlistJson, definition.name.empty () ? fallbackName : definition.name);
+    definition.items
+	= this->collectPlaylistItems (playlistJson, definition.name.empty () ? fallbackName : definition.name);
 
     if (definition.items.empty ()) {
-        return std::nullopt;
+	return std::nullopt;
     }
 
     if (definition.name.empty ()) {
-        if (fallbackName.empty ()) {
-            sLog.error ("Skipping playlist with no name");
-            return std::nullopt;
-        }
+	if (fallbackName.empty ()) {
+	    sLog.error ("Skipping playlist with no name");
+	    return std::nullopt;
+	}
 
-        definition.name = fallbackName;
+	definition.name = fallbackName;
     }
 
     return definition;
@@ -116,29 +121,31 @@ ApplicationContext::collectPlaylistItems (const JSON& playlistJson, const std::s
     const auto jsonItems = playlistJson.optional ("items");
 
     if (!jsonItems.has_value () || !jsonItems->is_array ()) {
-        sLog.error ("Skipping playlist ", name, ": missing items");
-        return items;
+	sLog.error ("Skipping playlist ", name, ": missing items");
+	return items;
     }
 
     for (const auto& rawItem : *jsonItems) {
-        if (!rawItem.is_string ())
-            continue;
+	if (!rawItem.is_string ()) {
+	    continue;
+	}
 
-        auto resolvedPath = this->resolvePlaylistItemPath (rawItem.get<std::string> ());
+	auto resolvedPath = this->resolvePlaylistItemPath (rawItem.get<std::string> ());
 
-        if (resolvedPath.empty ())
-            continue;
+	if (resolvedPath.empty ()) {
+	    continue;
+	}
 
-        if (!std::filesystem::exists (resolvedPath)) {
-            sLog.error ("Skipping playlist item not found: ", resolvedPath.string ());
-            continue;
-        }
+	if (!std::filesystem::exists (resolvedPath)) {
+	    sLog.error ("Skipping playlist item not found: ", resolvedPath.string ());
+	    continue;
+	}
 
-        items.push_back (resolvedPath);
+	items.push_back (resolvedPath);
     }
 
     if (items.empty ()) {
-        sLog.error ("Skipping playlist ", name, ": no usable items found");
+	sLog.error ("Skipping playlist ", name, ": no usable items found");
     }
 
     return items;
@@ -149,89 +156,90 @@ void ApplicationContext::registerPlaylist (PlaylistDefinition&& definition) {
 }
 
 void ApplicationContext::loadPlaylistsFromConfig () {
-    if (this->m_loadedConfigPlaylists)
-        return;
+    if (this->m_loadedConfigPlaylists) {
+	return;
+    }
 
     this->m_loadedConfigPlaylists = true;
 
     const auto configPath = this->configFilePath ();
     const auto root = this->parseConfigJson (configPath);
-    if (!root.has_value ())
-        return;
+    if (!root.has_value ()) {
+	return;
+    }
 
     const auto steamUser = root->optional ("steamuser");
 
     if (!steamUser.has_value ()) {
-        sLog.exception ("Cannot find steamuser section in config.json");
+	sLog.exception ("Cannot find steamuser section in config.json");
     }
 
-    auto addPlaylist = [this](const JSON& playlistJson, const std::string& fallbackName) {
-        auto definition = this->buildPlaylistDefinition (playlistJson, fallbackName);
-        if (!definition)
-            return;
-        this->registerPlaylist (std::move (*definition));
+    auto addPlaylist = [this] (const JSON& playlistJson, const std::string& fallbackName) {
+	auto definition = this->buildPlaylistDefinition (playlistJson, fallbackName);
+	if (!definition) {
+	    return;
+	}
+	this->registerPlaylist (std::move (*definition));
     };
 
     if (const auto general = steamUser->optional ("general")) {
-        if (const auto playlists = general->optional ("playlists")) {
-            for (const auto& playlist : *playlists) {
-                try {
-                    addPlaylist (playlist, playlist.optional<std::string> ("name", ""));
-                } catch (const std::exception& e) {
-                    sLog.error ("Failed parsing playlist: ", e.what ());
-                }
-            }
-        }
+	if (const auto playlists = general->optional ("playlists")) {
+	    for (const auto& playlist : *playlists) {
+		try {
+		    addPlaylist (playlist, playlist.optional<std::string> ("name", ""));
+		} catch (const std::exception& e) {
+		    sLog.error ("Failed parsing playlist: ", e.what ());
+		}
+	    }
+	}
     }
 
     if (const auto wallpaperConfig = steamUser->optional ("wallpaperconfig")) {
-        if (const auto selected = wallpaperConfig->optional ("selectedwallpapers")) {
-            for (const auto& entry : selected->items ()) {
-                const auto playlist = entry.value ().optional ("playlist");
-
-                if (!playlist.has_value ())
-                    continue;
-
-                try {
-                    addPlaylist (*playlist, entry.key ());
-                } catch (const std::exception& e) {
-                    sLog.error ("Failed parsing playlist for ", entry.key (), ": ", e.what ());
-                }
-            }
-        }
+	if (const auto selected = wallpaperConfig->optional ("selectedwallpapers")) {
+	    for (const auto& entry : selected->items ()) {
+		const auto playlist = entry.value ().optional ("playlist");
+
+		if (!playlist.has_value ()) {
+		    continue;
+		}
+
+		try {
+		    addPlaylist (*playlist, entry.key ());
+		} catch (const std::exception& e) {
+		    sLog.error ("Failed parsing playlist for ", entry.key (), ": ", e.what ());
+		}
+	    }
+	}
     }
 }
 
-const ApplicationContext::PlaylistDefinition&
-ApplicationContext::getPlaylistFromConfig (const std::string& name) {
+const ApplicationContext::PlaylistDefinition& ApplicationContext::getPlaylistFromConfig (const std::string& name) {
     if (!this->m_loadedConfigPlaylists) {
-        this->loadPlaylistsFromConfig ();
+	this->loadPlaylistsFromConfig ();
     }
 
     const auto cur = this->m_configPlaylists.find (name);
 
     if (cur == this->m_configPlaylists.end ()) {
-        std::string available;
+	std::string available;
 
-        for (auto it = this->m_configPlaylists.begin (); it != this->m_configPlaylists.end (); ++it) {
-            available += it->first;
-            if (std::next (it) != this->m_configPlaylists.end ())
-                available += ", ";
-        }
+	for (auto it = this->m_configPlaylists.begin (); it != this->m_configPlaylists.end (); ++it) {
+	    available += it->first;
+	    if (std::next (it) != this->m_configPlaylists.end ()) {
+		available += ", ";
+	    }
+	}
 
-        const std::string availableText = available.empty () ? "" : std::string (". Available: ") + available;
+	const std::string availableText = available.empty () ? "" : std::string (". Available: ") + available;
 
-        sLog.exception ("Playlist not found in config.json: ", name, availableText);
-        throw std::runtime_error ("Playlist not found: " + name);
+	sLog.exception ("Playlist not found in config.json: ", name, availableText);
+	throw std::runtime_error ("Playlist not found: " + name);
     }
 
     return cur->second;
 }
 
-ApplicationContext::ApplicationContext (int argc, char* argv []) :
-    m_argc (argc),
-    m_argv (argv) {
-}
+ApplicationContext::ApplicationContext (int argc, char* argv[]) : m_argc (argc), m_argv (argv) { }
 
 void ApplicationContext::loadSettingsFromArgv () {
     std::string lastScreen;
@@ -239,368 +247,368 @@ void ApplicationContext::loadSettingsFromArgv () {
     argparse::ArgumentParser program ("linux-wallpaperengine", "0.0", argparse::default_arguments::help);
 
     auto& backgroundGroup = program.add_group ("Background options");
-        auto& backgroundMode = backgroundGroup.add_mutually_exclusive_group (false);
-
-        backgroundGroup.add_argument ("background id")
-            .help ("The background to use as default for screens with no background specified")
-            .default_value ("")
-            .action([this](const std::string& value) -> void {
-                if (!value.empty()) {
-                    this->settings.general.defaultBackground = translateBackground (value);
-                }
-            });
-
-        backgroundMode.add_argument ("-w", "--window")
-            .help ("Window geometry to use for the given screen")
-            .action ([this](const std::string& value) -> void {
-                if (this->settings.render.mode == DESKTOP_BACKGROUND) {
-                    sLog.exception ("Cannot run in both background and window mode");
-                }
-                if (this->settings.render.mode == EXPLICIT_WINDOW) {
-                    sLog.exception ("Only one window at a time can be specified in explicit window mode");
-                }
-
-                this->settings.render.mode = EXPLICIT_WINDOW;
-
-                if (value.empty ()) {
-                    sLog.exception ("Window geometry cannot be empty");
-                }
-
-                const char* str = value.c_str ();
-                const char* delim1 = strchr (str, 'x');
-                const char* delim2 = delim1 ? strchr (delim1 + 1, 'x') : nullptr;
-                const char* delim3 = delim2 ? strchr (delim2 + 1, 'x') : nullptr;
-
-                if (delim1 == nullptr || delim2 == nullptr || delim3 == nullptr) {
-                    sLog.exception ("Window geometry must be in the format: XxYxWxH");
-                }
-
-                this->settings.render.window.geometry.x = strtol(str, nullptr, 10);
-                this->settings.render.window.geometry.y = strtol (delim1 + 1, nullptr, 10);
-                this->settings.render.window.geometry.z = strtol (delim2 + 1, nullptr, 10);
-                this->settings.render.window.geometry.w = strtol (delim3 + 1, nullptr, 10);
-            })
-            .append ();
-        backgroundMode.add_argument ("-r", "--screen-root")
-            .help ("The screen the following settings will have an effect on")
-            .action([this, &lastScreen](const std::string& value) -> void {
-                if (this->settings.general.screenBackgrounds.find (value) != this->settings.general.screenBackgrounds.end ()) {
-                    sLog.exception ("Cannot specify the same screen more than once: ", value);
-                }
-                if (this->settings.render.mode == EXPLICIT_WINDOW) {
-                    sLog.exception ("Cannot run in both background and window mode");
-                }
-
-                this->settings.render.mode = DESKTOP_BACKGROUND;
-                lastScreen = value;
-                this->settings.general.screenBackgrounds [lastScreen] = "";
-                this->settings.general.screenScalings [lastScreen] = this->settings.render.window.scalingMode;
-                this->settings.general.screenClamps [lastScreen] = this->settings.render.window.clamp;
-            })
-            .append ();
-        backgroundGroup.add_argument ("-b", "--bg")
-            .help ("After --screen-root, specifies the background to use for the given screen")
-            .action ([this, &lastScreen](const std::string& value) -> void {
-                this->settings.general.screenBackgrounds [lastScreen] = translateBackground (value);
-                // set the default background to the last one used
-                this->settings.general.defaultBackground = translateBackground (value);
-            })
-            .append ();
-        backgroundGroup.add_argument ("--playlist")
-            .help ("Uses a playlist from wallpaper engine's config.json. If used after --screen-root it is applied to that screen, otherwise it is used in window mode.")
-            .action ([this, &lastScreen](const std::string& value) -> void {
-                const auto& playlist = this->getPlaylistFromConfig (value);
-
-                if (lastScreen.empty ()) {
-                    this->settings.general.defaultPlaylist = playlist;
-                    if (this->settings.general.defaultBackground.empty () && !playlist.items.empty ()) {
-                        this->settings.general.defaultBackground = playlist.items.front ();
-                    }
-                } else {
-                    this->settings.general.screenPlaylists [lastScreen] = playlist;
-                    if (!playlist.items.empty ()) {
-                        this->settings.general.screenBackgrounds [lastScreen] = playlist.items.front ();
-                    }
-
-                    if (this->settings.general.defaultBackground.empty () && !playlist.items.empty ()) {
-                        this->settings.general.defaultBackground = playlist.items.front ();
-                    }
-                }
-            })
-            .append ();
-        backgroundGroup.add_argument ("--scaling")
-            .help ("Scaling mode to use when rendering the background, this applies to the previous --window or --screen-root output, or the default background if no other background is specified")
-            .choices ("stretch", "fit", "fill", "default")
-            .action([this, &lastScreen](const std::string& value) -> void {
-                WallpaperEngine::Render::WallpaperState::TextureUVsScaling mode;
-
-                if (value == "stretch") {
-                    mode = WallpaperEngine::Render::WallpaperState::TextureUVsScaling::StretchUVs;
-                } else if (value == "fit") {
-                    mode = WallpaperEngine::Render::WallpaperState::TextureUVsScaling::ZoomFitUVs;
-                } else if (value == "fill") {
-                    mode = WallpaperEngine::Render::WallpaperState::TextureUVsScaling::ZoomFillUVs;
-                } else if (value == "default") {
-                    mode = WallpaperEngine::Render::WallpaperState::TextureUVsScaling::DefaultUVs;
-                } else {
-                    sLog.exception ("Invalid scaling mode: ", value);
-                }
-
-                if (this->settings.render.mode == DESKTOP_BACKGROUND) {
-                    this->settings.general.screenScalings [lastScreen] = mode;
-                } else {
-                    this->settings.render.window.scalingMode = mode;
-                }
-            })
-            .append ();
-        backgroundGroup.add_argument ("--clamp")
-            .help ("Clamp mode to use when rendering the background, this applies to the previous --window or --screen-root output, or the default background if no other background is specified")
-            .choices("clamp", "border", "repeat")
-            .action([this, &lastScreen](const std::string& value) -> void {
-                TextureFlags flags;
-
-                if (value == "clamp") {
-                    flags = TextureFlags_ClampUVs;
-                } else if (value == "border") {
-                    flags = TextureFlags_ClampUVsBorder;
-                } else if (value == "repeat") {
-                    flags = TextureFlags_NoFlags;
-                } else {
-                    sLog.exception ("Invalid clamp mode: ", value);
-                }
-
-                if (this->settings.render.mode == DESKTOP_BACKGROUND) {
-                    this->settings.general.screenClamps [lastScreen] = flags;
-                } else {
-                    this->settings.render.window.clamp = flags;
-                }
-            });
+    auto& backgroundMode = backgroundGroup.add_mutually_exclusive_group (false);
+
+    backgroundGroup.add_argument ("background id")
+	.help ("The background to use as default for screens with no background specified")
+	.default_value ("")
+	.action ([this] (const std::string& value) -> void {
+	    if (!value.empty ()) {
+		this->settings.general.defaultBackground = translateBackground (value);
+	    }
+	});
+
+    backgroundMode.add_argument ("-w", "--window")
+	.help ("Window geometry to use for the given screen")
+	.action ([this] (const std::string& value) -> void {
+	    if (this->settings.render.mode == DESKTOP_BACKGROUND) {
+		sLog.exception ("Cannot run in both background and window mode");
+	    }
+	    if (this->settings.render.mode == EXPLICIT_WINDOW) {
+		sLog.exception ("Only one window at a time can be specified in explicit window mode");
+	    }
+
+	    this->settings.render.mode = EXPLICIT_WINDOW;
+
+	    if (value.empty ()) {
+		sLog.exception ("Window geometry cannot be empty");
+	    }
+
+	    const char* str = value.c_str ();
+	    const char* delim1 = strchr (str, 'x');
+	    const char* delim2 = delim1 ? strchr (delim1 + 1, 'x') : nullptr;
+	    const char* delim3 = delim2 ? strchr (delim2 + 1, 'x') : nullptr;
+
+	    if (delim1 == nullptr || delim2 == nullptr || delim3 == nullptr) {
+		sLog.exception ("Window geometry must be in the format: XxYxWxH");
+	    }
+
+	    this->settings.render.window.geometry.x = strtol (str, nullptr, 10);
+	    this->settings.render.window.geometry.y = strtol (delim1 + 1, nullptr, 10);
+	    this->settings.render.window.geometry.z = strtol (delim2 + 1, nullptr, 10);
+	    this->settings.render.window.geometry.w = strtol (delim3 + 1, nullptr, 10);
+	})
+	.append ();
+    backgroundMode.add_argument ("-r", "--screen-root")
+	.help ("The screen the following settings will have an effect on")
+	.action ([this, &lastScreen] (const std::string& value) -> void {
+	    if (this->settings.general.screenBackgrounds.find (value)
+		!= this->settings.general.screenBackgrounds.end ()) {
+		sLog.exception ("Cannot specify the same screen more than once: ", value);
+	    }
+	    if (this->settings.render.mode == EXPLICIT_WINDOW) {
+		sLog.exception ("Cannot run in both background and window mode");
+	    }
+
+	    this->settings.render.mode = DESKTOP_BACKGROUND;
+	    lastScreen = value;
+	    this->settings.general.screenBackgrounds[lastScreen] = "";
+	    this->settings.general.screenScalings[lastScreen] = this->settings.render.window.scalingMode;
+	    this->settings.general.screenClamps[lastScreen] = this->settings.render.window.clamp;
+	})
+	.append ();
+    backgroundGroup.add_argument ("-b", "--bg")
+	.help ("After --screen-root, specifies the background to use for the given screen")
+	.action ([this, &lastScreen] (const std::string& value) -> void {
+	    this->settings.general.screenBackgrounds[lastScreen] = translateBackground (value);
+	    // set the default background to the last one used
+	    this->settings.general.defaultBackground = translateBackground (value);
+	})
+	.append ();
+    backgroundGroup.add_argument ("--playlist")
+	.help (
+	    "Uses a playlist from wallpaper engine's config.json. If used after --screen-root it is applied to that "
+	    "screen, otherwise it is used in window mode."
+	)
+	.action ([this, &lastScreen] (const std::string& value) -> void {
+	    const auto& playlist = this->getPlaylistFromConfig (value);
+
+	    if (lastScreen.empty ()) {
+		this->settings.general.defaultPlaylist = playlist;
+		if (this->settings.general.defaultBackground.empty () && !playlist.items.empty ()) {
+		    this->settings.general.defaultBackground = playlist.items.front ();
+		}
+	    } else {
+		this->settings.general.screenPlaylists[lastScreen] = playlist;
+		if (!playlist.items.empty ()) {
+		    this->settings.general.screenBackgrounds[lastScreen] = playlist.items.front ();
+		}
+
+		if (this->settings.general.defaultBackground.empty () && !playlist.items.empty ()) {
+		    this->settings.general.defaultBackground = playlist.items.front ();
+		}
+	    }
+	})
+	.append ();
+    backgroundGroup.add_argument ("--scaling")
+	.help (
+	    "Scaling mode to use when rendering the background, this applies to the previous --window or --screen-root "
+	    "output, or the default background if no other background is specified"
+	)
+	.choices ("stretch", "fit", "fill", "default")
+	.action ([this, &lastScreen] (const std::string& value) -> void {
+	    WallpaperEngine::Render::WallpaperState::TextureUVsScaling mode;
+
+	    if (value == "stretch") {
+		mode = WallpaperEngine::Render::WallpaperState::TextureUVsScaling::StretchUVs;
+	    } else if (value == "fit") {
+		mode = WallpaperEngine::Render::WallpaperState::TextureUVsScaling::ZoomFitUVs;
+	    } else if (value == "fill") {
+		mode = WallpaperEngine::Render::WallpaperState::TextureUVsScaling::ZoomFillUVs;
+	    } else if (value == "default") {
+		mode = WallpaperEngine::Render::WallpaperState::TextureUVsScaling::DefaultUVs;
+	    } else {
+		sLog.exception ("Invalid scaling mode: ", value);
+	    }
+
+	    if (this->settings.render.mode == DESKTOP_BACKGROUND) {
+		this->settings.general.screenScalings[lastScreen] = mode;
+	    } else {
+		this->settings.render.window.scalingMode = mode;
+	    }
+	})
+	.append ();
+    backgroundGroup.add_argument ("--clamp")
+	.help (
+	    "Clamp mode to use when rendering the background, this applies to the previous --window or --screen-root "
+	    "output, or the default background if no other background is specified"
+	)
+	.choices ("clamp", "border", "repeat")
+	.action ([this, &lastScreen] (const std::string& value) -> void {
+	    TextureFlags flags;
+
+	    if (value == "clamp") {
+		flags = TextureFlags_ClampUVs;
+	    } else if (value == "border") {
+		flags = TextureFlags_ClampUVsBorder;
+	    } else if (value == "repeat") {
+		flags = TextureFlags_NoFlags;
+	    } else {
+		sLog.exception ("Invalid clamp mode: ", value);
+	    }
+
+	    if (this->settings.render.mode == DESKTOP_BACKGROUND) {
+		this->settings.general.screenClamps[lastScreen] = flags;
+	    } else {
+		this->settings.render.window.clamp = flags;
+	    }
+	});
 
     auto& performanceGroup = program.add_group ("Performance options");
 
-        performanceGroup.add_argument ("-f", "--fps")
-            .help ("Limits the FPS to the given number, useful to keep battery consumption low")
-            .default_value (30)
-            .store_into(this->settings.render.maximumFPS);
-
-        performanceGroup.add_argument ("--no-fullscreen-pause")
-            .help ("Prevents the background pausing when an app is fullscreen")
-            .flag ()
-            .action ([this](const std::string& value) -> void {
-                this->settings.render.pauseOnFullscreen = false;
-            });
-
-        performanceGroup.add_argument ("--fullscreen-pause-only-active")
-            .help ("Wayland only: pause only when a fullscreen window is active (activated)")
-            .flag ()
-            .action ([this](const std::string& value) -> void {
-                this->settings.render.pauseOnFullscreenOnlyWhenActive = true;
-            });
-
-        performanceGroup.add_argument ("--fullscreen-pause-ignore-appid")
-            .help ("Wayland only: ignore fullscreen windows whose app_id contains this value (repeatable)")
-            .action ([this](const std::string& value) -> void {
-                if (!value.empty ()) {
-                    this->settings.render.fullscreenPauseIgnoreAppIds.push_back (value);
-                }
-            })
-            .append ();
+    performanceGroup.add_argument ("-f", "--fps")
+	.help ("Limits the FPS to the given number, useful to keep battery consumption low")
+	.default_value (30)
+	.store_into (this->settings.render.maximumFPS);
+
+    performanceGroup.add_argument ("--no-fullscreen-pause")
+	.help ("Prevents the background pausing when an app is fullscreen")
+	.flag ()
+	.action ([this] (const std::string& value) -> void { this->settings.render.pauseOnFullscreen = false; });
+
+    performanceGroup.add_argument ("--fullscreen-pause-only-active")
+	.help ("Wayland only: pause only when a fullscreen window is active (activated)")
+	.flag ()
+	.action ([this] (const std::string& value) -> void {
+	    this->settings.render.pauseOnFullscreenOnlyWhenActive = true;
+	});
+
+    performanceGroup.add_argument ("--fullscreen-pause-ignore-appid")
+	.help ("Wayland only: ignore fullscreen windows whose app_id contains this value (repeatable)")
+	.action ([this] (const std::string& value) -> void {
+	    if (!value.empty ()) {
+		this->settings.render.fullscreenPauseIgnoreAppIds.push_back (value);
+	    }
+	})
+	.append ();
 
     auto& audioGroup = program.add_group ("Sound settings");
     auto& audioSettingsGroup = audioGroup.add_mutually_exclusive_group (false);
 
-        audioSettingsGroup.add_argument ("-v", "--volume")
-            .help ("Volume for all the sounds in the background")
-            .default_value (15)
-            .store_into (this->settings.audio.volume);
-
-        audioSettingsGroup.add_argument ("-s", "--silent")
-            .help ("Mutes all the sound the wallpaper might produce")
-            .flag ()
-            .action ([this](const std::string& value) -> void {
-                this->settings.audio.enabled = false;
-            });
-
-        audioGroup.add_argument ("--noautomute")
-            .help ("Disables the automute when an app is playing sound")
-            .flag ()
-            .action([this](const std::string& value) -> void {
-                this->settings.audio.automute = false;
-            });
-
-        audioGroup.add_argument ("--no-audio-processing")
-            .help ("Disables audio processing for backgrounds")
-            .flag ()
-            .action ([this](const std::string& value) -> void {
-                this->settings.audio.audioprocessing = false;
-            });
+    audioSettingsGroup.add_argument ("-v", "--volume")
+	.help ("Volume for all the sounds in the background")
+	.default_value (15)
+	.store_into (this->settings.audio.volume);
+
+    audioSettingsGroup.add_argument ("-s", "--silent")
+	.help ("Mutes all the sound the wallpaper might produce")
+	.flag ()
+	.action ([this] (const std::string& value) -> void { this->settings.audio.enabled = false; });
+
+    audioGroup.add_argument ("--noautomute")
+	.help ("Disables the automute when an app is playing sound")
+	.flag ()
+	.action ([this] (const std::string& value) -> void { this->settings.audio.automute = false; });
+
+    audioGroup.add_argument ("--no-audio-processing")
+	.help ("Disables audio processing for backgrounds")
+	.flag ()
+	.action ([this] (const std::string& value) -> void { this->settings.audio.audioprocessing = false; });
 
     auto& screenshotGroup = program.add_group ("Screenshot options");
 
-        screenshotGroup.add_argument ("--screenshot")
-            .help ("Takes a screenshot of the background for it's use with tools like PyWAL")
-            .default_value ("")
-            .action ([this](const std::string& value) -> void {
-                this->settings.screenshot.take = true;
-                this->settings.screenshot.path = value;
-            });
+    screenshotGroup.add_argument ("--screenshot")
+	.help ("Takes a screenshot of the background for it's use with tools like PyWAL")
+	.default_value ("")
+	.action ([this] (const std::string& value) -> void {
+	    this->settings.screenshot.take = true;
+	    this->settings.screenshot.path = value;
+	});
 
-        screenshotGroup.add_argument ("--screenshot-delay")
-            .help ("Frames to wait before taking the screenshot")
-            .default_value <uint32_t> (5)
-            .store_into (this->settings.screenshot.delay);
+    screenshotGroup.add_argument ("--screenshot-delay")
+	.help ("Frames to wait before taking the screenshot")
+	.default_value<uint32_t> (5)
+	.store_into (this->settings.screenshot.delay);
 
     auto& contentGroup = program.add_group ("Content options");
 
-        contentGroup.add_argument ("--assets-dir")
-            .help ("Folder where the assets are stored")
-            .default_value ("")
-            .action ([this](const std::string& value) -> void {
-                this->settings.general.assets = value;
-            });
+    contentGroup.add_argument ("--assets-dir")
+	.help ("Folder where the assets are stored")
+	.default_value ("")
+	.action ([this] (const std::string& value) -> void { this->settings.general.assets = value; });
 
     auto& configurationGroup = program.add_group ("Wallpaper configuration options");
 
-        configurationGroup.add_argument ("--disable-particles")
-            .help ("Disables particles for the backgrounds")
-            .flag()
-            .action([this](const std::string& value) -> void {
-                this->settings.general.disableParticles = true;
-            });
-
-        configurationGroup.add_argument ("--disable-mouse")
-            .help ("Disables mouse interaction with the backgrounds")
-            .flag ()
-            .action ([this](const std::string& value) -> void {
-                this->settings.mouse.enabled = false;
-            });
-        configurationGroup.add_argument ("--disable-parallax")
-            .help ("Disables parallax effect for the backgrounds")
-            .flag ()
-            .action ([this](const std::string& value) -> void {
-                this->settings.mouse.disableparallax = true;
-            });
-
-        configurationGroup.add_argument ("-l", "--list-properties")
-            .help ("List all the available properties and their configuration")
-            .flag ()
-            .store_into (this->settings.general.onlyListProperties);
-
-        configurationGroup.add_argument ("--set-property", "--property")
-            .help ("Overrides the default value of the given property")
-            .action([this](const std::string& value) -> void {
-                const std::string::size_type equals = value.find ('=');
-
-                // properties without value are treated as booleans for now
-                if (equals == std::string::npos)
-                    this->settings.general.properties [value] = "1";
-                else
-                    this->settings.general.properties [value.substr (0, equals)] = value.substr (equals + 1);
-            })
-            .append ();
+    configurationGroup.add_argument ("--disable-particles")
+	.help ("Disables particles for the backgrounds")
+	.flag ()
+	.action ([this] (const std::string& value) -> void { this->settings.general.disableParticles = true; });
+
+    configurationGroup.add_argument ("--disable-mouse")
+	.help ("Disables mouse interaction with the backgrounds")
+	.flag ()
+	.action ([this] (const std::string& value) -> void { this->settings.mouse.enabled = false; });
+    configurationGroup.add_argument ("--disable-parallax")
+	.help ("Disables parallax effect for the backgrounds")
+	.flag ()
+	.action ([this] (const std::string& value) -> void { this->settings.mouse.disableparallax = true; });
+
+    configurationGroup.add_argument ("-l", "--list-properties")
+	.help ("List all the available properties and their configuration")
+	.flag ()
+	.store_into (this->settings.general.onlyListProperties);
+
+    configurationGroup.add_argument ("--set-property", "--property")
+	.help ("Overrides the default value of the given property")
+	.action ([this] (const std::string& value) -> void {
+	    const std::string::size_type equals = value.find ('=');
+
+	    // properties without value are treated as booleans for now
+	    if (equals == std::string::npos) {
+		this->settings.general.properties[value] = "1";
+	    } else {
+		this->settings.general.properties[value.substr (0, equals)] = value.substr (equals + 1);
+	    }
+	})
+	.append ();
 
     auto& debuggingGroup = program.add_group ("Debugging options");
 
-        debuggingGroup.add_argument ("-z", "--dump-structure")
-            .help ("Dumps the structure of the backgrounds")
-            .flag ()
-            .store_into (this->settings.general.dumpStructure);
+    debuggingGroup.add_argument ("-z", "--dump-structure")
+	.help ("Dumps the structure of the backgrounds")
+	.flag ()
+	.store_into (this->settings.general.dumpStructure);
 
     program.add_epilog (
-        "Usage examples:\n"
-            "  linux-wallpaperengine --screen-root HDMI-1 --bg 2317494988 --scaling fill --clamp border\n"
-            "    Runs the background 2317494988 on screen HDMI-1, scaling it to fill the screen and clamping the UVs to the border\n\n"
-            "  linux-wallpaperengine 2317494988\n"
-            "    Previews the background 2317494988 on a window\n\n"
-            "  linux-wallpaperengine --screen-root HDMI-1 --bg 2317494988 --screen-root HDMI-2 --bg 1108150151\n"
-            "    Runs two backgrounds on two screens, one on HDMI-1 and the other on HDMI-2\n\n"
-            "  linux-wallpaperengine --screen-root HDMI-1 --screen-root HDMI-2 2317494988\n"
-            "    Runs the background 2317494988 on two screens, one on HDMI-1 and the other on HDMI-2\n\n"
+	"Usage examples:\n"
+	"  linux-wallpaperengine --screen-root HDMI-1 --bg 2317494988 --scaling fill --clamp border\n"
+	"    Runs the background 2317494988 on screen HDMI-1, scaling it to fill the screen and clamping the UVs to "
+	"the border\n\n"
+	"  linux-wallpaperengine 2317494988\n"
+	"    Previews the background 2317494988 on a window\n\n"
+	"  linux-wallpaperengine --screen-root HDMI-1 --bg 2317494988 --screen-root HDMI-2 --bg 1108150151\n"
+	"    Runs two backgrounds on two screens, one on HDMI-1 and the other on HDMI-2\n\n"
+	"  linux-wallpaperengine --screen-root HDMI-1 --screen-root HDMI-2 2317494988\n"
+	"    Runs the background 2317494988 on two screens, one on HDMI-1 and the other on HDMI-2\n\n"
     );
 
     try {
-        program.parse_known_args (this->m_argc, this->m_argv);
+	program.parse_known_args (this->m_argc, this->m_argv);
 
-        if (this->settings.general.defaultBackground.empty ()) {
-            throw std::runtime_error ("At least one background ID must be specified");
-        }
+	if (this->settings.general.defaultBackground.empty ()) {
+	    throw std::runtime_error ("At least one background ID must be specified");
+	}
 
-        this->settings.audio.volume = std::max(0, std::min (this->settings.audio.volume, 128));
-        this->settings.screenshot.delay = std::max <uint32_t> (0, std::min <uint32_t> (this->settings.screenshot.delay, 5));
+	this->settings.audio.volume = std::max (0, std::min (this->settings.audio.volume, 128));
+	this->settings.screenshot.delay
+	    = std::max<uint32_t> (0, std::min<uint32_t> (this->settings.screenshot.delay, 5));
 
-        // use std::cout on this in case logging is disabled, this way it's easy to look at what is running
-        std::stringbuf buffer;
-        std::ostream bufferStream (&buffer);
+	// use std::cout on this in case logging is disabled, this way it's easy to look at what is running
+	std::stringbuf buffer;
+	std::ostream bufferStream (&buffer);
 
-        bufferStream << "Running with: ";
+	bufferStream << "Running with: ";
 
-        for (int i = 0; i < this->m_argc; i ++) {
-            bufferStream << this->m_argv [i];
-            bufferStream << " ";
-        }
+	for (int i = 0; i < this->m_argc; i++) {
+	    bufferStream << this->m_argv[i];
+	    bufferStream << " ";
+	}
 
-        std::cout << buffer.str() << std::endl;
-        // perform some extra validation on the inputs
-        this->validateAssets ();
-        this->validateScreenshot ();
+	std::cout << buffer.str () << std::endl;
+	// perform some extra validation on the inputs
+	this->validateAssets ();
+	this->validateScreenshot ();
 
-        // setup application state
-        this->state.general.keepRunning = true;
-        this->state.audio.enabled = this->settings.audio.enabled;
-        this->state.audio.volume = this->settings.audio.volume;
-        this->state.mouse.enabled = this->settings.mouse.enabled;
+	// setup application state
+	this->state.general.keepRunning = true;
+	this->state.audio.enabled = this->settings.audio.enabled;
+	this->state.audio.volume = this->settings.audio.volume;
+	this->state.mouse.enabled = this->settings.mouse.enabled;
 
 #if DEMOMODE
-        sLog.error ("WARNING: RUNNING IN DEMO MODE WILL STOP WALLPAPERS AFTER 5 SECONDS SO VIDEO CAN BE RECORDED");
-        // special settings for demomode
-        this->settings.render.maximumFPS = 30;
-        this->settings.screenshot.take = false;
-        this->settings.render.pauseOnFullscreen = false;
+	sLog.error ("WARNING: RUNNING IN DEMO MODE WILL STOP WALLPAPERS AFTER 5 SECONDS SO VIDEO CAN BE RECORDED");
+	// special settings for demomode
+	this->settings.render.maximumFPS = 30;
+	this->settings.screenshot.take = false;
+	this->settings.render.pauseOnFullscreen = false;
 #endif /* DEMOMODE */
-   } catch (const std::runtime_error& e) {
-       throw std::runtime_error (std::string (e.what()) + ". Use " + std::string (this->m_argv[0]) + " --help for more information");
-   }
+    } catch (const std::runtime_error& e) {
+	throw std::runtime_error (
+	    std::string (e.what ()) + ". Use " + std::string (this->m_argv[0]) + " --help for more information"
+	);
+    }
 }
 
-int ApplicationContext::getArgc () const {
-    return this->m_argc;
-}
+int ApplicationContext::getArgc () const { return this->m_argc; }
 
-char** ApplicationContext::getArgv () const {
-    return this->m_argv;
-}
+char** ApplicationContext::getArgv () const { return this->m_argv; }
 
 std::filesystem::path ApplicationContext::translateBackground (const std::string& bgIdOrPath) {
-    if (bgIdOrPath.find ('/') == std::string::npos)
-        return Steam::FileSystem::workshopDirectory (WORKSHOP_APP_ID, bgIdOrPath);
+    if (bgIdOrPath.find ('/') == std::string::npos) {
+	return Steam::FileSystem::workshopDirectory (WORKSHOP_APP_ID, bgIdOrPath);
+    }
 
     return bgIdOrPath;
 }
 
 void ApplicationContext::validateAssets () {
     if (!this->settings.general.assets.empty ()) {
-        sLog.out ("Using wallpaper engine's assets at ", this->settings.general.assets,
-                  " based on --assets-dir parameter");
-        return;
+	sLog.out (
+	    "Using wallpaper engine's assets at ", this->settings.general.assets, " based on --assets-dir parameter"
+	);
+	return;
     }
 
     try {
-        this->settings.general.assets = Steam::FileSystem::appDirectory (APP_DIRECTORY, "assets");
+	this->settings.general.assets = Steam::FileSystem::appDirectory (APP_DIRECTORY, "assets");
     } catch (std::runtime_error&) {
-        // set current path as assets' folder
-        this->settings.general.assets = std::filesystem::canonical ("/proc/self/exe").parent_path () / "assets";
+	// set current path as assets' folder
+	this->settings.general.assets = std::filesystem::canonical ("/proc/self/exe").parent_path () / "assets";
     }
 }
 
 void ApplicationContext::validateScreenshot () const {
-    if (!this->settings.screenshot.take)
-        return;
+    if (!this->settings.screenshot.take) {
+	return;
+    }
 
-    if (!this->settings.screenshot.path.has_extension ())
-        sLog.exception ("Cannot determine screenshot format");
+    if (!this->settings.screenshot.path.has_extension ()) {
+	sLog.exception ("Cannot determine screenshot format");
+    }
 
     const std::string extension = this->settings.screenshot.path.extension ();
 
-    if (extension != ".bmp" && extension != ".png" && extension != ".jpeg" && extension != ".jpg")
-        sLog.exception ("Cannot determine screenshot format, unknown extension ", extension);
+    if (extension != ".bmp" && extension != ".png" && extension != ".jpeg" && extension != ".jpg") {
+	sLog.exception ("Cannot determine screenshot format, unknown extension ", extension);
+    }
 }

+ 117 - 116
src/WallpaperEngine/Application/ApplicationContext.h

@@ -3,8 +3,8 @@
 #include <cstdint>
 #include <filesystem>
 #include <map>
-#include <string>
 #include <optional>
+#include <string>
 #include <vector>
 
 #include <glm/vec4.hpp>
@@ -23,8 +23,8 @@ using namespace WallpaperEngine::Data::Assets;
  * Application information as parsed off the command line arguments
  */
 class ApplicationContext {
-  public:
-    ApplicationContext (int argc, char* argv []);
+public:
+    ApplicationContext (int argc, char* argv[]);
 
     /**
      * Parses the given argc and argv and builds settings for the app
@@ -32,121 +32,121 @@ class ApplicationContext {
     void loadSettingsFromArgv ();
 
     enum WINDOW_MODE {
-        /** Default window mode */
-        NORMAL_WINDOW = 0,
-        /** Draw to the window server desktop */
-        DESKTOP_BACKGROUND = 1,
-        /** Explicit window mode with specified geometry */
-        EXPLICIT_WINDOW = 2,
+	/** Default window mode */
+	NORMAL_WINDOW = 0,
+	/** Draw to the window server desktop */
+	DESKTOP_BACKGROUND = 1,
+	/** Explicit window mode with specified geometry */
+	EXPLICIT_WINDOW = 2,
     };
 
     struct PlaylistSettings {
-        uint32_t delayMinutes = 60;
-        std::string mode = "timer";
-        std::string order = "sequential";
-        bool updateOnPause = false;
-        bool videoSequence = false;
+	uint32_t delayMinutes = 60;
+	std::string mode = "timer";
+	std::string order = "sequential";
+	bool updateOnPause = false;
+	bool videoSequence = false;
     };
 
     struct PlaylistDefinition {
-        std::string name;
-        std::vector<std::filesystem::path> items;
-        PlaylistSettings settings;
+	std::string name;
+	std::vector<std::filesystem::path> items;
+	PlaylistSettings settings;
     };
 
     struct {
-        /**
-         * General settings
-         */
-        struct {
-            /** If the user requested a list of properties for the given background */
-            bool onlyListProperties;
-            /** If the user requested a dump of the background structure */
-            bool dumpStructure;
-            /** If the user requested the particles to be deactivated */
-            bool disableParticles;
-            /** The path to the assets folder */
-            std::filesystem::path assets;
-            /** Background to load (provided as the final argument) as fallback for multi-screen setups */
-            std::filesystem::path defaultBackground;
-            /** The backgrounds specified for different screens */
-            std::map<std::string, std::filesystem::path> screenBackgrounds;
-            /** Properties to change values for */
-            std::map<std::string, std::string> properties;
-            /** The scaling mode for different screens */
-            std::map<std::string, WallpaperEngine::Render::WallpaperState::TextureUVsScaling> screenScalings;
-            /** The clamping mode for different screens */
-            std::map<std::string, TextureFlags> screenClamps;
-            /** Playlists selected per screen */
-            std::map<std::string, PlaylistDefinition> screenPlaylists;
-            /** Playlist used in window mode */
-            std::optional<PlaylistDefinition> defaultPlaylist;
-        } general;
-
-        /**
-         * Render settings
-         */
-        struct {
-            /** The mode to run the background in */
-            WINDOW_MODE mode;
-            /** Maximum FPS */
-            int maximumFPS;
-            /** Indicates if pausing should happen when something goes fullscreen */
-            bool pauseOnFullscreen;
-            /**
-             * Wayland-only: if true, only consider fullscreen toplevels that are also activated.
-             * Useful for compositors with "virtual" fullscreen windows (e.g. scrollable tiling).
-             */
-            bool pauseOnFullscreenOnlyWhenActive;
-            /**
-             * Wayland-only: list of app_id substrings to ignore for fullscreen pause.
-             * Example: "firefox" will match "org.mozilla.firefox".
-             */
-            std::vector<std::string> fullscreenPauseIgnoreAppIds;
-
-            struct {
-                /** The window size used in explicit window */
-                glm::ivec4 geometry;
-                TextureFlags clamp;
-                WallpaperEngine::Render::WallpaperState::TextureUVsScaling scalingMode;
-            } window;
-        } render;
-
-        /**
-         * Audio settings
-         */
-        struct {
-            /** If the audio system is enabled */
-            bool enabled;
-            /** Sound volume (0-128) */
-            int volume;
-            /** If the audio must be muted if something else is playing sound */
-            bool automute;
-            /** If audio processing can be enabled or not */
-            bool audioprocessing;
-        } audio;
-
-        /**
-         * Mouse input settings
-         */
-        struct {
-            /** If the mouse movement is enabled */
-            bool enabled;
-            /** If the mouse parallax should be disabled */
-            bool disableparallax;
-        } mouse;
-
-        /**
-         * Screenshot settings
-         */
-        struct {
-            /** If an screenshot should be taken */
-            bool take;
-            /** The frames to wait until the screenshot is taken */
-            uint32_t delay;
-            /** The path to where the screenshot must be saved */
-            std::filesystem::path path;
-        } screenshot;
+	/**
+	 * General settings
+	 */
+	struct {
+	    /** If the user requested a list of properties for the given background */
+	    bool onlyListProperties;
+	    /** If the user requested a dump of the background structure */
+	    bool dumpStructure;
+	    /** If the user requested the particles to be deactivated */
+	    bool disableParticles;
+	    /** The path to the assets folder */
+	    std::filesystem::path assets;
+	    /** Background to load (provided as the final argument) as fallback for multi-screen setups */
+	    std::filesystem::path defaultBackground;
+	    /** The backgrounds specified for different screens */
+	    std::map<std::string, std::filesystem::path> screenBackgrounds;
+	    /** Properties to change values for */
+	    std::map<std::string, std::string> properties;
+	    /** The scaling mode for different screens */
+	    std::map<std::string, WallpaperEngine::Render::WallpaperState::TextureUVsScaling> screenScalings;
+	    /** The clamping mode for different screens */
+	    std::map<std::string, TextureFlags> screenClamps;
+	    /** Playlists selected per screen */
+	    std::map<std::string, PlaylistDefinition> screenPlaylists;
+	    /** Playlist used in window mode */
+	    std::optional<PlaylistDefinition> defaultPlaylist;
+	} general;
+
+	/**
+	 * Render settings
+	 */
+	struct {
+	    /** The mode to run the background in */
+	    WINDOW_MODE mode;
+	    /** Maximum FPS */
+	    int maximumFPS;
+	    /** Indicates if pausing should happen when something goes fullscreen */
+	    bool pauseOnFullscreen;
+	    /**
+	     * Wayland-only: if true, only consider fullscreen toplevels that are also activated.
+	     * Useful for compositors with "virtual" fullscreen windows (e.g. scrollable tiling).
+	     */
+	    bool pauseOnFullscreenOnlyWhenActive;
+	    /**
+	     * Wayland-only: list of app_id substrings to ignore for fullscreen pause.
+	     * Example: "firefox" will match "org.mozilla.firefox".
+	     */
+	    std::vector<std::string> fullscreenPauseIgnoreAppIds;
+
+	    struct {
+		/** The window size used in explicit window */
+		glm::ivec4 geometry;
+		TextureFlags clamp;
+		WallpaperEngine::Render::WallpaperState::TextureUVsScaling scalingMode;
+	    } window;
+	} render;
+
+	/**
+	 * Audio settings
+	 */
+	struct {
+	    /** If the audio system is enabled */
+	    bool enabled;
+	    /** Sound volume (0-128) */
+	    int volume;
+	    /** If the audio must be muted if something else is playing sound */
+	    bool automute;
+	    /** If audio processing can be enabled or not */
+	    bool audioprocessing;
+	} audio;
+
+	/**
+	 * Mouse input settings
+	 */
+	struct {
+	    /** If the mouse movement is enabled */
+	    bool enabled;
+	    /** If the mouse parallax should be disabled */
+	    bool disableparallax;
+	} mouse;
+
+	/**
+	 * Screenshot settings
+	 */
+	struct {
+	    /** If an screenshot should be taken */
+	    bool take;
+	    /** The frames to wait until the screenshot is taken */
+	    uint32_t delay;
+	    /** The path to where the screenshot must be saved */
+	    std::filesystem::path path;
+	} screenshot;
     } settings = {
         .general = {
             .onlyListProperties = false,
@@ -191,10 +191,10 @@ class ApplicationContext {
 
     ApplicationState state;
 
-    [[nodiscard]] int getArgc() const;
-    [[nodiscard]] char** getArgv() const;
+    [[nodiscard]] int getArgc () const;
+    [[nodiscard]] char** getArgv () const;
 
-  private:
+private:
     /** Program argument count on startup */
     int m_argc;
     /** Program arguments on startup */
@@ -223,10 +223,11 @@ class ApplicationContext {
     std::filesystem::path configFilePath () const;
     std::optional<WallpaperEngine::Data::JSON::JSON> parseConfigJson (const std::filesystem::path& path) const;
     PlaylistSettings parsePlaylistSettings (const WallpaperEngine::Data::JSON::JSON& playlistJson) const;
-    std::vector<std::filesystem::path> collectPlaylistItems (const WallpaperEngine::Data::JSON::JSON& playlistJson,
-                                                             const std::string& name) const;
-    std::optional<PlaylistDefinition> buildPlaylistDefinition (const WallpaperEngine::Data::JSON::JSON& playlistJson,
-                                                               const std::string& fallbackName) const;
+    std::vector<std::filesystem::path>
+    collectPlaylistItems (const WallpaperEngine::Data::JSON::JSON& playlistJson, const std::string& name) const;
+    std::optional<PlaylistDefinition> buildPlaylistDefinition (
+	const WallpaperEngine::Data::JSON::JSON& playlistJson, const std::string& fallbackName
+    ) const;
     void registerPlaylist (PlaylistDefinition&& definition);
     [[nodiscard]] const PlaylistDefinition& getPlaylistFromConfig (const std::string& name);
 

+ 5 - 5
src/WallpaperEngine/Application/ApplicationState.h

@@ -7,18 +7,18 @@ namespace WallpaperEngine::Application {
  * Represents current application state
  */
 class ApplicationState {
-  public:
+public:
     struct {
-        bool keepRunning;
+	bool keepRunning;
     } general {};
 
     struct {
-        bool enabled;
-        int volume;
+	bool enabled;
+	int volume;
     } audio {};
 
     struct {
-        bool enabled;
+	bool enabled;
     } mouse {};
 };
 } // namespace WallpaperEngine::Application

Файловите разлики са ограничени, защото са твърде много
+ 379 - 426
src/WallpaperEngine/Application/WallpaperApplication.cpp


+ 20 - 19
src/WallpaperEngine/Application/WallpaperApplication.h

@@ -28,7 +28,7 @@ using namespace WallpaperEngine::Data::Model;
  * Small wrapper class over the actual wallpaper's main application skeleton
  */
 class WallpaperApplication {
-  public:
+public:
     explicit WallpaperApplication (ApplicationContext& context);
 
     /**
@@ -58,7 +58,7 @@ class WallpaperApplication {
      */
     [[nodiscard]] const WallpaperEngine::Render::Drivers::Output::Output& getOutput () const;
 
-  private:
+private:
     /**
      * Sets up an asset locator for the given background
      *
@@ -114,18 +114,19 @@ class WallpaperApplication {
     void takeScreenshot (const std::filesystem::path& filename) const;
 
     struct ActivePlaylist {
-        ApplicationContext::PlaylistDefinition definition;
-        std::vector<std::size_t> order;
-        std::size_t orderIndex = 0;
-        std::chrono::steady_clock::time_point nextSwitch;
-        std::chrono::steady_clock::time_point lastUpdate;
-        std::set<std::size_t> failedIndices;
+	ApplicationContext::PlaylistDefinition definition;
+	std::vector<std::size_t> order;
+	std::size_t orderIndex = 0;
+	std::chrono::steady_clock::time_point nextSwitch;
+	std::chrono::steady_clock::time_point lastUpdate;
+	std::set<std::size_t> failedIndices;
     };
 
     void initializePlaylists ();
     void updatePlaylists ();
-    void advancePlaylist (const std::string& screen, ActivePlaylist& playlist,
-                          const std::chrono::steady_clock::time_point& now);
+    void advancePlaylist (
+	const std::string& screen, ActivePlaylist& playlist, const std::chrono::steady_clock::time_point& now
+    );
     bool selectNextCandidate (ActivePlaylist& playlist, std::size_t& outOrderIndex);
     bool preflightWallpaper (const std::string& path);
     std::vector<std::size_t> buildPlaylistOrder (const ApplicationContext::PlaylistDefinition& definition);
@@ -138,15 +139,15 @@ class WallpaperApplication {
     std::map<std::string, ProjectUniquePtr> m_backgrounds {};
     std::map<std::string, ActivePlaylist> m_activePlaylists {};
 
-    std::unique_ptr <WallpaperEngine::Audio::Drivers::Detectors::AudioPlayingDetector> m_audioDetector = nullptr;
-    std::unique_ptr <WallpaperEngine::Audio::AudioContext> m_audioContext = nullptr;
-    std::unique_ptr <WallpaperEngine::Audio::Drivers::SDLAudioDriver> m_audioDriver = nullptr;
-    std::unique_ptr <WallpaperEngine::Audio::Drivers::Recorders::PlaybackRecorder> m_audioRecorder = nullptr;
-    std::unique_ptr <WallpaperEngine::Render::RenderContext> m_renderContext = nullptr;
-    std::unique_ptr <WallpaperEngine::Render::Drivers::VideoDriver> m_videoDriver = nullptr;
-    std::unique_ptr <WallpaperEngine::Render::Drivers::Detectors::FullScreenDetector> m_fullScreenDetector = nullptr;
-    std::unique_ptr <WallpaperEngine::WebBrowser::WebBrowserContext> m_browserContext = nullptr;
-    std::mt19937 m_playlistRng {std::random_device {} ()};
+    std::unique_ptr<WallpaperEngine::Audio::Drivers::Detectors::AudioPlayingDetector> m_audioDetector = nullptr;
+    std::unique_ptr<WallpaperEngine::Audio::AudioContext> m_audioContext = nullptr;
+    std::unique_ptr<WallpaperEngine::Audio::Drivers::SDLAudioDriver> m_audioDriver = nullptr;
+    std::unique_ptr<WallpaperEngine::Audio::Drivers::Recorders::PlaybackRecorder> m_audioRecorder = nullptr;
+    std::unique_ptr<WallpaperEngine::Render::RenderContext> m_renderContext = nullptr;
+    std::unique_ptr<WallpaperEngine::Render::Drivers::VideoDriver> m_videoDriver = nullptr;
+    std::unique_ptr<WallpaperEngine::Render::Drivers::Detectors::FullScreenDetector> m_fullScreenDetector = nullptr;
+    std::unique_ptr<WallpaperEngine::WebBrowser::WebBrowserContext> m_browserContext = nullptr;
+    std::mt19937 m_playlistRng { std::random_device {}() };
     bool m_isPaused = false;
     std::chrono::steady_clock::time_point m_pauseStart {};
 };

+ 2 - 2
src/WallpaperEngine/Assets/AssetLoadException.cpp

@@ -2,5 +2,5 @@
 
 using namespace WallpaperEngine::Assets;
 
-AssetLoadException::AssetLoadException (const std::filesystem::filesystem_error& filesystem_error) noexcept
-: std::filesystem::filesystem_error (filesystem_error) {}
+AssetLoadException::AssetLoadException (const std::filesystem::filesystem_error& filesystem_error) noexcept :
+    std::filesystem::filesystem_error (filesystem_error) { }

+ 1 - 1
src/WallpaperEngine/Assets/AssetLoadException.h

@@ -4,7 +4,7 @@
 
 namespace WallpaperEngine::Assets {
 class AssetLoadException final : public std::filesystem::filesystem_error {
-  public:
+public:
     using std::filesystem::filesystem_error::filesystem_error;
     explicit AssetLoadException (const std::filesystem::filesystem_error& filesystem_error) noexcept;
 };

+ 29 - 30
src/WallpaperEngine/Assets/AssetLocator.cpp

@@ -4,36 +4,36 @@
 
 using namespace WallpaperEngine::Assets;
 
-AssetLocator::AssetLocator (ContainerUniquePtr filesystem) : m_filesystem (std::move (filesystem)) {}
+AssetLocator::AssetLocator (ContainerUniquePtr filesystem) : m_filesystem (std::move (filesystem)) { }
 
 std::string AssetLocator::shader (const std::filesystem::path& filename) const {
     try {
-        std::filesystem::path shader = filename;
+	std::filesystem::path shader = filename;
 
-        // detect workshop shaders and check if there's a
-        if (auto it = shader.begin (); *it++ == "workshop") {
-            const std::filesystem::path workshopId = *it++;
+	// detect workshop shaders and check if there's a
+	if (auto it = shader.begin (); *it++ == "workshop") {
+	    const std::filesystem::path workshopId = *it++;
 
-            if (++it != shader.end ()) {
-                const std::filesystem::path& shaderfile = *it;
+	    if (++it != shader.end ()) {
+		const std::filesystem::path& shaderfile = *it;
 
-                try {
-                    shader = std::filesystem::path ("zcompat") / "scene" / "shaders" / workshopId / shaderfile;
-                    // replace the old path with the new one
-                    std::string contents = this->m_filesystem->readString (shader);
+		try {
+		    shader = std::filesystem::path ("zcompat") / "scene" / "shaders" / workshopId / shaderfile;
+		    // replace the old path with the new one
+		    std::string contents = this->m_filesystem->readString (shader);
 
-                    sLog.out ("Replaced ", filename, " with compat ", shader);
+		    sLog.out ("Replaced ", filename, " with compat ", shader);
 
-                    return contents;
-                } catch (std::filesystem::filesystem_error&) {
-                    // these exceptions can be ignored because the replacement file might not exist
-                }
-            }
-        }
+		    return contents;
+		} catch (std::filesystem::filesystem_error&) {
+		    // these exceptions can be ignored because the replacement file might not exist
+		}
+	    }
+	}
 
-        return this->m_filesystem->readString ("shaders" / filename);
+	return this->m_filesystem->readString ("shaders" / filename);
     } catch (std::filesystem::filesystem_error& base) {
-        throw AssetLoadException (base);
+	throw AssetLoadException (base);
     }
 }
 
@@ -63,35 +63,34 @@ std::string AssetLocator::includeShader (const std::filesystem::path& filename)
 
 std::string AssetLocator::readString (const std::filesystem::path& filename) const {
     try {
-        return this->m_filesystem->readString (filename);
+	return this->m_filesystem->readString (filename);
     } catch (std::filesystem::filesystem_error& base) {
-        throw AssetLoadException (base);
+	throw AssetLoadException (base);
     }
 }
 
-
 ReadStreamSharedPtr AssetLocator::texture (const std::filesystem::path& filename) const {
-    const auto final = std::filesystem::path("materials") / filename.string ().append (".tex");
+    const auto final = std::filesystem::path ("materials") / filename.string ().append (".tex");
 
     try {
-        return this->m_filesystem->read (final);
+	return this->m_filesystem->read (final);
     } catch (std::filesystem::filesystem_error& base) {
-        throw AssetLoadException (base);
+	throw AssetLoadException (base);
     }
 }
 
 ReadStreamSharedPtr AssetLocator::read (const std::filesystem::path& path) const {
     try {
-        return this->m_filesystem->read (path);
+	return this->m_filesystem->read (path);
     } catch (std::filesystem::filesystem_error& base) {
-        throw AssetLoadException (base);
+	throw AssetLoadException (base);
     }
 }
 
 std::filesystem::path AssetLocator::physicalPath (const std::filesystem::path& path) const {
     try {
-        return this->m_filesystem->physicalPath (path);
+	return this->m_filesystem->physicalPath (path);
     } catch (std::filesystem::filesystem_error& base) {
-        throw AssetLoadException (base);
+	throw AssetLoadException (base);
     }
 }

+ 2 - 2
src/WallpaperEngine/Assets/AssetLocator.h

@@ -6,7 +6,7 @@ namespace WallpaperEngine::Assets {
 using namespace WallpaperEngine::FileSystem;
 using namespace WallpaperEngine::Data::Model;
 class AssetLocator {
-  public:
+public:
     explicit AssetLocator (ContainerUniquePtr filesystem);
 
     std::string vertexShader (const std::filesystem::path& filename) const;
@@ -17,7 +17,7 @@ class AssetLocator {
     ReadStreamSharedPtr read (const std::filesystem::path& path) const;
     std::filesystem::path physicalPath (const std::filesystem::path& path) const;
 
-  private:
+private:
     std::string shader (const std::filesystem::path& filename) const;
 
     ContainerUniquePtr m_filesystem;

+ 7 - 19
src/WallpaperEngine/Audio/AudioContext.cpp

@@ -2,33 +2,21 @@
 #include "WallpaperEngine/Audio/Drivers/AudioDriver.h"
 
 namespace WallpaperEngine::Audio {
-AudioContext::AudioContext (Drivers::AudioDriver& driver) : m_driver (driver) {}
+AudioContext::AudioContext (Drivers::AudioDriver& driver) : m_driver (driver) { }
 
-void AudioContext::addStream (AudioStream* stream) const {
-    this->m_driver.addStream (stream);
-}
+void AudioContext::addStream (AudioStream* stream) const { this->m_driver.addStream (stream); }
 
-AVSampleFormat AudioContext::getFormat () const {
-    return this->m_driver.getFormat ();
-}
+AVSampleFormat AudioContext::getFormat () const { return this->m_driver.getFormat (); }
 
-int AudioContext::getSampleRate () const {
-    return this->m_driver.getSampleRate ();
-}
+int AudioContext::getSampleRate () const { return this->m_driver.getSampleRate (); }
 
-int AudioContext::getChannels () const {
-    return this->m_driver.getChannels ();
-}
+int AudioContext::getChannels () const { return this->m_driver.getChannels (); }
 
 Application::ApplicationContext& AudioContext::getApplicationContext () const {
     return this->m_driver.getApplicationContext ();
 }
 
-Drivers::Recorders::PlaybackRecorder& AudioContext::getRecorder () const {
-    return this->m_driver.getRecorder ();
-}
+Drivers::Recorders::PlaybackRecorder& AudioContext::getRecorder () const { return this->m_driver.getRecorder (); }
 
-Drivers::AudioDriver& AudioContext::getDriver () const {
-    return this->m_driver;
-}
+Drivers::AudioDriver& AudioContext::getDriver () const { return this->m_driver; }
 } // namespace WallpaperEngine::Audio

+ 47 - 47
src/WallpaperEngine/Audio/AudioContext.h

@@ -8,62 +8,62 @@
 
 namespace WallpaperEngine {
 namespace Application {
-class ApplicationContext;
+    class ApplicationContext;
 }
 
 namespace Audio {
-namespace Drivers {
-class AudioDriver;
+    namespace Drivers {
+	class AudioDriver;
 
-namespace Recorders {
-class PulseAudioPlaybackRecorder;
-}
-} // namespace Drivers
+	namespace Recorders {
+	    class PulseAudioPlaybackRecorder;
+	}
+    } // namespace Drivers
 
-class AudioStream;
+    class AudioStream;
 
-class AudioContext {
-  public:
-    explicit AudioContext (Drivers::AudioDriver& driver);
+    class AudioContext {
+    public:
+	explicit AudioContext (Drivers::AudioDriver& driver);
 
-    /**
-     * Registers the given stream in the driver for playing
-     *
-     * @param stream
-     */
-    void addStream (AudioStream* stream) const;
+	/**
+	 * Registers the given stream in the driver for playing
+	 *
+	 * @param stream
+	 */
+	void addStream (AudioStream* stream) const;
 
-    /**
-     * TODO: MAYBE THIS SHOULD BE OUR OWN DEFINITIONS INSTEAD OF LIBRARY SPECIFIC ONES?
-     *
-     * @return The audio format the driver supports
-     */
-    [[nodiscard]] AVSampleFormat getFormat () const;
-    /**
-     * @return The sample rate the driver supports
-     */
-    [[nodiscard]] int getSampleRate () const;
-    /**
-     * @return The channels the driver supports
-     */
-    [[nodiscard]] int getChannels () const;
-    /**
-     * @return The application context under which the audio driver is initialized
-     */
-    Application::ApplicationContext& getApplicationContext () const;
-    /**
-     * @return The audio recorder to use to capture stereo mix data
-     */
-    [[nodiscard]] Drivers::Recorders::PlaybackRecorder& getRecorder () const;
+	/**
+	 * TODO: MAYBE THIS SHOULD BE OUR OWN DEFINITIONS INSTEAD OF LIBRARY SPECIFIC ONES?
+	 *
+	 * @return The audio format the driver supports
+	 */
+	[[nodiscard]] AVSampleFormat getFormat () const;
+	/**
+	 * @return The sample rate the driver supports
+	 */
+	[[nodiscard]] int getSampleRate () const;
+	/**
+	 * @return The channels the driver supports
+	 */
+	[[nodiscard]] int getChannels () const;
+	/**
+	 * @return The application context under which the audio driver is initialized
+	 */
+	Application::ApplicationContext& getApplicationContext () const;
+	/**
+	 * @return The audio recorder to use to capture stereo mix data
+	 */
+	[[nodiscard]] Drivers::Recorders::PlaybackRecorder& getRecorder () const;
 
-    /**
-     * @return The audio driver used to playback and record audio
-     */
-    [[nodiscard]] Drivers::AudioDriver& getDriver () const;
+	/**
+	 * @return The audio driver used to playback and record audio
+	 */
+	[[nodiscard]] Drivers::AudioDriver& getDriver () const;
 
-  private:
-    /** The audio driver in use */
-    Drivers::AudioDriver& m_driver;
-};
+    private:
+	/** The audio driver in use */
+	Drivers::AudioDriver& m_driver;
+    };
 } // namespace Audio
 } // namespace WallpaperEngine

+ 302 - 265
src/WallpaperEngine/Audio/AudioStream.cpp

@@ -14,42 +14,46 @@ int audio_read_thread (void* arg) {
     AVPacket* packet = av_packet_alloc ();
     int ret = 0;
 
-    if (waitMutex == nullptr)
-        sLog.exception ("Cannot create mutex for audio playback waiting");
+    if (waitMutex == nullptr) {
+	sLog.exception ("Cannot create mutex for audio playback waiting");
+    }
 
     while (ret >= 0 && stream->getAudioContext ().getApplicationContext ().state.general.keepRunning) {
-        // give the cpu some time to play the queued frames if there's enough info there
-        if (stream->getQueueSize () >= MAX_QUEUE_SIZE ||
-            (stream->getQueuePacketCount () > MIN_FRAMES &&
-             (av_q2d (stream->getTimeBase ()) * stream->getQueueDuration () > 1.0))) {
-            SDL_LockMutex (waitMutex);
-            SDL_CondWaitTimeout (stream->getWaitCondition (), waitMutex, 10);
-            SDL_UnlockMutex (waitMutex);
-            continue;
-        }
-
-        ret = av_read_frame (stream->getFormatContext (), packet);
-
-        if (ret == AVERROR_EOF) {
-            // seek to the beginning of the file again
-            avformat_seek_file (stream->getFormatContext (), stream->getAudioStream (), 0, 0, 0, ~AVSEEK_FLAG_FRAME);
-            avcodec_flush_buffers (stream->getContext ());
-
-            // ensure the thread is not killed if audio has to be looped
-            if (stream->isRepeat ())
-                ret = 0;
-
-            continue;
-        }
-
-        // TODO: PROPERLY IMPLEMENT THIS
-        if (packet->stream_index == stream->getAudioStream ())
-            stream->queuePacket (packet);
-        else
-            av_packet_unref (packet);
-
-        if (!stream->isInitialized ())
-            break;
+	// give the cpu some time to play the queued frames if there's enough info there
+	if (stream->getQueueSize () >= MAX_QUEUE_SIZE
+	    || (stream->getQueuePacketCount () > MIN_FRAMES
+		&& (av_q2d (stream->getTimeBase ()) * stream->getQueueDuration () > 1.0))) {
+	    SDL_LockMutex (waitMutex);
+	    SDL_CondWaitTimeout (stream->getWaitCondition (), waitMutex, 10);
+	    SDL_UnlockMutex (waitMutex);
+	    continue;
+	}
+
+	ret = av_read_frame (stream->getFormatContext (), packet);
+
+	if (ret == AVERROR_EOF) {
+	    // seek to the beginning of the file again
+	    avformat_seek_file (stream->getFormatContext (), stream->getAudioStream (), 0, 0, 0, ~AVSEEK_FLAG_FRAME);
+	    avcodec_flush_buffers (stream->getContext ());
+
+	    // ensure the thread is not killed if audio has to be looped
+	    if (stream->isRepeat ()) {
+		ret = 0;
+	    }
+
+	    continue;
+	}
+
+	// TODO: PROPERLY IMPLEMENT THIS
+	if (packet->stream_index == stream->getAudioStream ()) {
+	    stream->queuePacket (packet);
+	} else {
+	    av_packet_unref (packet);
+	}
+
+	if (!stream->isInitialized ()) {
+	    break;
+	}
     }
 
     // stop the audio too just in case
@@ -64,13 +68,13 @@ static int audio_read_data_callback (void* streamarg, uint8_t* buffer, int buffe
 
     // check if we're at eof and return the right value
     if (stream->getBuffer ()->eof ()) {
-        return AVERROR_EOF;
+	return AVERROR_EOF;
     }
 
     stream->getBuffer ()->read (reinterpret_cast<std::istream::char_type*> (buffer), buffer_size);
 
     if (stream->getBuffer ()->fail () && !stream->getBuffer ()->eof ()) {
-        return AVERROR_INVALIDDATA;
+	return AVERROR_INVALIDDATA;
     }
 
     // return read bytes only
@@ -84,114 +88,134 @@ int64_t audio_seek_data_callback (void* streamarg, int64_t offset, int whence) {
     stream->getBuffer ()->clear ();
 
     if (whence & AVSEEK_SIZE) {
-        const auto current = stream->getBuffer ()->tellg ();
-        stream->getBuffer ()->seekg (0, std::ios_base::end);
-        const auto end = stream->getBuffer ()->tellg ();
-        stream->getBuffer ()->seekg (current, std::ios_base::beg);
-        return end;
+	const auto current = stream->getBuffer ()->tellg ();
+	stream->getBuffer ()->seekg (0, std::ios_base::end);
+	const auto end = stream->getBuffer ()->tellg ();
+	stream->getBuffer ()->seekg (current, std::ios_base::beg);
+	return end;
     }
 
     switch (whence) {
-        case SEEK_CUR: stream->getBuffer ()->seekg (offset, std::ios_base::cur); break;
-        case SEEK_SET: stream->getBuffer ()->seekg (offset, std::ios_base::beg); break;
-        case SEEK_END: stream->getBuffer ()->seekg (offset, std::ios_base::end); break;
+	case SEEK_CUR:
+	    stream->getBuffer ()->seekg (offset, std::ios_base::cur);
+	    break;
+	case SEEK_SET:
+	    stream->getBuffer ()->seekg (offset, std::ios_base::beg);
+	    break;
+	case SEEK_END:
+	    stream->getBuffer ()->seekg (offset, std::ios_base::end);
+	    break;
     }
 
     return 0;
 }
 
-AudioStream::AudioStream (AudioContext& context, const std::string& filename) :
-    m_audioContext (context) {
+AudioStream::AudioStream (AudioContext& context, const std::string& filename) : m_audioContext (context) {
     this->loadCustomContent (filename.c_str ());
 }
 
-AudioStream::AudioStream (AudioContext& context, const ReadStreamSharedPtr& buffer) :
-    m_audioContext (context) {
+AudioStream::AudioStream (AudioContext& context, const ReadStreamSharedPtr& buffer) : m_audioContext (context) {
     // setup a custom context first
     this->m_formatContext = avformat_alloc_context ();
 
-    if (this->m_formatContext == nullptr)
-        sLog.exception ("Cannot allocate ffmpeg format context");
+    if (this->m_formatContext == nullptr) {
+	sLog.exception ("Cannot allocate ffmpeg format context");
+    }
 
     this->m_buffer = buffer;
 
     // setup custom io for it
-    this->m_formatContext->pb = avio_alloc_context (static_cast<uint8_t*> (av_malloc (4096)), 4096, 0, this,
-                                                    &audio_read_data_callback, nullptr, &audio_seek_data_callback);
+    this->m_formatContext->pb = avio_alloc_context (
+	static_cast<uint8_t*> (av_malloc (4096)), 4096, 0, this, &audio_read_data_callback, nullptr,
+	&audio_seek_data_callback
+    );
 
-    if (this->m_formatContext->pb == nullptr)
-        sLog.exception ("Cannot create avio context");
+    if (this->m_formatContext->pb == nullptr) {
+	sLog.exception ("Cannot create avio context");
+    }
 
     // continue the normal load procedure
     this->loadCustomContent ();
 }
 
 AudioStream::AudioStream (AudioContext& audioContext, AVCodecContext* context) :
-    m_audioContext (audioContext),
-    m_context (context),
-    m_queue (new PacketQueue) {
+    m_audioContext (audioContext), m_context (context), m_queue (new PacketQueue) {
     this->initialize ();
 }
 
 AudioStream::~AudioStream () {
-    if (this->m_swrctx != nullptr && swr_is_initialized (this->m_swrctx) == true)
-        swr_close (this->m_swrctx);
-    if (this->m_swrctx != nullptr)
-        swr_free (&this->m_swrctx);
-    if (this->m_decodePacket != nullptr)
-        av_packet_free (&this->m_decodePacket);
-    if (this->m_decodeFrame != nullptr)
-        av_frame_free (&this->m_decodeFrame);
+    if (this->m_swrctx != nullptr && swr_is_initialized (this->m_swrctx) == true) {
+	swr_close (this->m_swrctx);
+    }
+    if (this->m_swrctx != nullptr) {
+	swr_free (&this->m_swrctx);
+    }
+    if (this->m_decodePacket != nullptr) {
+	av_packet_free (&this->m_decodePacket);
+    }
+    if (this->m_decodeFrame != nullptr) {
+	av_frame_free (&this->m_decodeFrame);
+    }
     if (this->m_queue != nullptr && this->m_queue->packetList != nullptr) {
 #if FF_API_FIFO_OLD_API
-        av_fifo_free (this->m_queue->packetList);
-        this->m_queue->packetList = nullptr;
+	av_fifo_free (this->m_queue->packetList);
+	this->m_queue->packetList = nullptr;
 #else
-        av_fifo_freep2 (&this->m_queue->packetList);
+	av_fifo_freep2 (&this->m_queue->packetList);
 #endif /* FF_API_FIFO_OLD_API */
     }
 
     delete this->m_queue;
 
-    if (this->m_formatContext != nullptr)
-        avformat_close_input (&this->m_formatContext);
-    if (this->m_context != nullptr)
-        avcodec_free_context (&this->m_context);
-    if (this->m_audioStream != NO_AUDIO_STREAM)
-        av_freep (&this->m_formatContext->streams [this->m_audioStream]);
-    if (this->m_formatContext != nullptr)
-        avformat_free_context (this->m_formatContext);
+    if (this->m_formatContext != nullptr) {
+	avformat_close_input (&this->m_formatContext);
+    }
+    if (this->m_context != nullptr) {
+	avcodec_free_context (&this->m_context);
+    }
+    if (this->m_audioStream != NO_AUDIO_STREAM) {
+	av_freep (&this->m_formatContext->streams[this->m_audioStream]);
+    }
+    if (this->m_formatContext != nullptr) {
+	avformat_free_context (this->m_formatContext);
+    }
 }
 
 void AudioStream::loadCustomContent (const char* filename) {
-    if (avformat_open_input (&this->m_formatContext, filename, nullptr, nullptr) != 0)
-        sLog.exception ("Cannot open audio file: ", filename);
-    if (avformat_find_stream_info (this->m_formatContext, nullptr) < 0)
-        sLog.exception ("Cannot determine file format: ", filename);
+    if (avformat_open_input (&this->m_formatContext, filename, nullptr, nullptr) != 0) {
+	sLog.exception ("Cannot open audio file: ", filename);
+    }
+    if (avformat_find_stream_info (this->m_formatContext, nullptr) < 0) {
+	sLog.exception ("Cannot determine file format: ", filename);
+    }
 
     // find the audio stream
     for (unsigned int i = 0; i < this->m_formatContext->nb_streams; i++) {
-        if (this->m_formatContext->streams [i]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO && this->m_audioStream == NO_AUDIO_STREAM) {
-            this->m_audioStream = i;
-        }
+	if (this->m_formatContext->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO
+	    && this->m_audioStream == NO_AUDIO_STREAM) {
+	    this->m_audioStream = i;
+	}
     }
 
-    if (this->m_audioStream == NO_AUDIO_STREAM)
-        sLog.exception ("Cannot find an audio stream in file ", filename);
+    if (this->m_audioStream == NO_AUDIO_STREAM) {
+	sLog.exception ("Cannot find an audio stream in file ", filename);
+    }
 
     // get the decoder for it and alloc the required context
-    const AVCodec* aCodec =
-        avcodec_find_decoder (this->m_formatContext->streams [this->m_audioStream]->codecpar->codec_id);
+    const AVCodec* aCodec
+	= avcodec_find_decoder (this->m_formatContext->streams[this->m_audioStream]->codecpar->codec_id);
 
-    if (aCodec == nullptr)
-        sLog.exception ("Cannot initialize audio decoder for file: ", filename);
+    if (aCodec == nullptr) {
+	sLog.exception ("Cannot initialize audio decoder for file: ", filename);
+    }
 
     // alocate context
     AVCodecContext* avCodecContext = avcodec_alloc_context3 (aCodec);
 
-    if (avcodec_parameters_to_context (avCodecContext,
-                                       this->m_formatContext->streams [this->m_audioStream]->codecpar) != 0)
-        sLog.exception ("Cannot initialize audio decoder parameters");
+    if (avcodec_parameters_to_context (avCodecContext, this->m_formatContext->streams[this->m_audioStream]->codecpar)
+	!= 0) {
+	sLog.exception ("Cannot initialize audio decoder parameters");
+    }
 
     // finally open
     avcodec_open2 (avCodecContext, aCodec, nullptr);
@@ -219,40 +243,58 @@ void AudioStream::initialize () {
 
     // set output audio channels based on the input audio channels
     switch (this->m_audioContext.getChannels ()) {
-        case 1: out_channel_layout = AV_CH_LAYOUT_MONO; break;
-        case 2: out_channel_layout = AV_CH_LAYOUT_STEREO; break;
-        default: out_channel_layout = AV_CH_LAYOUT_SURROUND; break;
+	case 1:
+	    out_channel_layout = AV_CH_LAYOUT_MONO;
+	    break;
+	case 2:
+	    out_channel_layout = AV_CH_LAYOUT_STEREO;
+	    break;
+	default:
+	    out_channel_layout = AV_CH_LAYOUT_SURROUND;
+	    break;
     }
 
     // initialize swrctx
-    this->m_swrctx = swr_alloc_set_opts (nullptr, out_channel_layout, this->m_audioContext.getFormat (),
-                                         this->m_audioContext.getSampleRate (), this->getContext ()->channel_layout,
-                                         this->getContext ()->sample_fmt, this->getContext ()->sample_rate, 0, nullptr);
+    this->m_swrctx = swr_alloc_set_opts (
+	nullptr, out_channel_layout, this->m_audioContext.getFormat (), this->m_audioContext.getSampleRate (),
+	this->getContext ()->channel_layout, this->getContext ()->sample_fmt, this->getContext ()->sample_rate, 0,
+	nullptr
+    );
 #else
     AVChannelLayout out_channel_layout;
     int64_t out_channel_mask;
 
     // set output audio channels based on the input audio channels
     switch (this->m_audioContext.getChannels ()) {
-        case 1: out_channel_mask = AV_CH_LAYOUT_MONO; break;
-        case 2: out_channel_mask = AV_CH_LAYOUT_STEREO; break;
-        default: out_channel_mask = AV_CH_LAYOUT_SURROUND; break;
+	case 1:
+	    out_channel_mask = AV_CH_LAYOUT_MONO;
+	    break;
+	case 2:
+	    out_channel_mask = AV_CH_LAYOUT_STEREO;
+	    break;
+	default:
+	    out_channel_mask = AV_CH_LAYOUT_SURROUND;
+	    break;
     }
 
-    if (av_channel_layout_from_mask (&out_channel_layout, out_channel_mask) != 0)
-        sLog.exception ("Cannot get channel layout from mask");
+    if (av_channel_layout_from_mask (&out_channel_layout, out_channel_mask) != 0) {
+	sLog.exception ("Cannot get channel layout from mask");
+    }
 
-    swr_alloc_set_opts2 (&this->m_swrctx, &out_channel_layout, this->m_audioContext.getFormat (),
-                         this->m_audioContext.getSampleRate (), &this->m_context->ch_layout,
-                         this->m_context->sample_fmt, this->m_context->sample_rate, 0, nullptr);
+    swr_alloc_set_opts2 (
+	&this->m_swrctx, &out_channel_layout, this->m_audioContext.getFormat (), this->m_audioContext.getSampleRate (),
+	&this->m_context->ch_layout, this->m_context->sample_fmt, this->m_context->sample_rate, 0, nullptr
+    );
 #endif
 
-    if (this->m_swrctx == nullptr)
-        sLog.exception ("Cannot initialize swrctx for audio resampling");
+    if (this->m_swrctx == nullptr) {
+	sLog.exception ("Cannot initialize swrctx for audio resampling");
+    }
 
     // initialize the context
-    if (swr_init (this->m_swrctx) < 0)
-        sLog.exception ("Failed to initialize the resampling context.");
+    if (swr_init (this->m_swrctx) < 0) {
+	sLog.exception ("Failed to initialize the resampling context.");
+    }
 
     // setup the queue information
     this->m_queue->mutex = SDL_CreateMutex ();
@@ -263,10 +305,10 @@ void AudioStream::initialize () {
     this->m_decodePacket = av_packet_alloc ();
 
     if (!this->m_decodeFrame) {
-        sLog.exception ("Could not allocate AVFrame.\n");
+	sLog.exception ("Could not allocate AVFrame.\n");
     }
     if (!this->m_decodePacket) {
-        sLog.exception ("Could not allocate AVPacket.\n");
+	sLog.exception ("Could not allocate AVPacket.\n");
     }
 
     this->m_initialized = true;
@@ -277,8 +319,8 @@ void AudioStream::queuePacket (AVPacket* pkt) {
     AVPacket* clone = av_packet_alloc ();
 
     if (clone == nullptr) {
-        av_packet_unref (clone);
-        return;
+	av_packet_unref (clone);
+	return;
     }
 
     av_packet_move_ref (clone, pkt);
@@ -287,23 +329,27 @@ void AudioStream::queuePacket (AVPacket* pkt) {
     const bool gotQueued = this->doQueue (clone);
     SDL_UnlockMutex (this->m_queue->mutex);
 
-    if (!gotQueued)
-        av_packet_free (&pkt);
+    if (!gotQueued) {
+	av_packet_free (&pkt);
+    }
 }
 
 bool AudioStream::doQueue (AVPacket* pkt) {
-    MyAVPacketList entry {pkt};
+    MyAVPacketList entry { pkt };
 
 #if FF_API_FIFO_OLD_API
-    if (av_fifo_space (this->m_queue->packetList) < static_cast <int> (sizeof (entry)))
-        if (av_fifo_grow (this->m_queue->packetList, sizeof (entry)) < 0)
-            return false;
+    if (av_fifo_space (this->m_queue->packetList) < static_cast<int> (sizeof (entry))) {
+	if (av_fifo_grow (this->m_queue->packetList, sizeof (entry)) < 0) {
+	    return false;
+	}
+    }
 
     av_fifo_generic_write (this->m_queue->packetList, &entry, sizeof (entry), nullptr);
 #else
     // write the entry if possible
-    if (av_fifo_write (this->m_queue->packetList, &entry, 1) < 0)
-        return false;
+    if (av_fifo_write (this->m_queue->packetList, &entry, 1) < 0) {
+	return false;
+    }
 #endif
 
     this->m_queue->nb_packets++;
@@ -316,102 +362,78 @@ bool AudioStream::doQueue (AVPacket* pkt) {
 }
 
 void AudioStream::dequeuePacket () {
-    MyAVPacketList entry{};
+    MyAVPacketList entry {};
 
     SDL_LockMutex (this->m_queue->mutex);
 
     while (this->m_audioContext.getApplicationContext ().state.general.keepRunning) {
 #if FF_API_FIFO_OLD_API
-        int ret = -1;
+	int ret = -1;
 
-        if (av_fifo_size (this->m_queue->packetList) >= static_cast <int> (sizeof (entry)))
-            ret = av_fifo_generic_read (this->m_queue->packetList, &entry, sizeof (entry), nullptr);
+	if (av_fifo_size (this->m_queue->packetList) >= static_cast<int> (sizeof (entry))) {
+	    ret = av_fifo_generic_read (this->m_queue->packetList, &entry, sizeof (entry), nullptr);
+	}
 #else
-        const int ret = av_fifo_read (this->m_queue->packetList, &entry, 1);
+	const int ret = av_fifo_read (this->m_queue->packetList, &entry, 1);
 #endif
 
-        // enough data available, read it
-        if (ret >= 0) {
-            this->m_queue->nb_packets--;
-            this->m_queue->size -= entry.packet->size + sizeof (entry);
-            this->m_queue->duration -= entry.packet->duration;
+	// enough data available, read it
+	if (ret >= 0) {
+	    this->m_queue->nb_packets--;
+	    this->m_queue->size -= entry.packet->size + sizeof (entry);
+	    this->m_queue->duration -= entry.packet->duration;
 
-            // move the reference and free the old one
-            av_packet_move_ref (this->m_decodePacket, entry.packet);
-            av_packet_free (&entry.packet);
-            break;
-        }
+	    // move the reference and free the old one
+	    av_packet_move_ref (this->m_decodePacket, entry.packet);
+	    av_packet_free (&entry.packet);
+	    break;
+	}
 
-        // make the thread wait if nothing was available
-        SDL_CondWait (this->m_queue->cond, this->m_queue->mutex);
+	// make the thread wait if nothing was available
+	SDL_CondWait (this->m_queue->cond, this->m_queue->mutex);
     }
 
     SDL_UnlockMutex (this->m_queue->mutex);
 }
 
-AVCodecContext* AudioStream::getContext () const {
-    return this->m_context;
-}
+AVCodecContext* AudioStream::getContext () const { return this->m_context; }
 
-AVFormatContext* AudioStream::getFormatContext () const {
-    return this->m_formatContext;
-}
+AVFormatContext* AudioStream::getFormatContext () const { return this->m_formatContext; }
 
-int AudioStream::getAudioStream () const {
-    return this->m_audioStream;
-}
+int AudioStream::getAudioStream () const { return this->m_audioStream; }
 
-bool AudioStream::isInitialized () const {
-    return this->m_initialized;
-}
+bool AudioStream::isInitialized () const { return this->m_initialized; }
 
-void AudioStream::setRepeat (const bool newRepeat) {
-    this->m_repeat = newRepeat;
-}
+void AudioStream::setRepeat (const bool newRepeat) { this->m_repeat = newRepeat; }
 
-bool AudioStream::isRepeat () const {
-    return this->m_repeat;
-}
+bool AudioStream::isRepeat () const { return this->m_repeat; }
 
-ReadStreamSharedPtr& AudioStream::getBuffer () {
-    return this->m_buffer;
-}
+ReadStreamSharedPtr& AudioStream::getBuffer () { return this->m_buffer; }
 
-SDL_cond* AudioStream::getWaitCondition () const {
-    return this->m_queue->wait;
-}
+SDL_cond* AudioStream::getWaitCondition () const { return this->m_queue->wait; }
 
-size_t AudioStream::getQueueSize () const {
-    return this->m_queue->size;
-}
+size_t AudioStream::getQueueSize () const { return this->m_queue->size; }
 
-int AudioStream::getQueuePacketCount () const {
-    return this->m_queue->nb_packets;
-}
+int AudioStream::getQueuePacketCount () const { return this->m_queue->nb_packets; }
 
 AVRational AudioStream::getTimeBase () const {
     if (this->m_audioStream == NO_AUDIO_STREAM) {
-        return {0, 0};
+	return { 0, 0 };
     }
 
-    return this->m_formatContext->streams [this->m_audioStream]->time_base;
+    return this->m_formatContext->streams[this->m_audioStream]->time_base;
 }
 
-int64_t AudioStream::getQueueDuration () const {
-    return this->m_queue->duration;
-}
+int64_t AudioStream::getQueueDuration () const { return this->m_queue->duration; }
 
-bool AudioStream::isQueueEmpty () const {
-    return this->m_queue->nb_packets == 0;
-}
+bool AudioStream::isQueueEmpty () const { return this->m_queue->nb_packets == 0; }
 
-SDL_mutex* AudioStream::getMutex () const {
-    return this->m_queue->mutex;
-}
+SDL_mutex* AudioStream::getMutex () const { return this->m_queue->mutex; }
 
 void AudioStream::stop () {
-    if (!this->isInitialized ())
-        return;
+    if (!this->isInitialized ()) {
+	return;
+    }
 
     // stop the threads running
     this->m_initialized = false;
@@ -428,17 +450,18 @@ int AudioStream::resampleAudio (uint8_t* out_buf, const int out_size) {
     // retrieve number of audio samples (per channel)
     const int in_nb_samples = this->m_decodeFrame->nb_samples;
     if (in_nb_samples <= 0) {
-        sLog.error ("in_nb_samples error.");
-        return -1;
+	sLog.error ("in_nb_samples error.");
+	return -1;
     }
 
-    int max_out_nb_samples = out_nb_samples = av_rescale_rnd (in_nb_samples, this->m_audioContext.getSampleRate (),
-                                                              this->getContext ()->sample_rate, AV_ROUND_UP);
+    int max_out_nb_samples = out_nb_samples = av_rescale_rnd (
+	in_nb_samples, this->m_audioContext.getSampleRate (), this->getContext ()->sample_rate, AV_ROUND_UP
+    );
 
     // check rescaling was successful
     if (max_out_nb_samples <= 0) {
-        sLog.error ("av_rescale_rnd error.");
-        return -1;
+	sLog.error ("av_rescale_rnd error.");
+	return -1;
     }
 
     // get number of output audio channels
@@ -447,78 +470,89 @@ int AudioStream::resampleAudio (uint8_t* out_buf, const int out_size) {
 
     // set output audio channels based on the input audio channels
     switch (this->m_audioContext.getChannels ()) {
-        case 1: out_channel_layout = AV_CH_LAYOUT_MONO; break;
-        case 2: out_channel_layout = AV_CH_LAYOUT_STEREO; break;
-        default: out_channel_layout = AV_CH_LAYOUT_SURROUND; break;
+	case 1:
+	    out_channel_layout = AV_CH_LAYOUT_MONO;
+	    break;
+	case 2:
+	    out_channel_layout = AV_CH_LAYOUT_STEREO;
+	    break;
+	default:
+	    out_channel_layout = AV_CH_LAYOUT_SURROUND;
+	    break;
     }
 
     out_nb_channels = av_get_channel_layout_nb_channels (out_channel_layout);
 #else
     out_nb_channels = this->getContext ()->ch_layout.nb_channels;
 #endif
-    ret = av_samples_alloc_array_and_samples (&resampled_data, &out_linesize, out_nb_channels, out_nb_samples,
-                                              this->m_audioContext.getFormat (), 0);
+    ret = av_samples_alloc_array_and_samples (
+	&resampled_data, &out_linesize, out_nb_channels, out_nb_samples, this->m_audioContext.getFormat (), 0
+    );
 
     if (ret < 0) {
-        sLog.error ("av_samples_alloc_array_and_samples() error: Could not allocate destination samples.");
-        return -1;
+	sLog.error ("av_samples_alloc_array_and_samples() error: Could not allocate destination samples.");
+	return -1;
     }
 
     // retrieve output samples number taking into account the progressive delay
-    out_nb_samples =
-        av_rescale_rnd (swr_get_delay (this->m_swrctx, this->getContext ()->sample_rate) + in_nb_samples,
-                        this->m_audioContext.getSampleRate (), this->getContext ()->sample_rate, AV_ROUND_UP);
+    out_nb_samples = av_rescale_rnd (
+	swr_get_delay (this->m_swrctx, this->getContext ()->sample_rate) + in_nb_samples,
+	this->m_audioContext.getSampleRate (), this->getContext ()->sample_rate, AV_ROUND_UP
+    );
 
     // check output samples number was correctly retrieved
     if (out_nb_samples <= 0) {
-        sLog.error ("av_rescale_rnd error");
-        return -1;
+	sLog.error ("av_rescale_rnd error");
+	return -1;
     }
 
     if (out_nb_samples > max_out_nb_samples) {
-        // free memory block and set pointer to NULL
-        av_freep (&resampled_data [0]);
+	// free memory block and set pointer to NULL
+	av_freep (&resampled_data[0]);
 
-        // Allocate a samples buffer for out_nb_samples samples
-        ret = av_samples_alloc (resampled_data, &out_linesize, out_nb_channels, out_nb_samples,
-                                this->m_audioContext.getFormat (), 1);
+	// Allocate a samples buffer for out_nb_samples samples
+	ret = av_samples_alloc (
+	    resampled_data, &out_linesize, out_nb_channels, out_nb_samples, this->m_audioContext.getFormat (), 1
+	);
 
-        // check samples buffer correctly allocated
-        if (ret < 0) {
-            sLog.error ("av_samples_alloc failed.");
-            return -1;
-        }
+	// check samples buffer correctly allocated
+	if (ret < 0) {
+	    sLog.error ("av_samples_alloc failed.");
+	    return -1;
+	}
 
-        max_out_nb_samples = out_nb_samples;
+	max_out_nb_samples = out_nb_samples;
     }
 
     // do the actual audio data resampling
-    ret = swr_convert (this->m_swrctx, resampled_data, max_out_nb_samples,
-    const_cast<const uint8_t**> (this->m_decodeFrame->data), this->m_decodeFrame->nb_samples);
+    ret = swr_convert (
+	this->m_swrctx, resampled_data, max_out_nb_samples, const_cast<const uint8_t**> (this->m_decodeFrame->data),
+	this->m_decodeFrame->nb_samples
+    );
 
     // check audio conversion was successful
     if (ret < 0) {
-        sLog.error ("swr_convert_error.");
-        return -1;
+	sLog.error ("swr_convert_error.");
+	return -1;
     }
 
     // Get the required buffer size for the given audio parameters
-    resampled_data_size =
-        av_samples_get_buffer_size (&out_linesize, out_nb_channels, ret, this->m_audioContext.getFormat (), 1);
+    resampled_data_size
+	= av_samples_get_buffer_size (&out_linesize, out_nb_channels, ret, this->m_audioContext.getFormat (), 1);
 
     // check audio buffer size
     if (resampled_data_size < 0) {
-        sLog.error ("av_samples_get_buffer_size error.");
-        return -1;
+	sLog.error ("av_samples_get_buffer_size error.");
+	return -1;
     }
 
     // copy the resampled data to the output buffer up to out_size bytes
-    memcpy (out_buf, resampled_data [0], std::min(resampled_data_size, out_size));
+    memcpy (out_buf, resampled_data[0], std::min (resampled_data_size, out_size));
 
     // memory cleanup
     if (resampled_data) {
-        // free memory block and set pointer to NULL
-        av_freep (&resampled_data [0]);
+	// free memory block and set pointer to NULL
+	av_freep (&resampled_data[0]);
     }
 
     av_freep (&resampled_data);
@@ -531,51 +565,54 @@ int AudioStream::decodeFrame (uint8_t* audioBuffer, const int bufferSize) {
 
     // block until there's any data in the buffers
     while (this->m_audioContext.getApplicationContext ().state.general.keepRunning) {
-        while (audio_pkt_size > 0 && this->m_audioContext.getApplicationContext ().state.general.keepRunning) {
-            int got_frame = 0;
-            int ret = avcodec_receive_frame (this->getContext (), this->m_decodeFrame);
-
-            if (ret == 0)
-                got_frame = 1;
-            if (ret == AVERROR (EAGAIN))
-                ret = 0;
-            if (ret == 0)
-                ret = avcodec_send_packet (this->getContext (), this->m_decodePacket);
-            if (ret < 0 && ret != AVERROR (EAGAIN))
-                return -1;
-
-            if (this->m_decodePacket->size < 0) {
-                // if error, skip frame
-                audio_pkt_size = 0;
-                break;
-            }
-
-            audio_pkt_size -= this->m_decodePacket->size;
-            int data_size = 0;
-
-            if (got_frame) {
-                // audio resampling
-                data_size = this->resampleAudio (audioBuffer, bufferSize);
-            }
-            if (data_size <= 0) {
-                // no data found, keep waiting
-                continue;
-            }
-            // some data was found
-            return data_size;
-        }
-
-        if (this->m_decodePacket->data)
-            av_packet_unref (this->m_decodePacket);
-
-        this->dequeuePacket ();
-
-        audio_pkt_size = this->m_decodePacket->size;
+	while (audio_pkt_size > 0 && this->m_audioContext.getApplicationContext ().state.general.keepRunning) {
+	    int got_frame = 0;
+	    int ret = avcodec_receive_frame (this->getContext (), this->m_decodeFrame);
+
+	    if (ret == 0) {
+		got_frame = 1;
+	    }
+	    if (ret == AVERROR (EAGAIN)) {
+		ret = 0;
+	    }
+	    if (ret == 0) {
+		ret = avcodec_send_packet (this->getContext (), this->m_decodePacket);
+	    }
+	    if (ret < 0 && ret != AVERROR (EAGAIN)) {
+		return -1;
+	    }
+
+	    if (this->m_decodePacket->size < 0) {
+		// if error, skip frame
+		audio_pkt_size = 0;
+		break;
+	    }
+
+	    audio_pkt_size -= this->m_decodePacket->size;
+	    int data_size = 0;
+
+	    if (got_frame) {
+		// audio resampling
+		data_size = this->resampleAudio (audioBuffer, bufferSize);
+	    }
+	    if (data_size <= 0) {
+		// no data found, keep waiting
+		continue;
+	    }
+	    // some data was found
+	    return data_size;
+	}
+
+	if (this->m_decodePacket->data) {
+	    av_packet_unref (this->m_decodePacket);
+	}
+
+	this->dequeuePacket ();
+
+	audio_pkt_size = this->m_decodePacket->size;
     }
 
     return 0;
 }
 
-AudioContext& AudioStream::getAudioContext () const {
-    return this->m_audioContext;
-}
+AudioContext& AudioStream::getAudioContext () const { return this->m_audioContext; }

+ 13 - 13
src/WallpaperEngine/Audio/AudioStream.h

@@ -18,10 +18,10 @@ extern "C" {
 
 // TODO: FIND A BETTER PLACE TO DO THIS? OLD_API MIGHT EXIST BUT THIS DEFINE MIGHT NOT BE DEFINED...
 #ifndef FF_API_FIFO_OLD_API
-#define 	FF_API_FIFO_OLD_API   (LIBAVUTIL_VERSION_MAJOR < 59)
+#define FF_API_FIFO_OLD_API (LIBAVUTIL_VERSION_MAJOR < 59)
 #endif
 #ifndef FF_API_OLD_CHANNEL_LAYOUT
-#define 	FF_API_OLD_CHANNEL_LAYOUT   (LIBAVUTIL_VERSION_MAJOR < 59)
+#define FF_API_OLD_CHANNEL_LAYOUT (LIBAVUTIL_VERSION_MAJOR < 59)
 #endif
 
 #define MAX_QUEUE_SIZE (5 * 1024 * 1024)
@@ -37,7 +37,7 @@ using namespace WallpaperEngine::FileSystem;
  * Represents a playable audio stream for the audio driver
  */
 class AudioStream {
-  public:
+public:
     AudioStream (AudioContext& context, const std::string& filename);
     AudioStream (AudioContext& context, const ReadStreamSharedPtr& buffer);
     AudioStream (AudioContext& audioContext, AVCodecContext* context);
@@ -131,7 +131,7 @@ class AudioStream {
      */
     int decodeFrame (uint8_t* audioBuffer, int bufferSize);
 
-  private:
+private:
     /**
      * Initializes ffmpeg to read the given file
      *
@@ -177,7 +177,7 @@ class AudioStream {
     uint32_t m_length = 0;
 
     struct MyAVPacketList {
-        AVPacket* packet;
+	AVPacket* packet;
     };
 
     /** The packet used while decoding this stream */
@@ -190,16 +190,16 @@ class AudioStream {
      */
     struct PacketQueue {
 #if FF_API_FIFO_OLD_API
-        AVFifoBuffer* packetList = nullptr;
+	AVFifoBuffer* packetList = nullptr;
 #else
-        AVFifo* packetList = nullptr;
+	AVFifo* packetList = nullptr;
 #endif
-        int nb_packets = 0;
-        size_t size = 0;
-        int64_t duration = 0;
-        SDL_mutex* mutex = nullptr;
-        SDL_cond* wait = nullptr;
-        SDL_cond* cond = nullptr;
+	int nb_packets = 0;
+	size_t size = 0;
+	int64_t duration = 0;
+	SDL_mutex* mutex = nullptr;
+	SDL_cond* wait = nullptr;
+	SDL_cond* cond = nullptr;
     }* m_queue {};
 };
 } // namespace WallpaperEngine::Audio

+ 4 - 13
src/WallpaperEngine/Audio/Drivers/AudioDriver.cpp

@@ -4,10 +4,7 @@ namespace WallpaperEngine::Audio::Drivers {
 AudioDriver::AudioDriver (
     Application::ApplicationContext& applicationContext, Detectors::AudioPlayingDetector& detector,
     Recorders::PlaybackRecorder& recorder
-) :
-    m_applicationContext (applicationContext),
-    m_detector (detector),
-    m_recorder (recorder) {
+) : m_applicationContext (applicationContext), m_detector (detector), m_recorder (recorder) {
     // perform a few update cycles to ensure data is ready before anything actually uses the audio
     this->AudioDriver::update ();
     this->AudioDriver::update ();
@@ -18,15 +15,9 @@ void AudioDriver::update () {
     this->m_detector.update ();
 }
 
-Application::ApplicationContext& AudioDriver::getApplicationContext () const {
-    return this->m_applicationContext;
-}
+Application::ApplicationContext& AudioDriver::getApplicationContext () const { return this->m_applicationContext; }
 
-Detectors::AudioPlayingDetector& AudioDriver::getAudioDetector () const {
-    return this->m_detector;
-}
+Detectors::AudioPlayingDetector& AudioDriver::getAudioDetector () const { return this->m_detector; }
 
-Recorders::PlaybackRecorder& AudioDriver::getRecorder () const {
-    return this->m_recorder;
-}
+Recorders::PlaybackRecorder& AudioDriver::getRecorder () const { return this->m_recorder; }
 } // namespace WallpaperEngine::Audio::Drivers

+ 61 - 60
src/WallpaperEngine/Audio/Drivers/AudioDriver.h

@@ -9,75 +9,76 @@
 
 namespace WallpaperEngine {
 namespace Application {
-class ApplicationContext;
+    class ApplicationContext;
 }
 
 namespace Audio {
-class AudioStream;
+    class AudioStream;
 
-namespace Drivers {
-namespace Detectors {
-class AudioPlayingDetector;
-}
+    namespace Drivers {
+	namespace Detectors {
+	    class AudioPlayingDetector;
+	}
 
-namespace Recorders {
-class PulseAudioPlaybackRecorder;
-}
+	namespace Recorders {
+	    class PulseAudioPlaybackRecorder;
+	}
 
-/**
- * Base class for audio driver implementations
- */
-class AudioDriver {
-  public:
-    explicit AudioDriver (
-        Application::ApplicationContext& applicationContext, Detectors::AudioPlayingDetector& detector,
-        Recorders::PlaybackRecorder& recorder);
+	/**
+	 * Base class for audio driver implementations
+	 */
+	class AudioDriver {
+	public:
+	    explicit AudioDriver (
+		Application::ApplicationContext& applicationContext, Detectors::AudioPlayingDetector& detector,
+		Recorders::PlaybackRecorder& recorder
+	    );
 
-    virtual ~AudioDriver () = default;
-    /**
-     * Registers the given stream in the driver for playing
-     *
-     * @param stream
-     */
-    virtual void addStream (AudioStream* stream) = 0;
+	    virtual ~AudioDriver () = default;
+	    /**
+	     * Registers the given stream in the driver for playing
+	     *
+	     * @param stream
+	     */
+	    virtual void addStream (AudioStream* stream) = 0;
 
-    /**
-     * Updates status of the different audio settings
-     */
-    virtual void update ();
+	    /**
+	     * Updates status of the different audio settings
+	     */
+	    virtual void update ();
 
-    /**
-     * TODO: MAYBE THIS SHOULD BE OUR OWN DEFINITIONS INSTEAD OF LIBRARY SPECIFIC ONES?
-     *
-     * @return The audio format the driver supports
-     */
-    [[nodiscard]] virtual AVSampleFormat getFormat () const = 0;
-    /**
-     * @return The sample rate the driver supports
-     */
-    [[nodiscard]] virtual int getSampleRate () const = 0;
-    /**
-     * @return The channels the driver supports
-     */
-    [[nodiscard]] virtual int getChannels () const = 0;
-    /**
-     * @return The application context under which the audio driver is initialized
-     */
-    Application::ApplicationContext& getApplicationContext () const;
-    /**
-     * @return The audio playing detector to use to stop playing sound when something else starts playing
-     */
-    [[nodiscard]] Detectors::AudioPlayingDetector& getAudioDetector () const;
-    /**
-     * @return The audio recorder to use to capture stereo mix data
-     */
-    [[nodiscard]] Recorders::PlaybackRecorder& getRecorder () const;
+	    /**
+	     * TODO: MAYBE THIS SHOULD BE OUR OWN DEFINITIONS INSTEAD OF LIBRARY SPECIFIC ONES?
+	     *
+	     * @return The audio format the driver supports
+	     */
+	    [[nodiscard]] virtual AVSampleFormat getFormat () const = 0;
+	    /**
+	     * @return The sample rate the driver supports
+	     */
+	    [[nodiscard]] virtual int getSampleRate () const = 0;
+	    /**
+	     * @return The channels the driver supports
+	     */
+	    [[nodiscard]] virtual int getChannels () const = 0;
+	    /**
+	     * @return The application context under which the audio driver is initialized
+	     */
+	    Application::ApplicationContext& getApplicationContext () const;
+	    /**
+	     * @return The audio playing detector to use to stop playing sound when something else starts playing
+	     */
+	    [[nodiscard]] Detectors::AudioPlayingDetector& getAudioDetector () const;
+	    /**
+	     * @return The audio recorder to use to capture stereo mix data
+	     */
+	    [[nodiscard]] Recorders::PlaybackRecorder& getRecorder () const;
 
-  private:
-    Application::ApplicationContext& m_applicationContext;
-    Detectors::AudioPlayingDetector& m_detector;
-    Recorders::PlaybackRecorder& m_recorder;
-};
-} // namespace Drivers
+	private:
+	    Application::ApplicationContext& m_applicationContext;
+	    Detectors::AudioPlayingDetector& m_detector;
+	    Recorders::PlaybackRecorder& m_recorder;
+	};
+    } // namespace Drivers
 } // namespace Audio
 } // namespace WallpaperEngine

+ 5 - 10
src/WallpaperEngine/Audio/Drivers/Detectors/AudioPlayingDetector.cpp

@@ -3,13 +3,10 @@
 namespace WallpaperEngine::Audio::Drivers::Detectors {
 AudioPlayingDetector::AudioPlayingDetector (
     Application::ApplicationContext& appContext,
-    const Render::Drivers::Detectors::FullScreenDetector& fullscreenDetector) :
-    m_applicationContext (appContext),
-    m_fullscreenDetector (fullscreenDetector) {}
+    const Render::Drivers::Detectors::FullScreenDetector& fullscreenDetector
+) : m_applicationContext (appContext), m_fullscreenDetector (fullscreenDetector) { }
 
-bool AudioPlayingDetector::anythingPlaying () const {
-    return this->m_isPlaying;
-}
+bool AudioPlayingDetector::anythingPlaying () const { return this->m_isPlaying; }
 
 Application::ApplicationContext& AudioPlayingDetector::getApplicationContext () const {
     return this->m_applicationContext;
@@ -19,10 +16,8 @@ const Render::Drivers::Detectors::FullScreenDetector& AudioPlayingDetector::getF
     return this->m_fullscreenDetector;
 }
 
-void AudioPlayingDetector::setIsPlaying (const bool newState) {
-    this->m_isPlaying = newState;
-}
+void AudioPlayingDetector::setIsPlaying (const bool newState) { this->m_isPlaying = newState; }
 
-void AudioPlayingDetector::update () {}
+void AudioPlayingDetector::update () { }
 
 } // namespace WallpaperEngine::Audio::Drivers::Detectors

+ 45 - 44
src/WallpaperEngine/Audio/Drivers/Detectors/AudioPlayingDetector.h

@@ -5,57 +5,58 @@
 
 namespace WallpaperEngine {
 namespace Application {
-class ApplicationContext;
+    class ApplicationContext;
 }
 
 namespace Render::Drivers::Detectors {
-class FullScreenDetector;
+    class FullScreenDetector;
 }
 
 namespace Audio::Drivers::Detectors {
-/**
- * Base class for any implementation of audio playing detection
- */
-class AudioPlayingDetector {
-  public:
-    AudioPlayingDetector (
-        Application::ApplicationContext& appContext,
-        const Render::Drivers::Detectors::FullScreenDetector& fullscreenDetector);
-
-    virtual ~AudioPlayingDetector () = default;
-
-    /**
-     * @return If any kind of sound is currently playing on the default audio device
-     */
-    [[nodiscard]] bool anythingPlaying () const;
-
-    /**
-     * Updates the playing status to the specified value
-     *
-     * @param newState
-     */
-    void setIsPlaying (bool newState);
-
     /**
-     * Checks if any audio is playing and updates state accordingly
+     * Base class for any implementation of audio playing detection
      */
-    virtual void update ();
-
-  protected:
-    /**
-     * @return The application context using this detector
-     */
-    [[nodiscard]] Application::ApplicationContext& getApplicationContext () const;
-    /**
-     * @return The fullscreen detector used
-     */
-    [[nodiscard]] const Render::Drivers::Detectors::FullScreenDetector& getFullscreenDetector () const;
-
-  private:
-    bool m_isPlaying = false;
-
-    Application::ApplicationContext& m_applicationContext;
-    const Render::Drivers::Detectors::FullScreenDetector& m_fullscreenDetector;
-};
+    class AudioPlayingDetector {
+    public:
+	AudioPlayingDetector (
+	    Application::ApplicationContext& appContext,
+	    const Render::Drivers::Detectors::FullScreenDetector& fullscreenDetector
+	);
+
+	virtual ~AudioPlayingDetector () = default;
+
+	/**
+	 * @return If any kind of sound is currently playing on the default audio device
+	 */
+	[[nodiscard]] bool anythingPlaying () const;
+
+	/**
+	 * Updates the playing status to the specified value
+	 *
+	 * @param newState
+	 */
+	void setIsPlaying (bool newState);
+
+	/**
+	 * Checks if any audio is playing and updates state accordingly
+	 */
+	virtual void update ();
+
+    protected:
+	/**
+	 * @return The application context using this detector
+	 */
+	[[nodiscard]] Application::ApplicationContext& getApplicationContext () const;
+	/**
+	 * @return The fullscreen detector used
+	 */
+	[[nodiscard]] const Render::Drivers::Detectors::FullScreenDetector& getFullscreenDetector () const;
+
+    private:
+	bool m_isPlaying = false;
+
+	Application::ApplicationContext& m_applicationContext;
+	const Render::Drivers::Detectors::FullScreenDetector& m_fullscreenDetector;
+    };
 } // namespace Audio::Drivers::Detectors
 } // namespace WallpaperEngine

+ 31 - 22
src/WallpaperEngine/Audio/Drivers/Detectors/PulseAudioPlayingDetector.cpp

@@ -7,22 +7,26 @@ namespace WallpaperEngine::Audio::Drivers::Detectors {
 void sinkInputInfoCallback (pa_context* context, const pa_sink_input_info* info, int eol, void* userdata) {
     auto* detector = static_cast<PulseAudioPlayingDetector*> (userdata);
 
-    if (info == nullptr)
-        return;
+    if (info == nullptr) {
+	return;
+    }
 
-    if (info->proplist == nullptr)
-        return;
+    if (info->proplist == nullptr) {
+	return;
+    }
 
     // get processid
     const char* value = pa_proplist_gets (info->proplist, PA_PROP_APPLICATION_PROCESS_ID);
 
-    if (value && strtol (value, nullptr, 10) != getpid () && pa_cvolume_avg (&info->volume) != PA_VOLUME_MUTED)
-        detector->setIsPlaying (true);
+    if (value && strtol (value, nullptr, 10) != getpid () && pa_cvolume_avg (&info->volume) != PA_VOLUME_MUTED) {
+	detector->setIsPlaying (true);
+    }
 }
 
 void defaultSinkInfoCallback (pa_context* context, const pa_server_info* info, void* userdata) {
-    if (info == nullptr)
-        return;
+    if (info == nullptr) {
+	return;
+    }
 
     pa_operation* op = pa_context_get_sink_input_info_list (context, sinkInputInfoCallback, userdata);
 
@@ -31,8 +35,8 @@ void defaultSinkInfoCallback (pa_context* context, const pa_server_info* info, v
 
 PulseAudioPlayingDetector::PulseAudioPlayingDetector (
     Application::ApplicationContext& appContext,
-    const Render::Drivers::Detectors::FullScreenDetector& fullscreenDetector) :
-    AudioPlayingDetector (appContext, fullscreenDetector) {
+    const Render::Drivers::Detectors::FullScreenDetector& fullscreenDetector
+) : AudioPlayingDetector (appContext, fullscreenDetector) {
     this->m_mainloop = pa_mainloop_new ();
     this->m_mainloopApi = pa_mainloop_get_api (this->m_mainloop);
     this->m_context = pa_context_new (this->m_mainloopApi, "wallpaperengine");
@@ -40,25 +44,29 @@ PulseAudioPlayingDetector::PulseAudioPlayingDetector (
     pa_context_connect (this->m_context, nullptr, PA_CONTEXT_NOFLAGS, nullptr);
 
     // lock until pulseaudio allows connection
-    while (pa_context_get_state (this->m_context) != PA_CONTEXT_READY)
-        pa_mainloop_iterate (this->m_mainloop, 1, nullptr);
+    while (pa_context_get_state (this->m_context) != PA_CONTEXT_READY) {
+	pa_mainloop_iterate (this->m_mainloop, 1, nullptr);
+    }
 }
 
 PulseAudioPlayingDetector::~PulseAudioPlayingDetector () {
     if (this->m_context) {
-        pa_context_disconnect (this->m_context);
-        pa_context_unref (this->m_context);
+	pa_context_disconnect (this->m_context);
+	pa_context_unref (this->m_context);
     }
 
-    if (this->m_mainloop)
-        pa_mainloop_free (this->m_mainloop);
+    if (this->m_mainloop) {
+	pa_mainloop_free (this->m_mainloop);
+    }
 }
 
 void PulseAudioPlayingDetector::update () {
-    if (!this->getApplicationContext ().settings.audio.automute)
-        return this->setIsPlaying (false);
-    if (this->getFullscreenDetector ().anythingFullscreen ())
-        return this->setIsPlaying (true);
+    if (!this->getApplicationContext ().settings.audio.automute) {
+	return this->setIsPlaying (false);
+    }
+    if (this->getFullscreenDetector ().anythingFullscreen ()) {
+	return this->setIsPlaying (true);
+    }
 
     // reset playing state
     this->setIsPlaying (false);
@@ -67,8 +75,9 @@ void PulseAudioPlayingDetector::update () {
     pa_operation* op = pa_context_get_server_info (this->m_context, defaultSinkInfoCallback, this);
 
     // wait until all the operations are done
-    while (pa_operation_get_state (op) == PA_OPERATION_RUNNING)
-        pa_mainloop_iterate (this->m_mainloop, 1, nullptr);
+    while (pa_operation_get_state (op) == PA_OPERATION_RUNNING) {
+	pa_mainloop_iterate (this->m_mainloop, 1, nullptr);
+    }
 
     pa_operation_unref (op);
 }

+ 4 - 3
src/WallpaperEngine/Audio/Drivers/Detectors/PulseAudioPlayingDetector.h

@@ -7,14 +7,15 @@
 
 namespace WallpaperEngine::Audio::Drivers::Detectors {
 class PulseAudioPlayingDetector final : public AudioPlayingDetector {
-  public:
+public:
     explicit PulseAudioPlayingDetector (
-        Application::ApplicationContext& appContext, const Render::Drivers::Detectors::FullScreenDetector&);
+	Application::ApplicationContext& appContext, const Render::Drivers::Detectors::FullScreenDetector&
+    );
     ~PulseAudioPlayingDetector () override;
 
     void update () override;
 
-  private:
+private:
     pa_mainloop* m_mainloop = nullptr;
     pa_mainloop_api* m_mainloopApi = nullptr;
     pa_context* m_context = nullptr;

+ 1 - 1
src/WallpaperEngine/Audio/Drivers/Recorders/PlaybackRecorder.cpp

@@ -1,6 +1,6 @@
 #include "PlaybackRecorder.h"
 
 namespace WallpaperEngine::Audio::Drivers::Recorders {
-void PlaybackRecorder::update () {}
+void PlaybackRecorder::update () { }
 
 } // namespace WallpaperEngine::Audio::Drivers::Recorders

+ 4 - 4
src/WallpaperEngine/Audio/Drivers/Recorders/PlaybackRecorder.h

@@ -2,13 +2,13 @@
 
 namespace WallpaperEngine::Audio::Drivers::Recorders {
 class PlaybackRecorder {
-  public:
+public:
     virtual ~PlaybackRecorder () = default;
 
     virtual void update ();
 
-    float audio16 [16] = {0};
-    float audio32 [32] = {0};
-    float audio64 [64] = {0};
+    float audio16[16] = { 0 };
+    float audio32[32] = { 0 };
+    float audio64[64] = { 0 };
 };
 } // namespace WallpaperEngine::Audio::Drivers::Recorders

+ 131 - 109
src/WallpaperEngine/Audio/Drivers/Recorders/PulseAudioPlaybackRecorder.cpp

@@ -5,8 +5,9 @@
 #include <glm/common.hpp>
 
 float movetowards (float current, float target, float maxDelta) {
-    if (abs (target - current) <= maxDelta)
-        return target;
+    if (abs (target - current) <= maxDelta) {
+	return target;
+    }
 
     return current + glm::sign (target - current) * maxDelta;
 }
@@ -14,9 +15,14 @@ float movetowards (float current, float target, float maxDelta) {
 namespace WallpaperEngine::Audio::Drivers::Recorders {
 void pa_stream_notify_cb (pa_stream* stream, void* /*userdata*/) {
     switch (pa_stream_get_state (stream)) {
-        case PA_STREAM_FAILED: sLog.error ("Cannot open stream for capture. Audio processing is disabled"); break;
-        case PA_STREAM_READY: sLog.debug ("Capture stream ready"); break;
-        default: break;
+	case PA_STREAM_FAILED:
+	    sLog.error ("Cannot open stream for capture. Audio processing is disabled");
+	    break;
+	case PA_STREAM_READY:
+	    sLog.debug ("Capture stream ready");
+	    break;
+	default:
+	    break;
     }
 }
 
@@ -28,59 +34,64 @@ void pa_stream_read_cb (pa_stream* stream, const size_t /*nbytes*/, void* userda
     const uint8_t* data = nullptr;
     size_t currentSize;
     if (pa_stream_peek (stream, reinterpret_cast<const void**> (&data), &currentSize) != 0) {
-        sLog.error ("Failed to peek at stream data...");
-        return;
+	sLog.error ("Failed to peek at stream data...");
+	return;
     }
 
     if (data == nullptr && currentSize == 0) {
-        // No data in the buffer, ignore.
-        return;
+	// No data in the buffer, ignore.
+	return;
     }
 
     if (data == nullptr && currentSize > 0) {
-        // Hole in the buffer. We must drop it.
-        if (pa_stream_drop (stream) != 0) {
-            sLog.error ("Failed to drop a hole while capturing!");
-            return;
-        }
+	// Hole in the buffer. We must drop it.
+	if (pa_stream_drop (stream) != 0) {
+	    sLog.error ("Failed to drop a hole while capturing!");
+	    return;
+	}
     } else if (currentSize > 0 && data) {
-        const size_t dataToCopy = std::min (currentSize, WAVE_BUFFER_SIZE - recorder->currentWritePointer);
-
-        // depending on the amount of data available, we might want to read one or multiple frames
-        const size_t end = recorder->currentWritePointer + dataToCopy;
-
-        // this packet will fill the buffer, perform some extra checks for extra full buffers and get the latest one
-        if (end == WAVE_BUFFER_SIZE) {
-            if (const size_t numberOfFullBuffers = (currentSize - dataToCopy) / WAVE_BUFFER_SIZE;
-                numberOfFullBuffers > 0) {
-                // calculate the start of the last block (we need the end of the previous block, hence the - 1)
-                const size_t startOfLastBuffer = std::max(dataToCopy + (numberOfFullBuffers - 1) * WAVE_BUFFER_SIZE, currentSize - WAVE_BUFFER_SIZE);
-                // copy directly into the final buffer
-                memcpy (recorder->audioBuffer, &data [startOfLastBuffer], WAVE_BUFFER_SIZE * sizeof (uint8_t));
-                // copy whatever is left to the read/write buffer
-                recorder->currentWritePointer = currentSize - startOfLastBuffer - WAVE_BUFFER_SIZE;
-                memcpy (recorder->audioBufferTmp, &data [startOfLastBuffer + WAVE_BUFFER_SIZE], recorder->currentWritePointer * sizeof (uint8_t));
-            } else {
-                // okay, no full extra packets available, copy the rest of the data and flip the buffers
-                memcpy (&recorder->audioBufferTmp [recorder->currentWritePointer], data, dataToCopy * sizeof (uint8_t));
-                uint8_t* tmp = recorder->audioBuffer;
-                recorder->audioBuffer = recorder->audioBufferTmp;
-                recorder->audioBufferTmp = tmp;
-                // reset write pointer
-                recorder->currentWritePointer = 0;
-            }
-
-            // signal a new frame is ready
-            recorder->fullFrameReady = true;
-        } else {
-            // copy over available data to the tmp buffer and everything should be set
-            memcpy (&recorder->audioBufferTmp [recorder->currentWritePointer], data, dataToCopy * sizeof (uint8_t));
-            recorder->currentWritePointer += dataToCopy;
-        }
+	const size_t dataToCopy = std::min (currentSize, WAVE_BUFFER_SIZE - recorder->currentWritePointer);
+
+	// depending on the amount of data available, we might want to read one or multiple frames
+	const size_t end = recorder->currentWritePointer + dataToCopy;
+
+	// this packet will fill the buffer, perform some extra checks for extra full buffers and get the latest one
+	if (end == WAVE_BUFFER_SIZE) {
+	    if (const size_t numberOfFullBuffers = (currentSize - dataToCopy) / WAVE_BUFFER_SIZE;
+		numberOfFullBuffers > 0) {
+		// calculate the start of the last block (we need the end of the previous block, hence the - 1)
+		const size_t startOfLastBuffer = std::max (
+		    dataToCopy + (numberOfFullBuffers - 1) * WAVE_BUFFER_SIZE, currentSize - WAVE_BUFFER_SIZE
+		);
+		// copy directly into the final buffer
+		memcpy (recorder->audioBuffer, &data[startOfLastBuffer], WAVE_BUFFER_SIZE * sizeof (uint8_t));
+		// copy whatever is left to the read/write buffer
+		recorder->currentWritePointer = currentSize - startOfLastBuffer - WAVE_BUFFER_SIZE;
+		memcpy (
+		    recorder->audioBufferTmp, &data[startOfLastBuffer + WAVE_BUFFER_SIZE],
+		    recorder->currentWritePointer * sizeof (uint8_t)
+		);
+	    } else {
+		// okay, no full extra packets available, copy the rest of the data and flip the buffers
+		memcpy (&recorder->audioBufferTmp[recorder->currentWritePointer], data, dataToCopy * sizeof (uint8_t));
+		uint8_t* tmp = recorder->audioBuffer;
+		recorder->audioBuffer = recorder->audioBufferTmp;
+		recorder->audioBufferTmp = tmp;
+		// reset write pointer
+		recorder->currentWritePointer = 0;
+	    }
+
+	    // signal a new frame is ready
+	    recorder->fullFrameReady = true;
+	} else {
+	    // copy over available data to the tmp buffer and everything should be set
+	    memcpy (&recorder->audioBufferTmp[recorder->currentWritePointer], data, dataToCopy * sizeof (uint8_t));
+	    recorder->currentWritePointer += dataToCopy;
+	}
     }
 
     if (pa_stream_drop (stream) != 0) {
-        sLog.error ("Failed to drop data after peeking");
+	sLog.error ("Failed to drop data after peeking");
     }
 }
 
@@ -93,7 +104,7 @@ void pa_server_info_cb (pa_context* ctx, const pa_server_info* info, void* userd
     spec.channels = 1;
 
     if (recorder->captureStream) {
-        pa_stream_unref (recorder->captureStream);
+	pa_stream_unref (recorder->captureStream);
     }
 
     recorder->captureStream = pa_stream_new (ctx, "output monitor", &spec, nullptr);
@@ -112,8 +123,9 @@ void pa_server_info_cb (pa_context* ctx, const pa_server_info* info, void* userd
     attr.fragsize = bytesPerSec * 10 / 100;
     attr.maxlength = attr.fragsize + bytesPerSec * 750 / 100;
 
-    if (pa_stream_connect_record (recorder->captureStream, monitor_name.c_str (), &attr, PA_STREAM_ADJUST_LATENCY) != 0) {
-        sLog.error ("Failed to connect to input for recording");
+    if (pa_stream_connect_record (recorder->captureStream, monitor_name.c_str (), &attr, PA_STREAM_ADJUST_LATENCY)
+	!= 0) {
+	sLog.error ("Failed to connect to input for recording");
     }
 }
 
@@ -124,36 +136,39 @@ void pa_context_subscribe_cb (pa_context* ctx, pa_subscription_event_type_t t, u
 
 void pa_context_notify_cb (pa_context* ctx, void* userdata) {
     switch (pa_context_get_state (ctx)) {
-        case PA_CONTEXT_READY: {
-            // set callback
-            pa_context_set_subscribe_callback (ctx, pa_context_subscribe_cb, userdata);
-            // set events mask and enable event callback.
-            pa_operation* o = pa_context_subscribe (
-                ctx, static_cast<pa_subscription_mask_t> (PA_SUBSCRIPTION_MASK_SINK | PA_SUBSCRIPTION_MASK_SOURCE),
-                nullptr, nullptr);
-
-            if (o)
-                pa_operation_unref (o);
-
-            // context being ready means to fetch the sink too
-            pa_context_get_server_info (ctx, &pa_server_info_cb, userdata);
-
-            break;
-        }
-        case PA_CONTEXT_FAILED:
-            sLog.error ("PulseAudio context initialization failed. Audio processing is disabled");
-            break;
-        default:
-            break;
+	case PA_CONTEXT_READY:
+	    {
+		// set callback
+		pa_context_set_subscribe_callback (ctx, pa_context_subscribe_cb, userdata);
+		// set events mask and enable event callback.
+		pa_operation* o = pa_context_subscribe (
+		    ctx, static_cast<pa_subscription_mask_t> (PA_SUBSCRIPTION_MASK_SINK | PA_SUBSCRIPTION_MASK_SOURCE),
+		    nullptr, nullptr
+		);
+
+		if (o) {
+		    pa_operation_unref (o);
+		}
+
+		// context being ready means to fetch the sink too
+		pa_context_get_server_info (ctx, &pa_server_info_cb, userdata);
+
+		break;
+	    }
+	case PA_CONTEXT_FAILED:
+	    sLog.error ("PulseAudio context initialization failed. Audio processing is disabled");
+	    break;
+	default:
+	    break;
     }
 }
 
 PulseAudioPlaybackRecorder::PulseAudioPlaybackRecorder () :
-    m_captureData({
-        .kisscfg = kiss_fftr_alloc (WAVE_BUFFER_SIZE, 0, nullptr, nullptr),
-        .audioBuffer = new uint8_t [WAVE_BUFFER_SIZE],
-        .audioBufferTmp = new uint8_t [WAVE_BUFFER_SIZE]
-    }) {
+    m_captureData (
+	{ .kisscfg = kiss_fftr_alloc (WAVE_BUFFER_SIZE, 0, nullptr, nullptr),
+	  .audioBuffer = new uint8_t[WAVE_BUFFER_SIZE],
+	  .audioBufferTmp = new uint8_t[WAVE_BUFFER_SIZE] }
+    ) {
     this->m_mainloop = pa_mainloop_new ();
     this->m_mainloopApi = pa_mainloop_get_api (this->m_mainloop);
     this->m_context = pa_context_new (this->m_mainloopApi, "wallpaperengine-audioprocessing");
@@ -161,22 +176,23 @@ PulseAudioPlaybackRecorder::PulseAudioPlaybackRecorder () :
     pa_context_set_state_callback (this->m_context, &pa_context_notify_cb, &this->m_captureData);
 
     if (pa_context_connect (this->m_context, nullptr, PA_CONTEXT_NOFLAGS, nullptr) < 0) {
-        sLog.error ("PulseAudio connection failed! Audio processing is disabled");
-        return;
+	sLog.error ("PulseAudio connection failed! Audio processing is disabled");
+	return;
     }
 
     // wait until the context is ready
-    while (pa_context_get_state (this->m_context) != PA_CONTEXT_READY)
-        pa_mainloop_iterate (this->m_mainloop, 1, nullptr);
+    while (pa_context_get_state (this->m_context) != PA_CONTEXT_READY) {
+	pa_mainloop_iterate (this->m_mainloop, 1, nullptr);
+    }
 }
 
 PulseAudioPlaybackRecorder::~PulseAudioPlaybackRecorder () {
     if (m_captureData.captureStream) {
-        pa_stream_unref (m_captureData.captureStream);
+	pa_stream_unref (m_captureData.captureStream);
     }
 
-    delete [] this->m_captureData.audioBufferTmp;
-    delete [] this->m_captureData.audioBuffer;
+    delete[] this->m_captureData.audioBufferTmp;
+    delete[] this->m_captureData.audioBuffer;
     free (this->m_captureData.kisscfg);
 
     pa_context_disconnect (this->m_context);
@@ -188,23 +204,26 @@ void PulseAudioPlaybackRecorder::update () {
 
     // interpolate current values to the destination
     for (int i = 0; i < 64; i++) {
-        this->audio64 [i] = movetowards (this->audio64 [i], this->m_FFTdestination64 [i], 0.3f);
-        if (i >= 32)
-            continue;
-        this->audio32 [i] = movetowards (this->audio32 [i], this->m_FFTdestination32 [i], 0.3f);
-        if (i >= 16)
-            continue;
-        this->audio16 [i] = movetowards (this->audio16 [i], this->m_FFTdestination16 [i], 0.3f);
+	this->audio64[i] = movetowards (this->audio64[i], this->m_FFTdestination64[i], 0.3f);
+	if (i >= 32) {
+	    continue;
+	}
+	this->audio32[i] = movetowards (this->audio32[i], this->m_FFTdestination32[i], 0.3f);
+	if (i >= 16) {
+	    continue;
+	}
+	this->audio16[i] = movetowards (this->audio16[i], this->m_FFTdestination16[i], 0.3f);
     }
 
-    if (!this->m_captureData.fullFrameReady)
-        return;
+    if (!this->m_captureData.fullFrameReady) {
+	return;
+    }
 
     this->m_captureData.fullFrameReady = false;
 
     // convert audio data to deltas so the fft library can properly handle it
-    for (int i = 0; i < WAVE_BUFFER_SIZE; i ++) {
-        this->m_audioFFTbuffer [i] = (this->m_captureData.audioBuffer[i] - 128) / 128.0f;
+    for (int i = 0; i < WAVE_BUFFER_SIZE; i++) {
+	this->m_audioFFTbuffer[i] = (this->m_captureData.audioBuffer[i] - 128) / 128.0f;
     }
 
     // perform full fft pass
@@ -212,20 +231,23 @@ void PulseAudioPlaybackRecorder::update () {
 
     // now reduce to the different bands
     // use just one for loop to produce all 3
-    for (int band = 0; band < 64; band ++) {
-        int index = band * 2;
-        float f1 = this->m_FFTinfo[index].r;
-        float f2 = this->m_FFTinfo[index].i;
-        f2 = f1 * f1 + f2 * f2; // magnitude
-        f1 = 0.0f;
-
-        if (f2 > 0.0f) {
-            f1 = 0.35f * log10 (f2);
-        }
-
-        this->m_FFTdestination64 [band] = fmin (1.0f, f1 * static_cast<float> (2.0f - pow (M_E, (1.0f - band / 63.0f) * 1.0f - 0.5f)));
-        this->m_FFTdestination32 [band >> 1] = fmin (1.0f, f1 * static_cast<float> (2.0f - pow (M_E, (1.0f - band / 31.0f) * 1.0f - 0.5f)));
-        this->m_FFTdestination16 [band >> 2] = fmin (1.0f, f1 * static_cast<float> (2.0f - pow (M_E, (1.0f - band / 15.0f) * 1.0f - 0.5f)));
+    for (int band = 0; band < 64; band++) {
+	int index = band * 2;
+	float f1 = this->m_FFTinfo[index].r;
+	float f2 = this->m_FFTinfo[index].i;
+	f2 = f1 * f1 + f2 * f2; // magnitude
+	f1 = 0.0f;
+
+	if (f2 > 0.0f) {
+	    f1 = 0.35f * log10 (f2);
+	}
+
+	this->m_FFTdestination64[band]
+	    = fmin (1.0f, f1 * static_cast<float> (2.0f - pow (M_E, (1.0f - band / 63.0f) * 1.0f - 0.5f)));
+	this->m_FFTdestination32[band >> 1]
+	    = fmin (1.0f, f1 * static_cast<float> (2.0f - pow (M_E, (1.0f - band / 31.0f) * 1.0f - 0.5f)));
+	this->m_FFTdestination16[band >> 2]
+	    = fmin (1.0f, f1 * static_cast<float> (2.0f - pow (M_E, (1.0f - band / 15.0f) * 1.0f - 0.5f)));
     }
 }
 

+ 13 - 15
src/WallpaperEngine/Audio/Drivers/Recorders/PulseAudioPlaybackRecorder.h

@@ -10,17 +10,17 @@ namespace WallpaperEngine::Audio::Drivers::Recorders {
 class PlaybackRecorder;
 
 class PulseAudioPlaybackRecorder final : public PlaybackRecorder {
-  public:
+public:
     /**
      * Struct that contains all the required data for the PulseAudio callbacks
      */
     struct PulseAudioData {
-        kiss_fftr_cfg kisscfg;
-        uint8_t* audioBuffer;
-        uint8_t* audioBufferTmp;
-        size_t currentWritePointer;
-        bool fullFrameReady;
-        pa_stream* captureStream;
+	kiss_fftr_cfg kisscfg;
+	uint8_t* audioBuffer;
+	uint8_t* audioBufferTmp;
+	size_t currentWritePointer;
+	bool fullFrameReady;
+	pa_stream* captureStream;
     };
 
     PulseAudioPlaybackRecorder ();
@@ -28,18 +28,16 @@ class PulseAudioPlaybackRecorder final : public PlaybackRecorder {
 
     void update () override;
 
-  private:
+private:
     pa_mainloop* m_mainloop;
     pa_mainloop_api* m_mainloopApi;
     pa_context* m_context;
     PulseAudioData m_captureData;
 
-    float m_audioFFTbuffer [WAVE_BUFFER_SIZE] = {0.0f};
-    kiss_fft_cpx m_FFTinfo [WAVE_BUFFER_SIZE / 2 + 1] = {
-        {.r = 0.0f, .i = 0.0f}
-    };
-    float m_FFTdestination64 [64] = {0};
-    float m_FFTdestination32 [32] = {0};
-    float m_FFTdestination16 [16] = {0};
+    float m_audioFFTbuffer[WAVE_BUFFER_SIZE] = { 0.0f };
+    kiss_fft_cpx m_FFTinfo[WAVE_BUFFER_SIZE / 2 + 1] = { { .r = 0.0f, .i = 0.0f } };
+    float m_FFTdestination64[64] = { 0 };
+    float m_FFTdestination32[32] = { 0 };
+    float m_FFTdestination16[16] = { 0 };
 };
 } // namespace WallpaperEngine::Audio::Drivers::Recorders

+ 89 - 98
src/WallpaperEngine/Audio/Drivers/SDLAudioDriver.cpp

@@ -13,85 +13,85 @@ void audio_callback (void* userdata, uint8_t* streamData, int length) {
     memset (streamData, 0, length);
 
     // if audio is playing do not do anything here!
-    if (driver->getAudioDetector ().anythingPlaying ())
-        return;
+    if (driver->getAudioDetector ().anythingPlaying ()) {
+	return;
+    }
 
     for (const auto& buffer : driver->getStreams ()) {
-        uint8_t* streamDataPointer = streamData;
-        int streamLength = length;
-
-        // sound is not initialized or stopped and is not in loop mode
-        // ignore mixing it in
-        if (!buffer->stream->isInitialized ())
-            continue;
-
-        // check if queue is empty and signal the read thread
-        if (buffer->stream->isQueueEmpty ()) {
-            SDL_CondSignal (buffer->stream->getWaitCondition ());
-            continue;
-        }
-
-        while (streamLength > 0 && driver->getApplicationContext ().state.general.keepRunning) {
-            if (buffer->audio_buf_index >= buffer->audio_buf_size) {
-                // get more data to fill the buffer
-                int audio_size = buffer->stream->decodeFrame (buffer->audio_buf, sizeof (buffer->audio_buf));
-
-                if (audio_size < 0) {
-                    // fallback for errors, silence
-                    buffer->audio_buf_size = 1024;
-                    memset (buffer->audio_buf, 0, buffer->audio_buf_size);
-                } else {
-                    buffer->audio_buf_size = audio_size;
-                }
-
-                buffer->audio_buf_index = 0;
-            }
-
-            int len1 = buffer->audio_buf_size - buffer->audio_buf_index;
-
-            if (len1 > streamLength)
-                len1 = streamLength;
-
-            // mix the audio
-            SDL_MixAudioFormat (
-                streamDataPointer, &buffer->audio_buf [buffer->audio_buf_index], driver->getSpec ().format,
-                len1, driver->getApplicationContext ().state.audio.volume);
-
-            streamLength -= len1;
-            streamDataPointer += len1;
-            buffer->audio_buf_index += len1;
-        }
+	uint8_t* streamDataPointer = streamData;
+	int streamLength = length;
+
+	// sound is not initialized or stopped and is not in loop mode
+	// ignore mixing it in
+	if (!buffer->stream->isInitialized ()) {
+	    continue;
+	}
+
+	// check if queue is empty and signal the read thread
+	if (buffer->stream->isQueueEmpty ()) {
+	    SDL_CondSignal (buffer->stream->getWaitCondition ());
+	    continue;
+	}
+
+	while (streamLength > 0 && driver->getApplicationContext ().state.general.keepRunning) {
+	    if (buffer->audio_buf_index >= buffer->audio_buf_size) {
+		// get more data to fill the buffer
+		int audio_size = buffer->stream->decodeFrame (buffer->audio_buf, sizeof (buffer->audio_buf));
+
+		if (audio_size < 0) {
+		    // fallback for errors, silence
+		    buffer->audio_buf_size = 1024;
+		    memset (buffer->audio_buf, 0, buffer->audio_buf_size);
+		} else {
+		    buffer->audio_buf_size = audio_size;
+		}
+
+		buffer->audio_buf_index = 0;
+	    }
+
+	    int len1 = buffer->audio_buf_size - buffer->audio_buf_index;
+
+	    if (len1 > streamLength) {
+		len1 = streamLength;
+	    }
+
+	    // mix the audio
+	    SDL_MixAudioFormat (
+		streamDataPointer, &buffer->audio_buf[buffer->audio_buf_index], driver->getSpec ().format, len1,
+		driver->getApplicationContext ().state.audio.volume
+	    );
+
+	    streamLength -= len1;
+	    streamDataPointer += len1;
+	    buffer->audio_buf_index += len1;
+	}
     }
 }
 
 SDLAudioDriver::SDLAudioDriver (
     Application::ApplicationContext& applicationContext, Detectors::AudioPlayingDetector& detector,
     Recorders::PlaybackRecorder& recorder
-) :
-    AudioDriver (applicationContext, detector, recorder),
-    m_audioSpec () {
+) : AudioDriver (applicationContext, detector, recorder), m_audioSpec () {
     if (SDL_InitSubSystem (SDL_INIT_AUDIO) < 0) {
-        sLog.error ("Cannot initialize SDL audio system, SDL_GetError: ", SDL_GetError ());
-        sLog.error ("Continuing without audio support");
+	sLog.error ("Cannot initialize SDL audio system, SDL_GetError: ", SDL_GetError ());
+	sLog.error ("Continuing without audio support");
 
-        return;
+	return;
     }
 
-    const SDL_AudioSpec requestedSpec = {
-        .freq = 48000,
-        .format = AUDIO_F32,
-        .channels = 2,
-        .samples = SDL_AUDIO_BUFFER_SIZE,
-        .callback = audio_callback,
-        .userdata = this
-    };
+    const SDL_AudioSpec requestedSpec = { .freq = 48000,
+					  .format = AUDIO_F32,
+					  .channels = 2,
+					  .samples = SDL_AUDIO_BUFFER_SIZE,
+					  .callback = audio_callback,
+					  .userdata = this };
 
-    this->m_deviceID =
-        SDL_OpenAudioDevice (nullptr, false, &requestedSpec, &this->m_audioSpec, SDL_AUDIO_ALLOW_ANY_CHANGE);
+    this->m_deviceID
+	= SDL_OpenAudioDevice (nullptr, false, &requestedSpec, &this->m_audioSpec, SDL_AUDIO_ALLOW_ANY_CHANGE);
 
     if (this->m_deviceID == 0) {
-        sLog.error ("SDL_OpenAudioDevice: ", SDL_GetError ());
-        return;
+	sLog.error ("SDL_OpenAudioDevice: ", SDL_GetError ());
+	return;
     }
 
     SDL_PauseAudioDevice (this->m_deviceID, 0);
@@ -100,53 +100,44 @@ SDLAudioDriver::SDLAudioDriver (
 }
 
 SDLAudioDriver::~SDLAudioDriver () {
-    if (!this->m_initialized)
-        return;
+    if (!this->m_initialized) {
+	return;
+    }
 
     if (this->m_deviceID != 0) {
-        SDL_CloseAudioDevice (this->m_deviceID);
+	SDL_CloseAudioDevice (this->m_deviceID);
     }
 
     SDL_QuitSubSystem (SDL_INIT_AUDIO);
 }
 
-void SDLAudioDriver::addStream (AudioStream* stream) {
-    this->m_streams.push_back (new SDLAudioBuffer {stream});
-}
+void SDLAudioDriver::addStream (AudioStream* stream) { this->m_streams.push_back (new SDLAudioBuffer { stream }); }
 
-const std::vector<SDLAudioBuffer*>& SDLAudioDriver::getStreams () {
-    return this->m_streams;
-}
+const std::vector<SDLAudioBuffer*>& SDLAudioDriver::getStreams () { return this->m_streams; }
 
 AVSampleFormat SDLAudioDriver::getFormat () const {
     switch (this->m_audioSpec.format) {
-        case AUDIO_U8:
-        case AUDIO_S8:
-            return AV_SAMPLE_FMT_U8;
-        case AUDIO_U16MSB:
-        case AUDIO_U16LSB:
-        case AUDIO_S16LSB:
-        case AUDIO_S16MSB:
-            return AV_SAMPLE_FMT_S16;
-        case AUDIO_S32LSB:
-        case AUDIO_S32MSB:
-            return AV_SAMPLE_FMT_S32;
-        case AUDIO_F32LSB:
-        case AUDIO_F32MSB:
-            return AV_SAMPLE_FMT_FLT;
-        default:
-            sLog.exception ("Cannot convert from SDL format to ffmpeg format, aborting...");
+	case AUDIO_U8:
+	case AUDIO_S8:
+	    return AV_SAMPLE_FMT_U8;
+	case AUDIO_U16MSB:
+	case AUDIO_U16LSB:
+	case AUDIO_S16LSB:
+	case AUDIO_S16MSB:
+	    return AV_SAMPLE_FMT_S16;
+	case AUDIO_S32LSB:
+	case AUDIO_S32MSB:
+	    return AV_SAMPLE_FMT_S32;
+	case AUDIO_F32LSB:
+	case AUDIO_F32MSB:
+	    return AV_SAMPLE_FMT_FLT;
+	default:
+	    sLog.exception ("Cannot convert from SDL format to ffmpeg format, aborting...");
     }
 }
 
-int SDLAudioDriver::getSampleRate () const {
-    return this->m_audioSpec.freq;
-}
+int SDLAudioDriver::getSampleRate () const { return this->m_audioSpec.freq; }
 
-int SDLAudioDriver::getChannels () const {
-    return this->m_audioSpec.channels;
-}
+int SDLAudioDriver::getChannels () const { return this->m_audioSpec.channels; }
 
-const SDL_AudioSpec& SDLAudioDriver::getSpec () const {
-    return this->m_audioSpec;
-}
+const SDL_AudioSpec& SDLAudioDriver::getSpec () const { return this->m_audioSpec; }

+ 6 - 5
src/WallpaperEngine/Audio/Drivers/SDLAudioDriver.h

@@ -16,7 +16,7 @@ namespace WallpaperEngine::Audio::Drivers {
  */
 struct SDLAudioBuffer {
     AudioStream* stream = nullptr;
-    uint8_t audio_buf [(MAX_AUDIO_FRAME_SIZE * 3) / 2] = {0};
+    uint8_t audio_buf[(MAX_AUDIO_FRAME_SIZE * 3) / 2] = { 0 };
     unsigned int audio_buf_size = 0;
     unsigned int audio_buf_index = 0;
 };
@@ -25,10 +25,11 @@ struct SDLAudioBuffer {
  * SDL's audio driver implementation
  */
 class SDLAudioDriver final : public AudioDriver {
-  public:
+public:
     SDLAudioDriver (
-        Application::ApplicationContext& applicationContext, Detectors::AudioPlayingDetector& detector,
-        Recorders::PlaybackRecorder& recorder);
+	Application::ApplicationContext& applicationContext, Detectors::AudioPlayingDetector& detector,
+	Recorders::PlaybackRecorder& recorder
+    );
     ~SDLAudioDriver () override;
 
     /** @inheritdoc */
@@ -49,7 +50,7 @@ class SDLAudioDriver final : public AudioDriver {
      */
     [[nodiscard]] const SDL_AudioSpec& getSpec () const;
 
-  private:
+private:
     /** The device's ID */
     SDL_AudioDeviceID m_deviceID;
     /** If the driver is initialized or not */

+ 44 - 49
src/WallpaperEngine/Data/Assets/Texture.h

@@ -1,10 +1,10 @@
 #pragma once
 
 #include <cstdint>
+#include <map>
 #include <memory>
 #include <string>
 #include <vector>
-#include <map>
 
 #include "Types.h"
 
@@ -25,45 +25,45 @@ enum AnimatedVersion {
 
 enum FIF {
     FIF_UNKNOWN = -1,
-    FIF_BMP	= 0,
-    FIF_ICO	= 1,
-    FIF_JPEG	= 2,
-    FIF_JNG	= 3,
-    FIF_KOALA	= 4,
-    FIF_LBM	= 5,
-    FIF_IFF     = FIF_LBM,
-    FIF_MNG	= 6,
-    FIF_PBM	= 7,
-    FIF_PBMRAW	= 8,
-    FIF_PCD	= 9,
-    FIF_PCX	= 10,
-    FIF_PGM	= 11,
-    FIF_PGMRAW	= 12,
-    FIF_PNG	= 13,
-    FIF_PPM	= 14,
-    FIF_PPMRAW	= 15,
-    FIF_RAS	= 16,
-    FIF_TARGA	= 17,
-    FIF_TIFF	= 18,
-    FIF_WBMP	= 19,
-    FIF_PSD	= 20,
-    FIF_CUT	= 21,
-    FIF_XBM	= 22,
-    FIF_XPM	= 23,
-    FIF_DDS	= 24,
-    FIF_GIF     = 25,
-    FIF_HDR	= 26,
-    FIF_FAXG3	= 27,
-    FIF_SGI	= 28,
-    FIF_EXR	= 29,
-    FIF_J2K	= 30,
-    FIF_JP2	= 31,
-    FIF_PFM	= 32,
-    FIF_PICT	= 33,
-    FIF_RAW	= 34,
-    FIF_WEBP	= 35,
-    FIF_MP4     = FIF_WEBP,
-    FIF_JXR	= 36
+    FIF_BMP = 0,
+    FIF_ICO = 1,
+    FIF_JPEG = 2,
+    FIF_JNG = 3,
+    FIF_KOALA = 4,
+    FIF_LBM = 5,
+    FIF_IFF = FIF_LBM,
+    FIF_MNG = 6,
+    FIF_PBM = 7,
+    FIF_PBMRAW = 8,
+    FIF_PCD = 9,
+    FIF_PCX = 10,
+    FIF_PGM = 11,
+    FIF_PGMRAW = 12,
+    FIF_PNG = 13,
+    FIF_PPM = 14,
+    FIF_PPMRAW = 15,
+    FIF_RAS = 16,
+    FIF_TARGA = 17,
+    FIF_TIFF = 18,
+    FIF_WBMP = 19,
+    FIF_PSD = 20,
+    FIF_CUT = 21,
+    FIF_XBM = 22,
+    FIF_XPM = 23,
+    FIF_DDS = 24,
+    FIF_GIF = 25,
+    FIF_HDR = 26,
+    FIF_FAXG3 = 27,
+    FIF_SGI = 28,
+    FIF_EXR = 29,
+    FIF_J2K = 30,
+    FIF_JP2 = 31,
+    FIF_PFM = 32,
+    FIF_PICT = 33,
+    FIF_RAW = 34,
+    FIF_WEBP = 35,
+    FIF_MP4 = FIF_WEBP,
+    FIF_JXR = 36
 };
 
 enum TextureFormat {
@@ -91,9 +91,8 @@ enum TextureFlags {
     TextureFlags_IsGif = 4,
     TextureFlags_ClampUVsBorder = 8,
     TextureFlags_AlphaChannelPriority = 524288, // Indicates RG88/R8 format where alpha is in G/R channel
-    TextureFlags_All =
-        TextureFlags_NoInterpolation | TextureFlags_ClampUVs |
-        TextureFlags_IsGif | TextureFlags_ClampUVsBorder | TextureFlags_AlphaChannelPriority,
+    TextureFlags_All = TextureFlags_NoInterpolation | TextureFlags_ClampUVs | TextureFlags_IsGif
+	| TextureFlags_ClampUVsBorder | TextureFlags_AlphaChannelPriority,
 };
 
 struct Mipmap {
@@ -170,12 +169,8 @@ struct Texture {
     uint32_t spritesheetFrames = 0;
     float spritesheetDuration = 0.0f;
 
-    [[nodiscard]] bool isAnimated () const {
-        return (flags & TextureFlags_IsGif) == TextureFlags_IsGif;
-    }
+    [[nodiscard]] bool isAnimated () const { return (flags & TextureFlags_IsGif) == TextureFlags_IsGif; }
 
-    [[nodiscard]] bool hasSpritesheet () const {
-        return spritesheetFrames > 0;
-    }
+    [[nodiscard]] bool hasSpritesheet () const { return spritesheetFrames > 0; }
 };
 }

+ 7 - 7
src/WallpaperEngine/Data/Assets/Types.h

@@ -10,11 +10,11 @@ struct Texture;
 struct Package;
 struct FileEntry;
 
-using MipmapSharedPtr = std::shared_ptr <Mipmap>;
-using FrameSharedPtr = std::shared_ptr <Frame>;
-using TextureUniquePtr = std::unique_ptr <Texture>;
-using FileEntryUniquePtr = std::unique_ptr <FileEntry>;
-using PackageUniquePtr = std::unique_ptr <Package>;
-using MipmapList = std::vector <MipmapSharedPtr>;
-using FileEntryList = std::vector <FileEntryUniquePtr>;
+using MipmapSharedPtr = std::shared_ptr<Mipmap>;
+using FrameSharedPtr = std::shared_ptr<Frame>;
+using TextureUniquePtr = std::unique_ptr<Texture>;
+using FileEntryUniquePtr = std::unique_ptr<FileEntry>;
+using PackageUniquePtr = std::unique_ptr<Package>;
+using MipmapList = std::vector<MipmapSharedPtr>;
+using FileEntryList = std::vector<FileEntryUniquePtr>;
 }

+ 8 - 9
src/WallpaperEngine/Data/Builders/UserSettingBuilder.h

@@ -6,16 +6,15 @@
 namespace WallpaperEngine::Data::Builders {
 using namespace WallpaperEngine::Data::Model;
 class UserSettingBuilder {
-  public:
-    template <typename T>
-    static UserSettingUniquePtr fromValue (T defaultValue) {
-        DynamicValueUniquePtr value = std::make_unique <DynamicValue> (defaultValue);
+public:
+    template <typename T> static UserSettingUniquePtr fromValue (T defaultValue) {
+	DynamicValueUniquePtr value = std::make_unique<DynamicValue> (defaultValue);
 
-        return std::make_unique <UserSetting> (UserSetting {
-            .value = std::move (value),
-            .property = PropertySharedPtr (),
-            .condition = std::nullopt,
-        });
+	return std::make_unique<UserSetting> (UserSetting {
+	    .value = std::move (value),
+	    .property = PropertySharedPtr (),
+	    .condition = std::nullopt,
+	});
     }
 };
 } // namespace WallpaperEngine::Data::Builders

+ 79 - 120
src/WallpaperEngine/Data/Builders/VectorBuilder.h

@@ -1,9 +1,9 @@
 #pragma once
 
 #include <cstring>
-#include <string>
 #include <glm/detail/qualifier.hpp>
 #include <glm/detail/type_vec1.hpp>
+#include <string>
 
 #include "WallpaperEngine/Data/Utils/SFINAE.h"
 #include "WallpaperEngine/Logging/Log.h"
@@ -20,10 +20,9 @@ class VectorBuilder {
      * @param str
      * @return
      */
-    template <typename type>
-    static type convert (const char* str);
+    template <typename type> static type convert (const char* str);
 
-  public:
+public:
     /**
      * Takes the string and returns the vector size (2, 3 or 4)
      *
@@ -33,24 +32,24 @@ class VectorBuilder {
      * @return
      */
     static int preparseSize (const std::string& str) {
-        const char* p = str.c_str ();
-        const char* first = strchr (p, ' ');
-        const char* second = first ? strchr (first + 1, ' ') : nullptr;
-        const char* third = second ? strchr (second + 1, ' ') : nullptr;
+	const char* p = str.c_str ();
+	const char* first = strchr (p, ' ');
+	const char* second = first ? strchr (first + 1, ' ') : nullptr;
+	const char* third = second ? strchr (second + 1, ' ') : nullptr;
 
-        if (first == nullptr) {
-            sLog.exception ("Invalid vector format: " + str + " (too few values, expected: 2, 3 or 4)");
-        }
+	if (first == nullptr) {
+	    sLog.exception ("Invalid vector format: " + str + " (too few values, expected: 2, 3 or 4)");
+	}
 
-        if (second == nullptr) {
-            return 2;
-        }
+	if (second == nullptr) {
+	    return 2;
+	}
 
-        if (third == nullptr) {
-            return 3;
-        }
+	if (third == nullptr) {
+	    return 3;
+	}
 
-        return 4;
+	return 4;
     }
 
     /**
@@ -68,130 +67,90 @@ class VectorBuilder {
      */
     template <int length, typename type, glm::qualifier qualifier>
     [[nodiscard]] static glm::vec<length, type, qualifier> parse (const std::string& str) {
-        // ensure a valid type is used, only 1 to 4 vectors are supported
-        static_assert (length >= 1 && length <= 4, "Invalid vector length");
-
-        const char* p = str.c_str ();
-
-        // get up to 4 spaces
-        const char* first = strchr (p, ' ');
-        const char* second = first ? strchr (first + 1, ' ') : nullptr;
-        const char* third = second ? strchr (second + 1, ' ') : nullptr;
-
-        // validate lengths against what was found in the strings
-        if constexpr (length == 1) {
-            if (first != nullptr) {
-                sLog.exception ("Invalid vector format: " + str + " (too many values, expected: ", length, ")");
-            }
-        } else if constexpr (length == 2) {
-            if (first == nullptr) {
-                sLog.exception ("Invalid vector format: " + str + " (too few values, expected: ", length, ")");
-            }
-
-            if (second != nullptr) {
-                sLog.exception ("Invalid vector format: " + str + " (too many values, expected: ", length, ")");
-            }
-        } else if constexpr (length == 3) {
-            if (first == nullptr || second == nullptr) {
-                sLog.exception ("Invalid vector format: " + str + " (too few values, expected: ", length, ")");
-            }
-            if (third != nullptr) {
-                sLog.exception ("Invalid vector format: " + str + " (too many values, expected: ", length, ")");
-            }
-        } else if constexpr (length == 4) {
-            if (first == nullptr || second == nullptr || third == nullptr) {
-                sLog.exception ("Invalid vector format: " + str + " (too few values, expected: ", length, ")");
-            }
-        }
-
-        // lengths validated, values can be used directly without issues
-        if constexpr (length == 1) {
-            return {
-                convert <type> (p)
-            };
-        } else if constexpr (length == 2) {
-            return {
-                convert <type> (p),
-                convert <type> (first + 1)
-            };
-        } else if constexpr (length == 3) {
-            return {
-                convert <type> (p),
-                convert <type> (first + 1),
-                convert <type> (second + 1)
-            };
-        } else if constexpr (length == 4) {
-            return {
-                convert <type> (p),
-                convert <type> (first + 1),
-                convert <type> (second + 1),
-                convert <type> (third + 1)
-            };
-        }
+	// ensure a valid type is used, only 1 to 4 vectors are supported
+	static_assert (length >= 1 && length <= 4, "Invalid vector length");
+
+	const char* p = str.c_str ();
+
+	// get up to 4 spaces
+	const char* first = strchr (p, ' ');
+	const char* second = first ? strchr (first + 1, ' ') : nullptr;
+	const char* third = second ? strchr (second + 1, ' ') : nullptr;
+
+	// validate lengths against what was found in the strings
+	if constexpr (length == 1) {
+	    if (first != nullptr) {
+		sLog.exception ("Invalid vector format: " + str + " (too many values, expected: ", length, ")");
+	    }
+	} else if constexpr (length == 2) {
+	    if (first == nullptr) {
+		sLog.exception ("Invalid vector format: " + str + " (too few values, expected: ", length, ")");
+	    }
+
+	    if (second != nullptr) {
+		sLog.exception ("Invalid vector format: " + str + " (too many values, expected: ", length, ")");
+	    }
+	} else if constexpr (length == 3) {
+	    if (first == nullptr || second == nullptr) {
+		sLog.exception ("Invalid vector format: " + str + " (too few values, expected: ", length, ")");
+	    }
+	    if (third != nullptr) {
+		sLog.exception ("Invalid vector format: " + str + " (too many values, expected: ", length, ")");
+	    }
+	} else if constexpr (length == 4) {
+	    if (first == nullptr || second == nullptr || third == nullptr) {
+		sLog.exception ("Invalid vector format: " + str + " (too few values, expected: ", length, ")");
+	    }
+	}
+
+	// lengths validated, values can be used directly without issues
+	if constexpr (length == 1) {
+	    return { convert<type> (p) };
+	} else if constexpr (length == 2) {
+	    return { convert<type> (p), convert<type> (first + 1) };
+	} else if constexpr (length == 3) {
+	    return { convert<type> (p), convert<type> (first + 1), convert<type> (second + 1) };
+	} else if constexpr (length == 4) {
+	    return { convert<type> (p), convert<type> (first + 1), convert<type> (second + 1),
+		     convert<type> (third + 1) };
+	}
     }
     template <typename T, typename std::enable_if_t<is_glm_vec<T>::value, int> = 0>
     [[nodiscard]] static T parse (const std::string& str) {
-        constexpr int length = GlmVecTraits<T>::length;
-        constexpr glm::qualifier qualifier = GlmVecTraits<T>::qualifier;
+	constexpr int length = GlmVecTraits<T>::length;
+	constexpr glm::qualifier qualifier = GlmVecTraits<T>::qualifier;
 
-        // call the specialized version of the function
-        return parse<length, typename GlmVecTraits<T>::type, qualifier> (str);
+	// call the specialized version of the function
+	return parse<length, typename GlmVecTraits<T>::type, qualifier> (str);
     }
 };
 
-template <>
-inline float VectorBuilder::convert<float> (const char* str) {
-    return std::strtof (str, nullptr);
-}
+template <> inline float VectorBuilder::convert<float> (const char* str) { return std::strtof (str, nullptr); }
 
-template <>
-inline int VectorBuilder::convert<int> (const char* str) {
-    return std::stoi (str);
-}
+template <> inline int VectorBuilder::convert<int> (const char* str) { return std::stoi (str); }
 
-template <>
-inline unsigned int VectorBuilder::convert<unsigned int> (const char* str) {
+template <> inline unsigned int VectorBuilder::convert<unsigned int> (const char* str) {
     return std::strtoul (str, nullptr, 10);
 }
 
-template <>
-inline double VectorBuilder::convert<double> (const char* str) {
-    return std::strtod (str, nullptr);
-}
+template <> inline double VectorBuilder::convert<double> (const char* str) { return std::strtod (str, nullptr); }
 
-template <>
-inline uint8_t VectorBuilder::convert<uint8_t> (const char* str) {
-    return std::strtoul (str, nullptr, 10);
-}
+template <> inline uint8_t VectorBuilder::convert<uint8_t> (const char* str) { return std::strtoul (str, nullptr, 10); }
 
-template <>
-inline uint16_t VectorBuilder::convert<uint16_t> (const char* str) {
+template <> inline uint16_t VectorBuilder::convert<uint16_t> (const char* str) {
     return std::strtoul (str, nullptr, 10);
 }
 
-template <>
-inline uint64_t VectorBuilder::convert<uint64_t> (const char* str) {
+template <> inline uint64_t VectorBuilder::convert<uint64_t> (const char* str) {
     return std::strtoull (str, nullptr, 10);
 }
 
-template <>
-inline int8_t VectorBuilder::convert<int8_t> (const char* str) {
-    return std::strtol (str, nullptr, 10);
-}
+template <> inline int8_t VectorBuilder::convert<int8_t> (const char* str) { return std::strtol (str, nullptr, 10); }
 
-template <>
-inline int16_t VectorBuilder::convert<int16_t> (const char* str) {
-    return std::strtol (str, nullptr, 10);
-}
+template <> inline int16_t VectorBuilder::convert<int16_t> (const char* str) { return std::strtol (str, nullptr, 10); }
 
-template <>
-inline int64_t VectorBuilder::convert<int64_t> (const char* str) {
-    return std::strtoll (str, nullptr, 10);
-}
+template <> inline int64_t VectorBuilder::convert<int64_t> (const char* str) { return std::strtoll (str, nullptr, 10); }
 
-template <>
-inline bool VectorBuilder::convert<bool> (const char* str) {
-    return std::strtoul (str, nullptr, 10) > 0;
-}
+template <> inline bool VectorBuilder::convert<bool> (const char* str) { return std::strtoul (str, nullptr, 10) > 0; }
 
 } // namespace WallpaperEngine::Data::Parsers

+ 124 - 130
src/WallpaperEngine/Data/Dumpers/StringPrinter.cpp

@@ -8,42 +8,41 @@ using namespace WallpaperEngine::Data::Dumpers;
 using namespace WallpaperEngine::Data::Model;
 
 StringPrinter::StringPrinter (std::string indentationCharacter) :
-    m_out (&this->m_buffer),
-    m_indentationCharacter (std::move(indentationCharacter)) { }
+    m_out (&this->m_buffer), m_indentationCharacter (std::move (indentationCharacter)) { }
 
 void StringPrinter::printWallpaper (const Wallpaper& wallpaper) {
-    const bool isScene = wallpaper.is <Scene> ();
-    const bool isVideo = wallpaper.is <Video> ();
-    const bool isWeb = wallpaper.is <Web> ();
+    const bool isScene = wallpaper.is<Scene> ();
+    const bool isVideo = wallpaper.is<Video> ();
+    const bool isWeb = wallpaper.is<Web> ();
 
     if (isVideo) {
-        const auto video = wallpaper.as <Video> ();
+	const auto video = wallpaper.as<Video> ();
 
-        this->m_out << "Video wallpaper: " << video->filename;
-        this->lineEnd ();
+	this->m_out << "Video wallpaper: " << video->filename;
+	this->lineEnd ();
     } else if (isWeb) {
-        const auto web = wallpaper.as <Web> ();
+	const auto web = wallpaper.as<Web> ();
 
-        this->m_out << "Web wallpaper: " << web->filename;
-        this->lineEnd ();
+	this->m_out << "Web wallpaper: " << web->filename;
+	this->lineEnd ();
     } else if (isScene) {
-        const auto scene = wallpaper.as <Scene> ();
+	const auto scene = wallpaper.as<Scene> ();
 
-        this->m_out << "Scene wallpaper: ";
-        this->increaseIndentation ();
-        this->lineEnd ();
+	this->m_out << "Scene wallpaper: ";
+	this->increaseIndentation ();
+	this->lineEnd ();
 
-        // TODO: IMPLEMENT FBO PRINTING, AS THIS WASN'T REALLY REFLECTION HOW IT ACTUALLY WORKS
-        this->m_out << "Objects count: " << scene->objects.size ();
-        this->increaseIndentation ();
+	// TODO: IMPLEMENT FBO PRINTING, AS THIS WASN'T REALLY REFLECTION HOW IT ACTUALLY WORKS
+	this->m_out << "Objects count: " << scene->objects.size ();
+	this->increaseIndentation ();
 
-        for (const auto& object : scene->objects) {
-            this->lineEnd ();
-            this->printObject (*object);
-            this->lineEnd ();
-        }
+	for (const auto& object : scene->objects) {
+	    this->lineEnd ();
+	    this->printObject (*object);
+	    this->lineEnd ();
+	}
 
-        this->decreaseIndentation ();
+	this->decreaseIndentation ();
     }
 }
 
@@ -55,15 +54,15 @@ void StringPrinter::printObject (const Object& object) {
     this->m_out << "Dependencies (" << object.dependencies.size () << "): ";
 
     for (const auto& dependency : object.dependencies) {
-        this->m_out << dependency << ", ";
+	this->m_out << dependency << ", ";
     }
 
-    if (object.is <Image> ()) {
-        this->lineEnd ();
-        this->printImage (*object.as <Image> ());
-    } else if (object.is <Sound> ()) {
-        this->lineEnd ();
-        this->printSound (*object.as <Sound> ());
+    if (object.is<Image> ()) {
+	this->lineEnd ();
+	this->printImage (*object.as<Image> ());
+    } else if (object.is<Sound> ()) {
+	this->lineEnd ();
+	this->printSound (*object.as<Sound> ());
     }
 
     this->decreaseIndentation ();
@@ -77,8 +76,8 @@ void StringPrinter::printImage (const Image& image) {
     this->increaseIndentation ();
 
     for (const auto& effect : image.effects) {
-        this->lineEnd ();
-        this->printImageEffect (*effect);
+	this->lineEnd ();
+	this->printImageEffect (*effect);
     }
 
     this->decreaseIndentation ();
@@ -89,8 +88,8 @@ void StringPrinter::printSound (const Sound& sound) {
     this->increaseIndentation ();
 
     for (const auto& filename : sound.sounds) {
-        this->lineEnd ();
-        this->m_out << "Filename " << filename;
+	this->lineEnd ();
+	this->m_out << "Filename " << filename;
     }
 
     this->decreaseIndentation ();
@@ -113,13 +112,13 @@ void StringPrinter::printModel (const ModelStruct& model) {
     this->lineEnd ();
 
     if (model.width.has_value ()) {
-        this->m_out << "Width: " << model.width.value ();
-        this->lineEnd ();
+	this->m_out << "Width: " << model.width.value ();
+	this->lineEnd ();
     }
 
     if (model.height.has_value ()) {
-        this->m_out << "Height: " << model.height.value ();
-        this->lineEnd ();
+	this->m_out << "Height: " << model.height.value ();
+	this->lineEnd ();
     }
 
     this->printMaterial (*model.material);
@@ -143,7 +142,7 @@ void StringPrinter::printImageEffect (const ImageEffect& imageEffect) {
     this->increaseIndentation ();
 
     for (const auto& override : imageEffect.passOverrides) {
-        this->printImageEffectPassOverride (*override);
+	this->printImageEffectPassOverride (*override);
     }
 
     this->decreaseIndentation ();
@@ -159,42 +158,42 @@ void StringPrinter::printImageEffectPassOverride (const ImageEffectPassOverride&
     this->m_out << "Textures count: " << imageEffectPass.textures.size ();
 
     if (!imageEffectPass.textures.empty ()) {
-        this->increaseIndentation ();
+	this->increaseIndentation ();
 
-        for (const auto& [index, texture] : imageEffectPass.textures) {
-            this->lineEnd ();
-            this->m_out << "Texture " << index << ": " << texture;
-        }
+	for (const auto& [index, texture] : imageEffectPass.textures) {
+	    this->lineEnd ();
+	    this->m_out << "Texture " << index << ": " << texture;
+	}
 
-        this->decreaseIndentation ();
+	this->decreaseIndentation ();
     }
 
     this->lineEnd ();
     this->m_out << "Combos count: " << imageEffectPass.combos.size ();
 
     if (!imageEffectPass.combos.empty ()) {
-        this->increaseIndentation ();
+	this->increaseIndentation ();
 
-        for (const auto& [name, value] : imageEffectPass.combos) {
-            this->lineEnd ();
-            this->m_out << "Combo " << name << "=" << value;
-        }
+	for (const auto& [name, value] : imageEffectPass.combos) {
+	    this->lineEnd ();
+	    this->m_out << "Combo " << name << "=" << value;
+	}
 
-        this->decreaseIndentation ();
+	this->decreaseIndentation ();
     }
 
     this->lineEnd ();
     this->m_out << "Constants count: " << imageEffectPass.constants.size ();
 
     if (!imageEffectPass.constants.empty ()) {
-        this->increaseIndentation ();
+	this->increaseIndentation ();
 
-        for (const auto& [name, value] : imageEffectPass.constants) {
-            this->lineEnd ();
-            this->m_out << "Constant " << name << "=" << value->value->toString();
-        }
+	for (const auto& [name, value] : imageEffectPass.constants) {
+	    this->lineEnd ();
+	    this->m_out << "Constant " << name << "=" << value->value->toString ();
+	}
 
-        this->decreaseIndentation ();
+	this->decreaseIndentation ();
     }
 
     this->decreaseIndentation ();
@@ -206,31 +205,31 @@ void StringPrinter::printEffect (const Effect& effect) {
     this->increaseIndentation ();
 
     if (!effect.description.empty ()) {
-        this->lineEnd ();
-        this->m_out << "Description: " << effect.description;
+	this->lineEnd ();
+	this->m_out << "Description: " << effect.description;
     }
 
     if (!effect.dependencies.empty ()) {
-        this->lineEnd ();
-        this->m_out << "Dependencies count: " << effect.dependencies.size ();
-        this->increaseIndentation ();
+	this->lineEnd ();
+	this->m_out << "Dependencies count: " << effect.dependencies.size ();
+	this->increaseIndentation ();
 
-        for (const auto& dependency : effect.dependencies) {
-            this->lineEnd ();
-            this->m_out << "Dependency: " << dependency;
-        }
+	for (const auto& dependency : effect.dependencies) {
+	    this->lineEnd ();
+	    this->m_out << "Dependency: " << dependency;
+	}
 
-        this->decreaseIndentation ();
+	this->decreaseIndentation ();
     }
 
     if (!effect.group.empty ()) {
-        this->lineEnd ();
-        this->m_out << "Group: " << effect.group;
+	this->lineEnd ();
+	this->m_out << "Group: " << effect.group;
     }
 
     if (!effect.preview.empty ()) {
-        this->lineEnd ();
-        this->m_out << "Preview: " << effect.preview;
+	this->lineEnd ();
+	this->m_out << "Preview: " << effect.preview;
     }
 
     this->lineEnd ();
@@ -240,12 +239,12 @@ void StringPrinter::printEffect (const Effect& effect) {
     int passId = 0;
 
     for (const auto& pass : effect.passes) {
-        this->lineEnd ();
-        this->m_out << "Pass " << ++passId << ":";
-        this->increaseIndentation ();
-        this->lineEnd ();
-        this->printEffectPass (*pass);
-        this->decreaseIndentation ();
+	this->lineEnd ();
+	this->m_out << "Pass " << ++passId << ":";
+	this->increaseIndentation ();
+	this->lineEnd ();
+	this->printEffectPass (*pass);
+	this->decreaseIndentation ();
     }
 
     this->decreaseIndentation ();
@@ -255,8 +254,8 @@ void StringPrinter::printEffect (const Effect& effect) {
     this->increaseIndentation ();
 
     for (const auto& fbo : effect.fbos) {
-        this->lineEnd ();
-        this->printFBO (*fbo);
+	this->lineEnd ();
+	this->printFBO (*fbo);
     }
 
     this->decreaseIndentation ();
@@ -265,47 +264,47 @@ void StringPrinter::printEffect (const Effect& effect) {
 
 void StringPrinter::printEffectPass (const EffectPass& effectPass) {
     if (effectPass.command.has_value ()) {
-        this->m_out << "Command: " << (*effectPass.command == Command_Copy ? "copy" : "swap");
+	this->m_out << "Command: " << (*effectPass.command == Command_Copy ? "copy" : "swap");
 
-        if (effectPass.target.has_value () || effectPass.source.has_value ()) {
-            this->lineEnd ();
-        }
+	if (effectPass.target.has_value () || effectPass.source.has_value ()) {
+	    this->lineEnd ();
+	}
     }
 
     if (effectPass.target.has_value ()) {
-        this->m_out << "Target: " << effectPass.target.value ();
+	this->m_out << "Target: " << effectPass.target.value ();
 
-        if (effectPass.source.has_value ()) {
-            this->lineEnd ();
-        }
+	if (effectPass.source.has_value ()) {
+	    this->lineEnd ();
+	}
     }
 
     if (effectPass.source.has_value ()) {
-        this->m_out << "Source: " << effectPass.source.value ();
+	this->m_out << "Source: " << effectPass.source.value ();
     }
 
     if (!effectPass.binds.empty ()) {
-        if (effectPass.target.has_value ()) {
-            this->lineEnd ();
-        }
+	if (effectPass.target.has_value ()) {
+	    this->lineEnd ();
+	}
 
-        this->m_out << "Binds count: " << effectPass.binds.size ();
-        this->increaseIndentation ();
+	this->m_out << "Binds count: " << effectPass.binds.size ();
+	this->increaseIndentation ();
 
-        for (const auto& [index, target] : effectPass.binds) {
-            this->lineEnd ();
-            this->m_out << "Bind " << index << ": " << target;
-        }
+	for (const auto& [index, target] : effectPass.binds) {
+	    this->lineEnd ();
+	    this->m_out << "Bind " << index << ": " << target;
+	}
 
-        this->decreaseIndentation ();
+	this->decreaseIndentation ();
     }
 
     if (effectPass.target.has_value () || !effectPass.binds.empty ()) {
-        this->lineEnd ();
+	this->lineEnd ();
     }
 
     if (effectPass.material.has_value ()) {
-        this->printMaterial (**effectPass.material);
+	this->printMaterial (**effectPass.material);
     }
 }
 
@@ -329,8 +328,8 @@ void StringPrinter::printMaterial (const Material& material) {
     this->increaseIndentation ();
 
     for (const auto& pass : material.passes) {
-        this->lineEnd ();
-        this->printMaterialPass (*pass);
+	this->lineEnd ();
+	this->printMaterialPass (*pass);
     }
 
     this->decreaseIndentation ();
@@ -351,37 +350,38 @@ void StringPrinter::printMaterialPass (const MaterialPass& materialPass) {
     this->m_out << "Culling mode: " << materialPass.cullmode;
 
     if (!materialPass.textures.empty ()) {
-        this->lineEnd ();
-        this->m_out << "Textures count: " << materialPass.textures.size ();
-        this->increaseIndentation ();
+	this->lineEnd ();
+	this->m_out << "Textures count: " << materialPass.textures.size ();
+	this->increaseIndentation ();
 
-        for (const auto& [index, texture] : materialPass.textures) {
-            this->lineEnd ();
-            this->m_out << "Texture " << index << ": " << texture;
-        }
+	for (const auto& [index, texture] : materialPass.textures) {
+	    this->lineEnd ();
+	    this->m_out << "Texture " << index << ": " << texture;
+	}
 
-        this->decreaseIndentation ();
+	this->decreaseIndentation ();
     }
 
     if (!materialPass.combos.empty ()) {
-        this->lineEnd ();
-        this->m_out << "Combos count: " << materialPass.combos.size ();
-        this->increaseIndentation ();
+	this->lineEnd ();
+	this->m_out << "Combos count: " << materialPass.combos.size ();
+	this->increaseIndentation ();
 
-        for (const auto& [name, value] : materialPass.combos) {
-            this->lineEnd ();
-            this->m_out << "Combo " << name << ": " << value;
-        }
+	for (const auto& [name, value] : materialPass.combos) {
+	    this->lineEnd ();
+	    this->m_out << "Combo " << name << ": " << value;
+	}
 
-        this->decreaseIndentation ();
+	this->decreaseIndentation ();
     }
 
     this->decreaseIndentation ();
 }
 
 void StringPrinter::indentation () {
-    for (int i = 0; i < this->m_level; i++)
-        this->m_out << this->m_indentationCharacter;
+    for (int i = 0; i < this->m_level; i++) {
+	this->m_out << this->m_indentationCharacter;
+    }
 }
 
 void StringPrinter::lineEnd () {
@@ -389,14 +389,8 @@ void StringPrinter::lineEnd () {
     this->indentation ();
 }
 
-void StringPrinter::increaseIndentation () {
-    this->m_level ++;
-}
+void StringPrinter::increaseIndentation () { this->m_level++; }
 
-void StringPrinter::decreaseIndentation () {
-    this->m_level --;
-}
+void StringPrinter::decreaseIndentation () { this->m_level--; }
 
-std::string StringPrinter::str () const {
-    return this->m_buffer.str ();
-}
+std::string StringPrinter::str () const { return this->m_buffer.str (); }

+ 3 - 3
src/WallpaperEngine/Data/Dumpers/StringPrinter.h

@@ -1,7 +1,7 @@
 #pragma once
 
-#include <string>
 #include <sstream>
+#include <string>
 
 #include "WallpaperEngine/Data/Model/Types.h"
 
@@ -9,7 +9,7 @@ namespace WallpaperEngine::Data::Dumpers {
 using namespace WallpaperEngine::Data::Model;
 
 class StringPrinter {
-  public:
+public:
     explicit StringPrinter (std::string indentationCharacter = "\t");
     ~StringPrinter () = default;
 
@@ -102,7 +102,7 @@ class StringPrinter {
      */
     void printEffectPass (const EffectPass& effectPass);
 
-  private:
+private:
     /**
      * Printss the current identation level
      */

+ 63 - 80
src/WallpaperEngine/Data/JSON.h

@@ -21,18 +21,8 @@ using namespace WallpaperEngine::Data::Utils::SFINAE;
 class JsonExtensions;
 
 using JSON = nlohmann::basic_json<
-    std::map,
-    std::vector,
-    std::string,
-    bool,
-    std::int64_t,
-    std::uint64_t,
-    double,
-    std::allocator,
-    nlohmann::adl_serializer,
-    std::vector<std::uint8_t>,
-    JsonExtensions
->;
+    std::map, std::vector, std::string, bool, std::int64_t, std::uint64_t, double, std::allocator,
+    nlohmann::adl_serializer, std::vector<std::uint8_t>, JsonExtensions>;
 
 /**
  * Small extensions class that is used as base class of nlohmann's implementation.
@@ -41,109 +31,102 @@ using JSON = nlohmann::basic_json<
  * (mainly throwing readable exceptions when a value is missing, optional/default values, user settings...)
  */
 class JsonExtensions {
-  public:
+public:
     using base_type = JSON;
 
-    template <typename T, typename std::enable_if_t<is_glm_vec<T>::value, int> = 0>
-    [[nodiscard]] T get () const {
-        constexpr int length = GlmVecTraits<T>::length;
-        constexpr glm::qualifier qualifier = GlmVecTraits<T>::qualifier;
+    template <typename T, typename std::enable_if_t<is_glm_vec<T>::value, int> = 0> [[nodiscard]] T get () const {
+	constexpr int length = GlmVecTraits<T>::length;
+	constexpr glm::qualifier qualifier = GlmVecTraits<T>::qualifier;
 
-        // call the specialized version of the function
-        return get <length, typename GlmVecTraits<T>::type, qualifier> ();
+	// call the specialized version of the function
+	return get<length, typename GlmVecTraits<T>::type, qualifier> ();
     }
     template <int length, typename type, glm::qualifier qualifier>
-    [[nodiscard]] glm::vec <length, type, qualifier> get () const {
-        return VectorBuilder::parse <length, type, qualifier> (this->base ().get <std::string> ());
+    [[nodiscard]] glm::vec<length, type, qualifier> get () const {
+	return VectorBuilder::parse<length, type, qualifier> (this->base ().get<std::string> ());
     }
     [[nodiscard]] base_type require (const std::string& key, const std::string& message) const {
-        auto base  =  this->base ();
-        const auto it = base.find (key);
+	auto base = this->base ();
+	const auto it = base.find (key);
 
-        if (it == base.end ()) {
-            sLog.exception (message, ". Contents: ", base.dump ());
-        }
+	if (it == base.end ()) {
+	    sLog.exception (message, ". Contents: ", base.dump ());
+	}
 
-        return *it;
+	return *it;
     }
-    template <typename T>
-    [[nodiscard]] T require (const std::string& key, const std::string& message) const {
-        auto base = this->base ();
-        const auto it = base.find (key);
+    template <typename T> [[nodiscard]] T require (const std::string& key, const std::string& message) const {
+	auto base = this->base ();
+	const auto it = base.find (key);
 
-        if (it == base.end ()) {
-            sLog.exception (message, ". Contents: ", base.dump ());
-        }
+	if (it == base.end ()) {
+	    sLog.exception (message, ". Contents: ", base.dump ());
+	}
 
-        return (*it);
+	return (*it);
     }
-    [[nodiscard]] std::optional <base_type> optional (const std::string& key) const noexcept {
-        auto base = this->base ();
-        const auto it = base.find (key);
-        auto result = std::optional<base_type> {};
+    [[nodiscard]] std::optional<base_type> optional (const std::string& key) const noexcept {
+	auto base = this->base ();
+	const auto it = base.find (key);
+	auto result = std::optional<base_type> {};
 
-        if (it != base.end () && !it->is_null ()) {
-            result.emplace (*it);
-        }
+	if (it != base.end () && !it->is_null ()) {
+	    result.emplace (*it);
+	}
 
-        return result;
+	return result;
     }
-    template <typename T>
-    [[nodiscard]] std::optional <T> optional (const std::string& key) const noexcept {
-        auto base = this->base ();
-        const auto it = base.find (key);
+    template <typename T> [[nodiscard]] std::optional<T> optional (const std::string& key) const noexcept {
+	auto base = this->base ();
+	const auto it = base.find (key);
 
-        if (it == base.end () || it->is_null ()) {
-            return std::nullopt;
-        }
+	if (it == base.end () || it->is_null ()) {
+	    return std::nullopt;
+	}
 
-        return *it;
+	return *it;
     }
-    template <typename T>
-    [[nodiscard]] T optional (const std::string& key, T defaultValue) const noexcept {
-        auto base = this->base ();
-        const auto it = base.find (key);
+    template <typename T> [[nodiscard]] T optional (const std::string& key, T defaultValue) const noexcept {
+	auto base = this->base ();
+	const auto it = base.find (key);
 
-        if (it == base.end () || it->is_null ()) {
-            return defaultValue;
-        }
+	if (it == base.end () || it->is_null ()) {
+	    return defaultValue;
+	}
 
-        return (*it);
+	return (*it);
     }
     [[nodiscard]] UserSettingUniquePtr user (const std::string& key, const Properties& properties) const;
     template <typename T>
-    [[nodiscard]] UserSettingUniquePtr user (const std::string& key, const Properties& properties, T defaultValue) const {
-        const auto value = this->optional (key);
+    [[nodiscard]] UserSettingUniquePtr
+    user (const std::string& key, const Properties& properties, T defaultValue) const {
+	const auto value = this->optional (key);
 
-        if (!value.has_value ()) {
-            return UserSettingBuilder::fromValue <T> (defaultValue);
-        }
+	if (!value.has_value ()) {
+	    return UserSettingBuilder::fromValue<T> (defaultValue);
+	}
 
-        // performs a second lookup, but handles the actual call to UserSettingParser outside of this header
-        // this resolving the include loop
-        return this->user (key, properties);
+	// performs a second lookup, but handles the actual call to UserSettingParser outside of this header
+	// this resolving the include loop
+	return this->user (key, properties);
     }
 
-    template <int length, typename type, glm::qualifier qualifier>
-    operator glm::vec <length, type, qualifier> () const {
-        return get <length, type, qualifier> ();
+    template <int length, typename type, glm::qualifier qualifier> operator glm::vec<length, type, qualifier> () const {
+	return get<length, type, qualifier> ();
     }
-    template <typename T, typename std::enable_if_t<is_glm_vec<T>::value> = 0>
-    operator T () const {
-        constexpr int length = GlmVecTraits<T>::length;
-        constexpr glm::qualifier qualifier = GlmVecTraits<T>::qualifier;
+    template <typename T, typename std::enable_if_t<is_glm_vec<T>::value> = 0> operator T () const {
+	constexpr int length = GlmVecTraits<T>::length;
+	constexpr glm::qualifier qualifier = GlmVecTraits<T>::qualifier;
 
-        // call the specialized version of the function
-        return operator glm::vec <length, typename GlmVecTraits<T>::type, qualifier> ();
+	// call the specialized version of the function
+	return operator glm::vec<length, typename GlmVecTraits<T>::type, qualifier> ();
     }
 
-  private:
+private:
     /**
      * @return The base json object to be used by the extension methods
      */
-    [[nodiscard]] const base_type& base () const {
-        return *static_cast<const base_type*> (this);
-    }
+    [[nodiscard]] const base_type& base () const { return *static_cast<const base_type*> (this); }
 };
 
 } // namespace WallpaperEngine::Data::JSON

+ 139 - 175
src/WallpaperEngine/Data/Model/DynamicValue.cpp

@@ -3,127 +3,92 @@
 
 using namespace WallpaperEngine::Data::Model;
 
-DynamicValue::DynamicValue (const glm::ivec4& value) {
-    this->DynamicValue::update (value);
-}
+DynamicValue::DynamicValue (const glm::ivec4& value) { this->DynamicValue::update (value); }
 
-DynamicValue::DynamicValue (const glm::ivec3& value) {
-    this->DynamicValue::update (value);
-}
+DynamicValue::DynamicValue (const glm::ivec3& value) { this->DynamicValue::update (value); }
 
-DynamicValue::DynamicValue (const glm::ivec2& value) {
-    this->DynamicValue::update (value);
-}
+DynamicValue::DynamicValue (const glm::ivec2& value) { this->DynamicValue::update (value); }
 
-DynamicValue::DynamicValue (const glm::vec4& value) {
-    this->DynamicValue::update (value);
-}
+DynamicValue::DynamicValue (const glm::vec4& value) { this->DynamicValue::update (value); }
 
-DynamicValue::DynamicValue (const glm::vec3& value) {
-    this->DynamicValue::update (value);
-}
+DynamicValue::DynamicValue (const glm::vec3& value) { this->DynamicValue::update (value); }
 
-DynamicValue::DynamicValue (const glm::vec2& value) {
-    this->DynamicValue::update (value);
-}
+DynamicValue::DynamicValue (const glm::vec2& value) { this->DynamicValue::update (value); }
 
-DynamicValue::DynamicValue (float value) {
-    this->DynamicValue::update (value);
-}
+DynamicValue::DynamicValue (float value) { this->DynamicValue::update (value); }
 
-DynamicValue::DynamicValue (int value) {
-    this->DynamicValue::update (value);
-}
+DynamicValue::DynamicValue (int value) { this->DynamicValue::update (value); }
 
-DynamicValue::DynamicValue (bool value) {
-    this->DynamicValue::update (value);
-}
+DynamicValue::DynamicValue (bool value) { this->DynamicValue::update (value); }
 
 DynamicValue::~DynamicValue () {
-    if (this->m_aliveFlag)
-        *this->m_aliveFlag = false;
+    if (this->m_aliveFlag) {
+	*this->m_aliveFlag = false;
+    }
     this->disconnect ();
     this->m_listeners.clear ();
 }
 
-const glm::ivec4& DynamicValue::getIVec4 () const {
-    return this->m_ivec4;
-}
+const glm::ivec4& DynamicValue::getIVec4 () const { return this->m_ivec4; }
 
-const glm::ivec3& DynamicValue::getIVec3 () const {
-    return this->m_ivec3;
-}
+const glm::ivec3& DynamicValue::getIVec3 () const { return this->m_ivec3; }
 
-const glm::ivec2& DynamicValue::getIVec2 () const {
-    return this->m_ivec2;
-}
+const glm::ivec2& DynamicValue::getIVec2 () const { return this->m_ivec2; }
 
-const glm::vec4& DynamicValue::getVec4 () const {
-    return this->m_vec4;
-}
+const glm::vec4& DynamicValue::getVec4 () const { return this->m_vec4; }
 
-const glm::vec3& DynamicValue::getVec3 () const {
-    return this->m_vec3;
-}
+const glm::vec3& DynamicValue::getVec3 () const { return this->m_vec3; }
 
-const glm::vec2& DynamicValue::getVec2 () const {
-    return this->m_vec2;
-}
+const glm::vec2& DynamicValue::getVec2 () const { return this->m_vec2; }
 
-const float& DynamicValue::getFloat () const {
-    return this->m_float;
-}
+const float& DynamicValue::getFloat () const { return this->m_float; }
 
-const int& DynamicValue::getInt () const {
-    return this->m_int;
-}
+const int& DynamicValue::getInt () const { return this->m_int; }
 
-const bool& DynamicValue::getBool () const {
-    return this->m_bool;
-}
+const bool& DynamicValue::getBool () const { return this->m_bool; }
 
-const std::string& DynamicValue::getString () const {
-    return this->m_string;
-}
+const std::string& DynamicValue::getString () const { return this->m_string; }
 
-DynamicValue::UnderlyingType DynamicValue::getType () const {
-    return this->m_type;
-}
+DynamicValue::UnderlyingType DynamicValue::getType () const { return this->m_type; }
 
 std::string DynamicValue::toString () const {
     switch (this->m_type) {
-        case UnderlyingType::Float:
-            return std::to_string (this->m_float);
-        case UnderlyingType::Int:
-            return std::to_string (this->m_int);
-        case UnderlyingType::Boolean:
-            return std::to_string (this->m_bool);
-        case UnderlyingType::Vec2:
-            return std::to_string (this->m_vec2.x) + ", " + std::to_string (this->m_vec2.y);
-        case UnderlyingType::Vec3:
-            return std::to_string (this->m_vec3.x) + ", " + std::to_string (this->m_vec3.y) + ", " + std::to_string (this->m_vec3.z);
-        case UnderlyingType::Vec4:
-            return std::to_string (this->m_vec4.x) + ", " + std::to_string (this->m_vec4.y) + ", " + std::to_string (this->m_vec4.z) + ", " + std::to_string (this->m_vec4.w);
-        case UnderlyingType::IVec2:
-            return std::to_string (this->m_ivec2.x) + ", " + std::to_string (this->m_ivec2.y);
-        case UnderlyingType::IVec3:
-            return std::to_string (this->m_ivec3.x) + ", " + std::to_string (this->m_ivec3.y) + ", " + std::to_string (this->m_ivec3.z);
-        case UnderlyingType::IVec4:
-            return std::to_string (this->m_ivec4.x) + ", " + std::to_string (this->m_ivec4.y) + ", " + std::to_string (this->m_ivec4.z) + ", " + std::to_string (this->m_ivec4.w);
-        case UnderlyingType::String:
-            return this->m_string;
-        default:
-            return "Unknown conversion for dynamic value of type: " + std::to_string (static_cast<int> (this->m_type));
+	case UnderlyingType::Float:
+	    return std::to_string (this->m_float);
+	case UnderlyingType::Int:
+	    return std::to_string (this->m_int);
+	case UnderlyingType::Boolean:
+	    return std::to_string (this->m_bool);
+	case UnderlyingType::Vec2:
+	    return std::to_string (this->m_vec2.x) + ", " + std::to_string (this->m_vec2.y);
+	case UnderlyingType::Vec3:
+	    return std::to_string (this->m_vec3.x) + ", " + std::to_string (this->m_vec3.y) + ", "
+		+ std::to_string (this->m_vec3.z);
+	case UnderlyingType::Vec4:
+	    return std::to_string (this->m_vec4.x) + ", " + std::to_string (this->m_vec4.y) + ", "
+		+ std::to_string (this->m_vec4.z) + ", " + std::to_string (this->m_vec4.w);
+	case UnderlyingType::IVec2:
+	    return std::to_string (this->m_ivec2.x) + ", " + std::to_string (this->m_ivec2.y);
+	case UnderlyingType::IVec3:
+	    return std::to_string (this->m_ivec3.x) + ", " + std::to_string (this->m_ivec3.y) + ", "
+		+ std::to_string (this->m_ivec3.z);
+	case UnderlyingType::IVec4:
+	    return std::to_string (this->m_ivec4.x) + ", " + std::to_string (this->m_ivec4.y) + ", "
+		+ std::to_string (this->m_ivec4.z) + ", " + std::to_string (this->m_ivec4.w);
+	case UnderlyingType::String:
+	    return this->m_string;
+	default:
+	    return "Unknown conversion for dynamic value of type: " + std::to_string (static_cast<int> (this->m_type));
     }
 }
 
 void DynamicValue::update (const float newValue) {
-    this->m_ivec4 = glm::ivec4(static_cast<int> (newValue));
-    this->m_ivec3 = glm::ivec3(static_cast<int> (newValue));
-    this->m_ivec2 = glm::ivec2(static_cast<int> (newValue));
-    this->m_vec4 = glm::vec4(newValue);
-    this->m_vec3 = glm::vec3(newValue);
-    this->m_vec2 = glm::vec2(newValue);
+    this->m_ivec4 = glm::ivec4 (static_cast<int> (newValue));
+    this->m_ivec3 = glm::ivec3 (static_cast<int> (newValue));
+    this->m_ivec2 = glm::ivec2 (static_cast<int> (newValue));
+    this->m_vec4 = glm::vec4 (newValue);
+    this->m_vec3 = glm::vec3 (newValue);
+    this->m_vec2 = glm::vec2 (newValue);
     this->m_float = newValue;
     this->m_int = static_cast<int> (newValue);
     this->m_bool = static_cast<int> (newValue) != 0;
@@ -134,12 +99,12 @@ void DynamicValue::update (const float newValue) {
 }
 
 void DynamicValue::update (const int newValue) {
-    this->m_ivec4 = glm::ivec4(newValue);
-    this->m_ivec3 = glm::ivec3(newValue);
-    this->m_ivec2 = glm::ivec2(newValue);
-    this->m_vec4 = glm::vec4(static_cast<float> (newValue));
-    this->m_vec3 = glm::vec3(static_cast<float> (newValue));
-    this->m_vec2 = glm::vec2(static_cast<float> (newValue));
+    this->m_ivec4 = glm::ivec4 (newValue);
+    this->m_ivec3 = glm::ivec3 (newValue);
+    this->m_ivec2 = glm::ivec2 (newValue);
+    this->m_vec4 = glm::vec4 (static_cast<float> (newValue));
+    this->m_vec3 = glm::vec3 (static_cast<float> (newValue));
+    this->m_vec2 = glm::vec2 (static_cast<float> (newValue));
     this->m_float = static_cast<float> (newValue);
     this->m_int = newValue;
     this->m_bool = newValue != 0;
@@ -150,12 +115,12 @@ void DynamicValue::update (const int newValue) {
 }
 
 void DynamicValue::update (const bool newValue) {
-    this->m_ivec4 = glm::ivec4(newValue);
-    this->m_ivec3 = glm::ivec3(newValue);
-    this->m_ivec2 = glm::ivec2(newValue);
-    this->m_vec4 = glm::vec4(newValue);
-    this->m_vec3 = glm::vec3(newValue);
-    this->m_vec2 = glm::vec2(newValue);
+    this->m_ivec4 = glm::ivec4 (newValue);
+    this->m_ivec3 = glm::ivec3 (newValue);
+    this->m_ivec2 = glm::ivec2 (newValue);
+    this->m_vec4 = glm::vec4 (newValue);
+    this->m_vec3 = glm::vec3 (newValue);
+    this->m_vec2 = glm::vec2 (newValue);
     this->m_float = newValue;
     this->m_int = newValue;
     this->m_bool = newValue;
@@ -165,13 +130,13 @@ void DynamicValue::update (const bool newValue) {
     this->propagate ();
 }
 
-void DynamicValue::update(const glm::vec2& newValue) {
-    this->m_ivec4 = glm::ivec4(newValue, 0, 0);
-    this->m_ivec3 = glm::ivec3(newValue, 0);
-    this->m_ivec2 = glm::ivec2(newValue);
+void DynamicValue::update (const glm::vec2& newValue) {
+    this->m_ivec4 = glm::ivec4 (newValue, 0, 0);
+    this->m_ivec3 = glm::ivec3 (newValue, 0);
+    this->m_ivec2 = glm::ivec2 (newValue);
     this->m_vec2 = newValue;
-    this->m_vec3 = glm::vec3(newValue, 0.0f);
-    this->m_vec4 = glm::vec4(newValue, 0.0f, 0.0f);
+    this->m_vec3 = glm::vec3 (newValue, 0.0f);
+    this->m_vec4 = glm::vec4 (newValue, 0.0f, 0.0f);
     this->m_float = newValue.x;
     this->m_int = static_cast<int> (newValue.x);
     this->m_bool = newValue.x != 0.0f;
@@ -181,13 +146,13 @@ void DynamicValue::update(const glm::vec2& newValue) {
     this->propagate ();
 }
 
-void DynamicValue::update(const glm::vec3& newValue) {
-    this->m_ivec4 = glm::ivec4(newValue, 0);
-    this->m_ivec3 = glm::ivec3(newValue);
-    this->m_ivec2 = glm::ivec2(newValue);
-    this->m_vec2 = glm::vec2(newValue);
+void DynamicValue::update (const glm::vec3& newValue) {
+    this->m_ivec4 = glm::ivec4 (newValue, 0);
+    this->m_ivec3 = glm::ivec3 (newValue);
+    this->m_ivec2 = glm::ivec2 (newValue);
+    this->m_vec2 = glm::vec2 (newValue);
     this->m_vec3 = newValue;
-    this->m_vec4 = glm::vec4(newValue, 0.0f);
+    this->m_vec4 = glm::vec4 (newValue, 0.0f);
     this->m_float = newValue.x;
     this->m_int = static_cast<int> (newValue.x);
     this->m_bool = newValue.x != 0.0f;
@@ -197,12 +162,12 @@ void DynamicValue::update(const glm::vec3& newValue) {
     this->propagate ();
 }
 
-void DynamicValue::update(const glm::vec4& newValue) {
-    this->m_ivec4 = glm::ivec4(newValue);
-    this->m_ivec3 = glm::ivec3(newValue);
-    this->m_ivec2 = glm::ivec2(newValue);
-    this->m_vec2 = glm::vec2(newValue);
-    this->m_vec3 = glm::vec3(newValue);
+void DynamicValue::update (const glm::vec4& newValue) {
+    this->m_ivec4 = glm::ivec4 (newValue);
+    this->m_ivec3 = glm::ivec3 (newValue);
+    this->m_ivec2 = glm::ivec2 (newValue);
+    this->m_vec2 = glm::vec2 (newValue);
+    this->m_vec3 = glm::vec3 (newValue);
     this->m_vec4 = newValue;
     this->m_float = newValue.x;
     this->m_int = static_cast<int> (newValue.x);
@@ -213,13 +178,13 @@ void DynamicValue::update(const glm::vec4& newValue) {
     this->propagate ();
 }
 
-void DynamicValue::update(const glm::ivec2& newValue) {
-    this->m_ivec4 = glm::ivec4(newValue, 0, 0);
-    this->m_ivec3 = glm::ivec3(newValue, 0);
-    this->m_ivec2 = glm::ivec2(newValue);
+void DynamicValue::update (const glm::ivec2& newValue) {
+    this->m_ivec4 = glm::ivec4 (newValue, 0, 0);
+    this->m_ivec3 = glm::ivec3 (newValue, 0);
+    this->m_ivec2 = glm::ivec2 (newValue);
     this->m_vec2 = newValue;
-    this->m_vec3 = glm::vec3(newValue, 0.0f);
-    this->m_vec4 = glm::vec4(newValue, 0.0f, 0.0f);
+    this->m_vec3 = glm::vec3 (newValue, 0.0f);
+    this->m_vec4 = glm::vec4 (newValue, 0.0f, 0.0f);
     this->m_float = static_cast<float> (newValue.x);
     this->m_int = static_cast<int> (newValue.x);
     this->m_bool = newValue.x != 0;
@@ -229,13 +194,13 @@ void DynamicValue::update(const glm::ivec2& newValue) {
     this->propagate ();
 }
 
-void DynamicValue::update(const glm::ivec3& newValue) {
-    this->m_ivec4 = glm::ivec4(newValue, 0);
-    this->m_ivec3 = glm::ivec3(newValue);
-    this->m_ivec2 = glm::ivec2(newValue);
-    this->m_vec2 = glm::vec2(newValue);
+void DynamicValue::update (const glm::ivec3& newValue) {
+    this->m_ivec4 = glm::ivec4 (newValue, 0);
+    this->m_ivec3 = glm::ivec3 (newValue);
+    this->m_ivec2 = glm::ivec2 (newValue);
+    this->m_vec2 = glm::vec2 (newValue);
     this->m_vec3 = newValue;
-    this->m_vec4 = glm::vec4(newValue, 0.0f);
+    this->m_vec4 = glm::vec4 (newValue, 0.0f);
     this->m_float = static_cast<float> (newValue.x);
     this->m_int = static_cast<int> (newValue.x);
     this->m_bool = newValue.x != 0;
@@ -245,12 +210,12 @@ void DynamicValue::update(const glm::ivec3& newValue) {
     this->propagate ();
 }
 
-void DynamicValue::update(const glm::ivec4& newValue) {
-    this->m_ivec4 = glm::ivec4(newValue);
-    this->m_ivec3 = glm::ivec3(newValue);
-    this->m_ivec2 = glm::ivec2(newValue);
-    this->m_vec2 = glm::vec2(newValue);
-    this->m_vec3 = glm::vec3(newValue);
+void DynamicValue::update (const glm::ivec4& newValue) {
+    this->m_ivec4 = glm::ivec4 (newValue);
+    this->m_ivec3 = glm::ivec3 (newValue);
+    this->m_ivec2 = glm::ivec2 (newValue);
+    this->m_vec2 = glm::vec2 (newValue);
+    this->m_vec3 = glm::vec3 (newValue);
     this->m_vec4 = newValue;
     this->m_float = static_cast<float> (newValue.x);
     this->m_int = static_cast<int> (newValue.x);
@@ -262,12 +227,12 @@ void DynamicValue::update(const glm::ivec4& newValue) {
 }
 
 void DynamicValue::update (const std::string& newValue) {
-    this->m_ivec4 = glm::ivec4(0);
-    this->m_ivec3 = glm::ivec3(0);
-    this->m_ivec2 = glm::ivec2(0);
-    this->m_vec2 = glm::vec2(0.0f);
-    this->m_vec3 = glm::vec3(0.0f);
-    this->m_vec4 = glm::vec4(0.0f);
+    this->m_ivec4 = glm::ivec4 (0);
+    this->m_ivec3 = glm::ivec3 (0);
+    this->m_ivec2 = glm::ivec2 (0);
+    this->m_vec2 = glm::vec2 (0.0f);
+    this->m_vec3 = glm::vec3 (0.0f);
+    this->m_vec4 = glm::vec4 (0.0f);
     this->m_float = 0.0f;
     this->m_int = 0;
     this->m_bool = false;
@@ -275,7 +240,7 @@ void DynamicValue::update (const std::string& newValue) {
     this->m_type = UnderlyingType::String;
 
     if (this->m_condition.has_value ()) {
-        this->m_bool = this->m_condition.value ().condition == newValue;
+	this->m_bool = this->m_condition.value ().condition == newValue;
     }
 
     this->propagate ();
@@ -294,20 +259,20 @@ void DynamicValue::update (const DynamicValue& other) {
     this->m_type = other.getType ();
 
     if (this->m_condition.has_value () && other.getType () == UnderlyingType::String) {
-        // TODO: DOES THIS NEED TO HAPPEN WITH OTHER TYPES TOO?
-        this->m_bool = this->m_condition.value ().condition == other.getString ();
+	// TODO: DOES THIS NEED TO HAPPEN WITH OTHER TYPES TOO?
+	this->m_bool = this->m_condition.value ().condition == other.getString ();
     }
 
     this->propagate ();
 }
 
 void DynamicValue::update () {
-    this->m_ivec4 = glm::ivec4(0);
-    this->m_ivec3 = glm::ivec3(0);
-    this->m_ivec2 = glm::ivec2(0);
-    this->m_vec2 = glm::vec2(0.0f);
-    this->m_vec3 = glm::vec3(0.0f);
-    this->m_vec4 = glm::vec4(0.0f);
+    this->m_ivec4 = glm::ivec4 (0);
+    this->m_ivec3 = glm::ivec3 (0);
+    this->m_ivec2 = glm::ivec2 (0);
+    this->m_vec2 = glm::vec2 (0.0f);
+    this->m_vec3 = glm::vec3 (0.0f);
+    this->m_vec4 = glm::vec4 (0.0f);
     this->m_float = 0.0f;
     this->m_int = 0;
     this->m_bool = false;
@@ -321,21 +286,22 @@ std::function<void ()> DynamicValue::listen (const std::function<void (const Dyn
     auto alive = this->m_aliveFlag;
 
     return [this, it, alive] {
-        if (!alive || !*alive)
-            return;
-        this->m_listeners.erase (it);
+	if (!alive || !*alive) {
+	    return;
+	}
+	this->m_listeners.erase (it);
     };
 }
 
 void DynamicValue::connect (DynamicValue* other) {
     const auto lambda = [this] (const DynamicValue& other) {
-        // null is a special case, copying everything to 0 is different,
-        // so calling the update without parameters is required
-        if (other.getType () == UnderlyingType::Null) {
-            this->update ();
-        } else {
-            this->update (other);
-        }
+	// null is a special case, copying everything to 0 is different,
+	// so calling the update without parameters is required
+	if (other.getType () == UnderlyingType::Null) {
+	    this->update ();
+	} else {
+	    this->update (other);
+	}
     };
 
     const auto deregisterFunction = other->listen (lambda);
@@ -348,25 +314,23 @@ void DynamicValue::connect (DynamicValue* other) {
 
 void DynamicValue::disconnect () {
     for (const auto& deregister : this->m_connections) {
-        if (!deregister)
-            continue;
-        try {
-            deregister ();
-        } catch (...) {
-            sLog.error ("Exception during listener deregistration");
-        }
+	if (!deregister) {
+	    continue;
+	}
+	try {
+	    deregister ();
+	} catch (...) {
+	    sLog.error ("Exception during listener deregistration");
+	}
     }
 
     this->m_connections.clear ();
 }
 
-void DynamicValue::attachCondition (const ConditionInfo& condition) {
-    this->m_condition = condition;
-}
-
+void DynamicValue::attachCondition (const ConditionInfo& condition) { this->m_condition = condition; }
 
 void DynamicValue::propagate () const {
     for (const auto& callback : this->m_listeners) {
-        callback(*this);
+	callback (*this);
     }
 }

+ 22 - 22
src/WallpaperEngine/Data/Model/DynamicValue.h

@@ -17,31 +17,31 @@ struct ConditionInfo {
  * Class that represents different types of dynamic values
  */
 class DynamicValue {
-  public:
+public:
     enum UnderlyingType {
-        Null = 0,
-        IVec4 = 1,
-        IVec3 = 2,
-        IVec2 = 3,
-        Vec4 = 4,
-        Vec3 = 5,
-        Vec2 = 6,
-        Float = 7,
-        Int = 8,
-        Boolean = 9,
-        String = 10
+	Null = 0,
+	IVec4 = 1,
+	IVec3 = 2,
+	IVec2 = 3,
+	Vec4 = 4,
+	Vec3 = 5,
+	Vec2 = 6,
+	Float = 7,
+	Int = 8,
+	Boolean = 9,
+	String = 10
     };
 
     DynamicValue () = default;
-    explicit DynamicValue(const glm::ivec4& value);
-    explicit DynamicValue(const glm::ivec3& value);
-    explicit DynamicValue(const glm::ivec2& value);
-    explicit DynamicValue(const glm::vec4& value);
-    explicit DynamicValue(const glm::vec3& value);
-    explicit DynamicValue(const glm::vec2& value);
-    explicit DynamicValue(float value);
-    explicit DynamicValue(int value);
-    explicit DynamicValue(bool value);
+    explicit DynamicValue (const glm::ivec4& value);
+    explicit DynamicValue (const glm::ivec3& value);
+    explicit DynamicValue (const glm::ivec2& value);
+    explicit DynamicValue (const glm::vec4& value);
+    explicit DynamicValue (const glm::vec3& value);
+    explicit DynamicValue (const glm::vec2& value);
+    explicit DynamicValue (float value);
+    explicit DynamicValue (int value);
+    explicit DynamicValue (bool value);
     virtual ~DynamicValue ();
 
     [[nodiscard]] const glm::ivec4& getIVec4 () const;
@@ -104,7 +104,7 @@ class DynamicValue {
      */
     void attachCondition (const ConditionInfo& condition);
 
-  private:
+private:
     /**
      * Notifies any listeners that the value has changed
      */

+ 8 - 11
src/WallpaperEngine/Data/Model/Effect.h

@@ -1,15 +1,12 @@
 #pragma once
 
-#include <string>
 #include <optional>
+#include <string>
 
 #include "Types.h"
 
 namespace WallpaperEngine::Data::Model {
-enum PassCommandType {
-    Command_Copy = 0,
-    Command_Swap = 1
-};
+enum PassCommandType { Command_Copy = 0, Command_Swap = 1 };
 
 struct FBO {
     std::string name;
@@ -24,11 +21,11 @@ struct EffectPass {
     /** Texture bindings for this effect's pass */
     TextureMap binds;
     /** The command this material executes (if specified) */
-    std::optional <PassCommandType> command;
+    std::optional<PassCommandType> command;
     /** The source this material renders from (if specified) */
-    std::optional <std::string> source;
+    std::optional<std::string> source;
     /** The target this material renders to (if specified) */
-    std::optional <std::string> target;
+    std::optional<std::string> target;
 };
 
 struct Effect {
@@ -41,10 +38,10 @@ struct Effect {
     /** Effect's preview project */
     std::string preview;
     /** Effect's dependencies */
-    std::vector <std::string> dependencies;
+    std::vector<std::string> dependencies;
     /** The different passes for this effect */
-    std::vector <EffectPassUniquePtr> passes;
+    std::vector<EffectPassUniquePtr> passes;
     /** The fbos declared by this effect */
-    std::vector <FBOUniquePtr> fbos;
+    std::vector<FBOUniquePtr> fbos;
 };
 } // namespace WallpaperEngine::Data::Model

+ 4 - 8
src/WallpaperEngine/Data/Model/Material.h

@@ -1,9 +1,9 @@
 #pragma once
 
 #include <map>
-#include <vector>
-#include <string>
 #include <optional>
+#include <string>
+#include <vector>
 
 #include "Types.h"
 
@@ -16,11 +16,7 @@ enum BlendingMode {
     BlendingMode_Additive = 3,
 };
 
-enum CullingMode {
-    CullingMode_Unknown = 0,
-    CullingMode_Normal = 1,
-    CullingMode_Disable = 2
-};
+enum CullingMode { CullingMode_Unknown = 0, CullingMode_Normal = 1, CullingMode_Disable = 2 };
 
 enum DepthtestMode {
     DepthtestMode_Unknown = 0,
@@ -59,7 +55,7 @@ struct Material {
     /** The name of the file this material is defined in */
     std::string filename;
     /** The passes that compose this material */
-    std::vector <MaterialPassUniquePtr> passes;
+    std::vector<MaterialPassUniquePtr> passes;
 };
 
 } // namespace WallpaperEngine::Data::Model

+ 1 - 1
src/WallpaperEngine/Data/Model/Model.h

@@ -27,6 +27,6 @@ struct ModelStruct {
     /** Not sure what's used for */
     std::optional<int> height;
     /** Model file for puppet */
-    std::optional <std::string> puppet;
+    std::optional<std::string> puppet;
 };
 } // namespace WallpaperEngine::Data::Model

+ 162 - 96
src/WallpaperEngine/Data/Model/Object.h

@@ -1,16 +1,16 @@
 #pragma once
 
+#include <string>
 #include <utility>
 #include <vector>
-#include <string>
 
 #include <glm/glm.hpp>
 
-#include "Types.h"
-#include "UserSetting.h"
+#include "Effect.h"
 #include "Material.h"
 #include "Model.h"
-#include "Effect.h"
+#include "Types.h"
+#include "UserSetting.h"
 #include "WallpaperEngine/Data/Utils/TypeCaster.h"
 #include <memory>
 
@@ -20,7 +20,7 @@ using namespace WallpaperEngine::Data::Utils;
 struct ObjectData {
     int id;
     std::string name;
-    std::vector <int> dependencies;
+    std::vector<int> dependencies;
 };
 
 /**
@@ -33,8 +33,8 @@ struct ObjectData {
  * @see Light
  */
 class Object : public TypeCaster, public ObjectData {
-  public:
-    explicit Object (ObjectData data) noexcept : TypeCaster (), ObjectData (std::move (data)) {};
+public:
+    explicit Object (ObjectData data) noexcept : TypeCaster (), ObjectData (std::move (data)) { };
     ~Object () override = default;
 };
 
@@ -67,7 +67,7 @@ struct ImageEffect {
     /** If this effect is visible or not */
     UserSettingUniquePtr visible;
     /** Pass overrides to apply to the effect's passes */
-    std::vector <ImageEffectPassOverrideUniquePtr> passOverrides;
+    std::vector<ImageEffectPassOverrideUniquePtr> passOverrides;
     /** The effect definition */
     EffectUniquePtr effect;
 };
@@ -110,27 +110,29 @@ struct ImageData {
     /** The material in use for this image */
     ModelUniquePtr model;
     /** The effects applied to this image after the material is rendered */
-    std::vector <ImageEffectUniquePtr> effects;
+    std::vector<ImageEffectUniquePtr> effects;
     /** The animation layers used in the puppet warp */
-    std::vector <ImageAnimationLayerUniquePtr> animationLayers;
+    std::vector<ImageAnimationLayerUniquePtr> animationLayers;
 };
 
 class Image : public Object, public ImageData {
-  public:
-    explicit Image (ObjectData data, ImageData imageData) noexcept : Object (std::move(data)), ImageData (std::move (imageData)) {};
+public:
+    explicit Image (ObjectData data, ImageData imageData) noexcept :
+	Object (std::move (data)), ImageData (std::move (imageData)) { };
     ~Image () override = default;
 };
 
 struct SoundData {
     /** Playback mode, loop, */
     // TODO: WRITE AN ENUM FOR THIS
-    std::optional <std::string> playbackmode;
-    std::vector <std::string> sounds;
+    std::optional<std::string> playbackmode;
+    std::vector<std::string> sounds;
 };
 
 class Sound : public Object, public SoundData {
-  public:
-    explicit Sound (ObjectData data, SoundData soundData) noexcept : Object (std::move(data)), SoundData (std::move (soundData)) {};
+public:
+    explicit Sound (ObjectData data, SoundData soundData) noexcept :
+	Object (std::move (data)), SoundData (std::move (soundData)) { };
     ~Sound () override = default;
 };
 
@@ -179,66 +181,79 @@ struct ParticleEmitter {
  * Particle initializer base and implementations
  */
 class ParticleInitializerBase : public TypeCaster {
-  public:
+public:
     virtual ~ParticleInitializerBase () = default;
 };
 
 class ColorRandomInitializer : public ParticleInitializerBase {
-  public:
-    ColorRandomInitializer (UserSettingUniquePtr min, UserSettingUniquePtr max) : min (std::move (min)), max (std::move (max)) {}
+public:
+    ColorRandomInitializer (UserSettingUniquePtr min, UserSettingUniquePtr max) :
+	min (std::move (min)), max (std::move (max)) { }
     UserSettingUniquePtr min;
     UserSettingUniquePtr max;
 };
 
 class SizeRandomInitializer : public ParticleInitializerBase {
-  public:
-    SizeRandomInitializer (UserSettingUniquePtr min, UserSettingUniquePtr max, UserSettingUniquePtr exponent)
-        : min (std::move (min)), max (std::move (max)), exponent (std::move (exponent)) {}
+public:
+    SizeRandomInitializer (UserSettingUniquePtr min, UserSettingUniquePtr max, UserSettingUniquePtr exponent) :
+	min (std::move (min)), max (std::move (max)), exponent (std::move (exponent)) { }
     UserSettingUniquePtr min;
     UserSettingUniquePtr max;
     UserSettingUniquePtr exponent;
 };
 
 class AlphaRandomInitializer : public ParticleInitializerBase {
-  public:
-    AlphaRandomInitializer (UserSettingUniquePtr min, UserSettingUniquePtr max) : min (std::move (min)), max (std::move (max)) {}
+public:
+    AlphaRandomInitializer (UserSettingUniquePtr min, UserSettingUniquePtr max) :
+	min (std::move (min)), max (std::move (max)) { }
     UserSettingUniquePtr min;
     UserSettingUniquePtr max;
 };
 
 class LifetimeRandomInitializer : public ParticleInitializerBase {
-  public:
-    LifetimeRandomInitializer (UserSettingUniquePtr min, UserSettingUniquePtr max) : min (std::move (min)), max (std::move (max)) {}
+public:
+    LifetimeRandomInitializer (UserSettingUniquePtr min, UserSettingUniquePtr max) :
+	min (std::move (min)), max (std::move (max)) { }
     UserSettingUniquePtr min;
     UserSettingUniquePtr max;
 };
 
 class VelocityRandomInitializer : public ParticleInitializerBase {
-  public:
-    VelocityRandomInitializer (UserSettingUniquePtr min, UserSettingUniquePtr max) : min (std::move (min)), max (std::move (max)) {}
+public:
+    VelocityRandomInitializer (UserSettingUniquePtr min, UserSettingUniquePtr max) :
+	min (std::move (min)), max (std::move (max)) { }
     UserSettingUniquePtr min;
     UserSettingUniquePtr max;
 };
 
 class RotationRandomInitializer : public ParticleInitializerBase {
-  public:
-    RotationRandomInitializer (UserSettingUniquePtr min, UserSettingUniquePtr max) : min (std::move (min)), max (std::move (max)) {}
+public:
+    RotationRandomInitializer (UserSettingUniquePtr min, UserSettingUniquePtr max) :
+	min (std::move (min)), max (std::move (max)) { }
     UserSettingUniquePtr min;
     UserSettingUniquePtr max;
 };
 
 class AngularVelocityRandomInitializer : public ParticleInitializerBase {
-  public:
-    AngularVelocityRandomInitializer (UserSettingUniquePtr min, UserSettingUniquePtr max, UserSettingUniquePtr exponent) : min (std::move (min)), max (std::move (max)), exponent (std::move (exponent)) {}
+public:
+    AngularVelocityRandomInitializer (
+	UserSettingUniquePtr min, UserSettingUniquePtr max, UserSettingUniquePtr exponent
+    ) : min (std::move (min)), max (std::move (max)), exponent (std::move (exponent)) { }
     UserSettingUniquePtr min;
     UserSettingUniquePtr max;
     UserSettingUniquePtr exponent;
 };
 
 class TurbulentVelocityRandomInitializer : public ParticleInitializerBase {
-  public:
-    TurbulentVelocityRandomInitializer (UserSettingUniquePtr speedMin, UserSettingUniquePtr speedMax, UserSettingUniquePtr scale, UserSettingUniquePtr offset, UserSettingUniquePtr forward, UserSettingUniquePtr timeScale, UserSettingUniquePtr phaseMin, UserSettingUniquePtr phaseMax, UserSettingUniquePtr right)
-        : speedMin (std::move (speedMin)), speedMax (std::move (speedMax)), scale (std::move (scale)), offset (std::move (offset)), forward (std::move (forward)), timeScale (std::move (timeScale)), phaseMin (std::move (phaseMin)), phaseMax (std::move (phaseMax)), right (std::move (right)) {}
+public:
+    TurbulentVelocityRandomInitializer (
+	UserSettingUniquePtr speedMin, UserSettingUniquePtr speedMax, UserSettingUniquePtr scale,
+	UserSettingUniquePtr offset, UserSettingUniquePtr forward, UserSettingUniquePtr timeScale,
+	UserSettingUniquePtr phaseMin, UserSettingUniquePtr phaseMax, UserSettingUniquePtr right
+    ) :
+	speedMin (std::move (speedMin)), speedMax (std::move (speedMax)), scale (std::move (scale)),
+	offset (std::move (offset)), forward (std::move (forward)), timeScale (std::move (timeScale)),
+	phaseMin (std::move (phaseMin)), phaseMax (std::move (phaseMax)), right (std::move (right)) { }
     UserSettingUniquePtr speedMin;
     UserSettingUniquePtr speedMax;
     UserSettingUniquePtr scale;
@@ -251,9 +266,13 @@ class TurbulentVelocityRandomInitializer : public ParticleInitializerBase {
 };
 
 class MapSequenceAroundControlPointInitializer : public ParticleInitializerBase {
-  public:
-    MapSequenceAroundControlPointInitializer (UserSettingUniquePtr controlPoint, UserSettingUniquePtr count, UserSettingUniquePtr speedMin, UserSettingUniquePtr speedMax)
-        : controlPoint (std::move (controlPoint)), count (std::move (count)), speedMin (std::move (speedMin)), speedMax (std::move (speedMax)) {}
+public:
+    MapSequenceAroundControlPointInitializer (
+	UserSettingUniquePtr controlPoint, UserSettingUniquePtr count, UserSettingUniquePtr speedMin,
+	UserSettingUniquePtr speedMax
+    ) :
+	controlPoint (std::move (controlPoint)), count (std::move (count)), speedMin (std::move (speedMin)),
+	speedMax (std::move (speedMax)) { }
     UserSettingUniquePtr controlPoint;
     UserSettingUniquePtr count;
     UserSettingUniquePtr speedMin;
@@ -266,35 +285,42 @@ using ParticleInitializerUniquePtr = std::unique_ptr<ParticleInitializerBase>;
  * Particle operator base and implementations
  */
 class ParticleOperatorBase : public TypeCaster {
-  public:
+public:
     virtual ~ParticleOperatorBase () = default;
 };
 
 class MovementOperator : public ParticleOperatorBase {
-  public:
-    MovementOperator (UserSettingUniquePtr drag, UserSettingUniquePtr gravity) : drag (std::move (drag)), gravity (std::move (gravity)) {}
+public:
+    MovementOperator (UserSettingUniquePtr drag, UserSettingUniquePtr gravity) :
+	drag (std::move (drag)), gravity (std::move (gravity)) { }
     UserSettingUniquePtr drag;
     UserSettingUniquePtr gravity;
 };
 
 class AngularMovementOperator : public ParticleOperatorBase {
-  public:
-    AngularMovementOperator (UserSettingUniquePtr drag, UserSettingUniquePtr force) : drag (std::move (drag)), force (std::move (force)) {}
+public:
+    AngularMovementOperator (UserSettingUniquePtr drag, UserSettingUniquePtr force) :
+	drag (std::move (drag)), force (std::move (force)) { }
     UserSettingUniquePtr drag;
     UserSettingUniquePtr force;
 };
 
 class AlphaFadeOperator : public ParticleOperatorBase {
-  public:
-    AlphaFadeOperator (UserSettingUniquePtr fadeInTime, UserSettingUniquePtr fadeOutTime) : fadeInTime (std::move (fadeInTime)), fadeOutTime (std::move (fadeOutTime)) {}
+public:
+    AlphaFadeOperator (UserSettingUniquePtr fadeInTime, UserSettingUniquePtr fadeOutTime) :
+	fadeInTime (std::move (fadeInTime)), fadeOutTime (std::move (fadeOutTime)) { }
     UserSettingUniquePtr fadeInTime;
     UserSettingUniquePtr fadeOutTime;
 };
 
 class SizeChangeOperator : public ParticleOperatorBase {
-  public:
-    SizeChangeOperator (UserSettingUniquePtr startTime, UserSettingUniquePtr endTime, UserSettingUniquePtr startValue, UserSettingUniquePtr endValue)
-        : startTime (std::move (startTime)), endTime (std::move (endTime)), startValue (std::move (startValue)), endValue (std::move (endValue)) {}
+public:
+    SizeChangeOperator (
+	UserSettingUniquePtr startTime, UserSettingUniquePtr endTime, UserSettingUniquePtr startValue,
+	UserSettingUniquePtr endValue
+    ) :
+	startTime (std::move (startTime)), endTime (std::move (endTime)), startValue (std::move (startValue)),
+	endValue (std::move (endValue)) { }
     UserSettingUniquePtr startTime;
     UserSettingUniquePtr endTime;
     UserSettingUniquePtr startValue;
@@ -302,9 +328,13 @@ class SizeChangeOperator : public ParticleOperatorBase {
 };
 
 class AlphaChangeOperator : public ParticleOperatorBase {
-  public:
-    AlphaChangeOperator (UserSettingUniquePtr startTime, UserSettingUniquePtr endTime, UserSettingUniquePtr startValue, UserSettingUniquePtr endValue)
-        : startTime (std::move (startTime)), endTime (std::move (endTime)), startValue (std::move (startValue)), endValue (std::move (endValue)) {}
+public:
+    AlphaChangeOperator (
+	UserSettingUniquePtr startTime, UserSettingUniquePtr endTime, UserSettingUniquePtr startValue,
+	UserSettingUniquePtr endValue
+    ) :
+	startTime (std::move (startTime)), endTime (std::move (endTime)), startValue (std::move (startValue)),
+	endValue (std::move (endValue)) { }
     UserSettingUniquePtr startTime;
     UserSettingUniquePtr endTime;
     UserSettingUniquePtr startValue;
@@ -312,9 +342,13 @@ class AlphaChangeOperator : public ParticleOperatorBase {
 };
 
 class ColorChangeOperator : public ParticleOperatorBase {
-  public:
-    ColorChangeOperator (UserSettingUniquePtr startTime, UserSettingUniquePtr endTime, UserSettingUniquePtr startValue, UserSettingUniquePtr endValue)
-        : startTime (std::move (startTime)), endTime (std::move (endTime)), startValue (std::move (startValue)), endValue (std::move (endValue)) {}
+public:
+    ColorChangeOperator (
+	UserSettingUniquePtr startTime, UserSettingUniquePtr endTime, UserSettingUniquePtr startValue,
+	UserSettingUniquePtr endValue
+    ) :
+	startTime (std::move (startTime)), endTime (std::move (endTime)), startValue (std::move (startValue)),
+	endValue (std::move (endValue)) { }
     UserSettingUniquePtr startTime;
     UserSettingUniquePtr endTime;
     UserSettingUniquePtr startValue;
@@ -322,9 +356,21 @@ class ColorChangeOperator : public ParticleOperatorBase {
 };
 
 class TurbulenceOperator : public ParticleOperatorBase {
-  public:
-    TurbulenceOperator (UserSettingUniquePtr scale, UserSettingUniquePtr speedMin, UserSettingUniquePtr speedMax, UserSettingUniquePtr timeScale, UserSettingUniquePtr mask, UserSettingUniquePtr phaseMin, UserSettingUniquePtr phaseMax, UserSettingUniquePtr audioProcessingMode, UserSettingUniquePtr audioProcessingBounds, UserSettingUniquePtr audioProcessingExponent, UserSettingUniquePtr audioProcessingFrequencyStart, UserSettingUniquePtr audioProcessingFrequencyEnd)
-        : scale (std::move (scale)), speedMin (std::move (speedMin)), speedMax (std::move (speedMax)), timeScale (std::move (timeScale)), mask (std::move (mask)), phaseMin (std::move (phaseMin)), phaseMax (std::move (phaseMax)), audioProcessingMode(std::move(audioProcessingMode)), audioProcessingBounds(std::move(audioProcessingBounds)), audioProcessingExponent(std::move(audioProcessingExponent)), audioProcessingFrequencyStart(std::move(audioProcessingFrequencyStart)), audioProcessingFrequencyEnd(std::move(audioProcessingFrequencyEnd)) {}
+public:
+    TurbulenceOperator (
+	UserSettingUniquePtr scale, UserSettingUniquePtr speedMin, UserSettingUniquePtr speedMax,
+	UserSettingUniquePtr timeScale, UserSettingUniquePtr mask, UserSettingUniquePtr phaseMin,
+	UserSettingUniquePtr phaseMax, UserSettingUniquePtr audioProcessingMode,
+	UserSettingUniquePtr audioProcessingBounds, UserSettingUniquePtr audioProcessingExponent,
+	UserSettingUniquePtr audioProcessingFrequencyStart, UserSettingUniquePtr audioProcessingFrequencyEnd
+    ) :
+	scale (std::move (scale)), speedMin (std::move (speedMin)), speedMax (std::move (speedMax)),
+	timeScale (std::move (timeScale)), mask (std::move (mask)), phaseMin (std::move (phaseMin)),
+	phaseMax (std::move (phaseMax)), audioProcessingMode (std::move (audioProcessingMode)),
+	audioProcessingBounds (std::move (audioProcessingBounds)),
+	audioProcessingExponent (std::move (audioProcessingExponent)),
+	audioProcessingFrequencyStart (std::move (audioProcessingFrequencyStart)),
+	audioProcessingFrequencyEnd (std::move (audioProcessingFrequencyEnd)) { }
     UserSettingUniquePtr scale;
     UserSettingUniquePtr speedMin;
     UserSettingUniquePtr speedMax;
@@ -340,42 +386,45 @@ class TurbulenceOperator : public ParticleOperatorBase {
 };
 
 class VortexOperator : public ParticleOperatorBase {
-  public:
-    VortexOperator (int controlPoint, int flags, UserSettingUniquePtr axis, UserSettingUniquePtr offset,
-                    UserSettingUniquePtr distanceInner, UserSettingUniquePtr distanceOuter,
-                    UserSettingUniquePtr speedInner, UserSettingUniquePtr speedOuter,
-                    UserSettingUniquePtr centerForce,
-                    UserSettingUniquePtr ringRadius, UserSettingUniquePtr ringWidth,
-                    UserSettingUniquePtr ringPullDistance, UserSettingUniquePtr ringPullForce,
-                    UserSettingUniquePtr audioProcessingMode, UserSettingUniquePtr audioProcessingBounds)
-        : controlPoint (controlPoint), flags (flags), axis (std::move (axis)), offset (std::move (offset)),
-          distanceInner (std::move (distanceInner)), distanceOuter (std::move (distanceOuter)),
-          speedInner (std::move (speedInner)), speedOuter (std::move (speedOuter)),
-          centerForce (std::move (centerForce)),
-          ringRadius (std::move (ringRadius)), ringWidth (std::move (ringWidth)),
-          ringPullDistance (std::move (ringPullDistance)), ringPullForce (std::move (ringPullForce)),
-          audioProcessingMode (std::move (audioProcessingMode)), audioProcessingBounds (std::move (audioProcessingBounds)) {}
+public:
+    VortexOperator (
+	int controlPoint, int flags, UserSettingUniquePtr axis, UserSettingUniquePtr offset,
+	UserSettingUniquePtr distanceInner, UserSettingUniquePtr distanceOuter, UserSettingUniquePtr speedInner,
+	UserSettingUniquePtr speedOuter, UserSettingUniquePtr centerForce, UserSettingUniquePtr ringRadius,
+	UserSettingUniquePtr ringWidth, UserSettingUniquePtr ringPullDistance, UserSettingUniquePtr ringPullForce,
+	UserSettingUniquePtr audioProcessingMode, UserSettingUniquePtr audioProcessingBounds
+    ) :
+	controlPoint (controlPoint), flags (flags), axis (std::move (axis)), offset (std::move (offset)),
+	distanceInner (std::move (distanceInner)), distanceOuter (std::move (distanceOuter)),
+	speedInner (std::move (speedInner)), speedOuter (std::move (speedOuter)), centerForce (std::move (centerForce)),
+	ringRadius (std::move (ringRadius)), ringWidth (std::move (ringWidth)),
+	ringPullDistance (std::move (ringPullDistance)), ringPullForce (std::move (ringPullForce)),
+	audioProcessingMode (std::move (audioProcessingMode)),
+	audioProcessingBounds (std::move (audioProcessingBounds)) { }
     int controlPoint;
-    int flags;                                  // 1 = infinite axis, 2 = maintain distance to center, 4 = ring shape
+    int flags; // 1 = infinite axis, 2 = maintain distance to center, 4 = ring shape
     UserSettingUniquePtr axis;
     UserSettingUniquePtr offset;
-    UserSettingUniquePtr distanceInner;         // Standard vortex inner radius
-    UserSettingUniquePtr distanceOuter;         // Standard vortex outer radius
+    UserSettingUniquePtr distanceInner; // Standard vortex inner radius
+    UserSettingUniquePtr distanceOuter; // Standard vortex outer radius
     UserSettingUniquePtr speedInner;
     UserSettingUniquePtr speedOuter;
-    UserSettingUniquePtr centerForce;           // Strength to pull particles toward center
-    UserSettingUniquePtr ringRadius;            // Ring mode: radius of the ring
-    UserSettingUniquePtr ringWidth;             // Ring mode: width of the ring
-    UserSettingUniquePtr ringPullDistance;      // Ring mode: distance at which ring attracts particles
-    UserSettingUniquePtr ringPullForce;         // Ring mode: strength of ring attraction
+    UserSettingUniquePtr centerForce; // Strength to pull particles toward center
+    UserSettingUniquePtr ringRadius; // Ring mode: radius of the ring
+    UserSettingUniquePtr ringWidth; // Ring mode: width of the ring
+    UserSettingUniquePtr ringPullDistance; // Ring mode: distance at which ring attracts particles
+    UserSettingUniquePtr ringPullForce; // Ring mode: strength of ring attraction
     UserSettingUniquePtr audioProcessingMode;
     UserSettingUniquePtr audioProcessingBounds;
 };
 
 class ControlPointAttractOperator : public ParticleOperatorBase {
-  public:
-    ControlPointAttractOperator (int controlPoint, UserSettingUniquePtr origin, UserSettingUniquePtr scale, UserSettingUniquePtr threshold)
-        : controlPoint (controlPoint), origin (std::move (origin)), scale (std::move (scale)), threshold (std::move (threshold)) {}
+public:
+    ControlPointAttractOperator (
+	int controlPoint, UserSettingUniquePtr origin, UserSettingUniquePtr scale, UserSettingUniquePtr threshold
+    ) :
+	controlPoint (controlPoint), origin (std::move (origin)), scale (std::move (scale)),
+	threshold (std::move (threshold)) { }
     int controlPoint;
     UserSettingUniquePtr origin;
     UserSettingUniquePtr scale;
@@ -383,9 +432,14 @@ class ControlPointAttractOperator : public ParticleOperatorBase {
 };
 
 class OscillateAlphaOperator : public ParticleOperatorBase {
-  public:
-    OscillateAlphaOperator (UserSettingUniquePtr frequencyMin, UserSettingUniquePtr frequencyMax, UserSettingUniquePtr scaleMin, UserSettingUniquePtr scaleMax, UserSettingUniquePtr phaseMin, UserSettingUniquePtr phaseMax)
-        : frequencyMin (std::move (frequencyMin)), frequencyMax (std::move (frequencyMax)), scaleMin (std::move (scaleMin)), scaleMax (std::move (scaleMax)), phaseMin (std::move (phaseMin)), phaseMax (std::move (phaseMax)) {}
+public:
+    OscillateAlphaOperator (
+	UserSettingUniquePtr frequencyMin, UserSettingUniquePtr frequencyMax, UserSettingUniquePtr scaleMin,
+	UserSettingUniquePtr scaleMax, UserSettingUniquePtr phaseMin, UserSettingUniquePtr phaseMax
+    ) :
+	frequencyMin (std::move (frequencyMin)), frequencyMax (std::move (frequencyMax)),
+	scaleMin (std::move (scaleMin)), scaleMax (std::move (scaleMax)), phaseMin (std::move (phaseMin)),
+	phaseMax (std::move (phaseMax)) { }
     UserSettingUniquePtr frequencyMin;
     UserSettingUniquePtr frequencyMax;
     UserSettingUniquePtr scaleMin;
@@ -395,9 +449,14 @@ class OscillateAlphaOperator : public ParticleOperatorBase {
 };
 
 class OscillateSizeOperator : public ParticleOperatorBase {
-  public:
-    OscillateSizeOperator (UserSettingUniquePtr frequencyMin, UserSettingUniquePtr frequencyMax, UserSettingUniquePtr scaleMin, UserSettingUniquePtr scaleMax, UserSettingUniquePtr phaseMin, UserSettingUniquePtr phaseMax)
-        : frequencyMin (std::move (frequencyMin)), frequencyMax (std::move (frequencyMax)), scaleMin (std::move (scaleMin)), scaleMax (std::move (scaleMax)), phaseMin (std::move (phaseMin)), phaseMax (std::move (phaseMax)) {}
+public:
+    OscillateSizeOperator (
+	UserSettingUniquePtr frequencyMin, UserSettingUniquePtr frequencyMax, UserSettingUniquePtr scaleMin,
+	UserSettingUniquePtr scaleMax, UserSettingUniquePtr phaseMin, UserSettingUniquePtr phaseMax
+    ) :
+	frequencyMin (std::move (frequencyMin)), frequencyMax (std::move (frequencyMax)),
+	scaleMin (std::move (scaleMin)), scaleMax (std::move (scaleMax)), phaseMin (std::move (phaseMin)),
+	phaseMax (std::move (phaseMax)) { }
     UserSettingUniquePtr frequencyMin;
     UserSettingUniquePtr frequencyMax;
     UserSettingUniquePtr scaleMin;
@@ -407,9 +466,15 @@ class OscillateSizeOperator : public ParticleOperatorBase {
 };
 
 class OscillatePositionOperator : public ParticleOperatorBase {
-  public:
-    OscillatePositionOperator (UserSettingUniquePtr frequencyMin, UserSettingUniquePtr frequencyMax, UserSettingUniquePtr scaleMin, UserSettingUniquePtr scaleMax, UserSettingUniquePtr phaseMin, UserSettingUniquePtr phaseMax, UserSettingUniquePtr mask)
-        : frequencyMin (std::move (frequencyMin)), frequencyMax (std::move (frequencyMax)), scaleMin (std::move (scaleMin)), scaleMax (std::move (scaleMax)), phaseMin (std::move (phaseMin)), phaseMax (std::move (phaseMax)), mask (std::move (mask)) {}
+public:
+    OscillatePositionOperator (
+	UserSettingUniquePtr frequencyMin, UserSettingUniquePtr frequencyMax, UserSettingUniquePtr scaleMin,
+	UserSettingUniquePtr scaleMax, UserSettingUniquePtr phaseMin, UserSettingUniquePtr phaseMax,
+	UserSettingUniquePtr mask
+    ) :
+	frequencyMin (std::move (frequencyMin)), frequencyMax (std::move (frequencyMax)),
+	scaleMin (std::move (scaleMin)), scaleMax (std::move (scaleMax)), phaseMin (std::move (phaseMin)),
+	phaseMax (std::move (phaseMax)), mask (std::move (mask)) { }
     UserSettingUniquePtr frequencyMin;
     UserSettingUniquePtr frequencyMax;
     UserSettingUniquePtr scaleMin;
@@ -458,8 +523,8 @@ struct ParticleInstanceOverride {
     UserSettingUniquePtr rate;
     UserSettingUniquePtr speed;
     UserSettingUniquePtr count;
-    UserSettingUniquePtr color;   // Replaces particle color
-    UserSettingUniquePtr colorn;  // Multiplies particle color
+    UserSettingUniquePtr color; // Replaces particle color
+    UserSettingUniquePtr colorn; // Multiplies particle color
 };
 
 struct ParticleData {
@@ -498,8 +563,9 @@ struct ParticleData {
 };
 
 class Particle : public Object, public ParticleData {
-  public:
-    explicit Particle (ObjectData data, ParticleData particleData) noexcept : Object (std::move(data)), ParticleData (std::move (particleData)) {};
+public:
+    explicit Particle (ObjectData data, ParticleData particleData) noexcept :
+	Object (std::move (data)), ParticleData (std::move (particleData)) { };
     ~Particle () override = default;
 };
 } // namespace WallpaperEngine::Data::Model

+ 2 - 7
src/WallpaperEngine/Data/Model/Project.h

@@ -1,7 +1,7 @@
 #pragma once
 
-#include <string>
 #include <memory>
+#include <string>
 
 #include "Types.h"
 #include "WallpaperEngine/Assets/AssetLocator.h"
@@ -12,12 +12,7 @@ using namespace WallpaperEngine::Assets;
  * Represents a wallpaper engine project
  */
 struct Project {
-    enum Type {
-        Type_Scene = 0,
-        Type_Web = 1,
-        Type_Video = 2,
-        Type_Unknown = 3
-    };
+    enum Type { Type_Scene = 0, Type_Web = 1, Type_Video = 2, Type_Unknown = 3 };
 
     /** Wallpapers title */
     std::string title;

+ 135 - 149
src/WallpaperEngine/Data/Model/Property.h

@@ -1,10 +1,10 @@
 #pragma once
 
+#include "../Utils/TypeCaster.h"
+#include "DynamicValue.h"
 #include <map>
 #include <string>
 #include <utility>
-#include "DynamicValue.h"
-#include "../Utils/TypeCaster.h"
 
 namespace WallpaperEngine::Data::Model {
 using namespace WallpaperEngine::Data::Utils;
@@ -26,250 +26,236 @@ struct ComboData {
 };
 
 class Property : public DynamicValue, public TypeCaster, public PropertyData {
-  public:
-    explicit Property (PropertyData data) : DynamicValue (), TypeCaster (), PropertyData (std::move(data)) {}
+public:
+    explicit Property (PropertyData data) : DynamicValue (), TypeCaster (), PropertyData (std::move (data)) { }
 
     using DynamicValue::update;
-    virtual void update(const std::string& value) = 0;
+    virtual void update (const std::string& value) = 0;
     [[nodiscard]] virtual std::string dump () const = 0;
 };
 
 class PropertySlider final : public Property, SliderData {
-  public:
-    PropertySlider (PropertyData data, SliderData sliderData, const float value) : Property (std::move(data)), SliderData (std::move (sliderData)) {
-        this->Property::update (value);
+public:
+    PropertySlider (PropertyData data, SliderData sliderData, const float value) :
+	Property (std::move (data)), SliderData (std::move (sliderData)) {
+	this->Property::update (value);
     }
 
     using Property::update;
-    void update(const std::string& value) override {
-        this->update (std::stof (value));
-    }
+    void update (const std::string& value) override { this->update (std::stof (value)); }
 
     [[nodiscard]] std::string dump () const override {
-        std::stringstream ss;
+	std::stringstream ss;
 
-        ss << this->name << " - slider" << std::endl
-           << "\tText: " << this->text << std::endl
-           << "\tMin: " << this->min << std::endl
-           << "\tMax: " << this->max << std::endl
-           << "\tStep: " << this->step << std::endl
-           << "\tValue: " << this->toString () << std::endl;
+	ss << this->name << " - slider" << std::endl
+	   << "\tText: " << this->text << std::endl
+	   << "\tMin: " << this->min << std::endl
+	   << "\tMax: " << this->max << std::endl
+	   << "\tStep: " << this->step << std::endl
+	   << "\tValue: " << this->toString () << std::endl;
 
-        return ss.str ();
+	return ss.str ();
     }
 };
 
 class PropertyBoolean final : public Property {
-  public:
-    explicit PropertyBoolean (PropertyData data, const bool value) : Property (std::move(data)) {
-        this->Property::update (value);
+public:
+    explicit PropertyBoolean (PropertyData data, const bool value) : Property (std::move (data)) {
+	this->Property::update (value);
     }
 
     using Property::update;
-    void update(const std::string& value) override {
-        this->update (value == "true" || value == "1");
-    }
+    void update (const std::string& value) override { this->update (value == "true" || value == "1"); }
 
     [[nodiscard]] std::string dump () const override {
-        std::stringstream ss;
+	std::stringstream ss;
 
-        ss << this->name << " - boolean" << std::endl
-           << "\tText: " << this->text << std::endl
-           << "\tValue: " << this->toString () << std::endl;
+	ss << this->name << " - boolean" << std::endl
+	   << "\tText: " << this->text << std::endl
+	   << "\tValue: " << this->toString () << std::endl;
 
-        return ss.str ();
+	return ss.str ();
     }
 };
 
 class PropertyColor final : public Property {
-  public:
-    explicit PropertyColor (PropertyData data, const std::string& value) : Property (std::move(data)) {
-        this->PropertyColor::update (value);
+public:
+    explicit PropertyColor (PropertyData data, const std::string& value) : Property (std::move (data)) {
+	this->PropertyColor::update (value);
     }
 
     using Property::update;
-    void update(const std::string& value) override {
-        auto copy = value;
-
-        // TODO: ENSURE ALL THIS PARSING IS CORRECT
-        if (copy.find (',') != std::string::npos) {
-            // replace comma separator with spaces so it's
-            std::ranges::replace (copy, ',', ' ');
-        }
-
-        // hex colors should be converted to int colors
-        if (copy.find ('#') == 0) {
-            auto number = copy.substr (1);
-
-            // support for css notation
-            if (number.size () == 3) {
-                number = number[0] + number[0] + number[1] + number[1] + number[2] + number[2];
-            }
-
-            // remove alpha if it's present, should look into it more closely
-            if (number.size () > 6) {
-                sLog.error ("Color value has alpha channel, which is not supported");
-                number = number.substr (0, 6);
-            }
-
-            const auto color = std::stoi (number, nullptr, 16);
-
-            // format the number as float vector
-            copy =
-                std::to_string (((color >> 16) & 0xFF) / 255.0) + " " +
-                std::to_string (((color >> 8) & 0xFF) / 255.0) + " " +
-                std::to_string ((color & 0xFF) / 255.0);
-        } else if (copy.find ('.') == std::string::npos) {
-            // integer vector, convert it to float vector
-            const auto intcolor = VectorBuilder::parse <glm::ivec3> (copy);
-
-            copy =
-                std::to_string (intcolor.r / 255.0) + " " +
-                std::to_string (intcolor.g / 255.0) + " " +
-                std::to_string (intcolor.b / 255.0);
-        }
-
-        // finally parse the string as a float vector
-        this->update (VectorBuilder::parse <glm::vec3> (copy));
+    void update (const std::string& value) override {
+	auto copy = value;
+
+	// TODO: ENSURE ALL THIS PARSING IS CORRECT
+	if (copy.find (',') != std::string::npos) {
+	    // replace comma separator with spaces so it's
+	    std::ranges::replace (copy, ',', ' ');
+	}
+
+	// hex colors should be converted to int colors
+	if (copy.find ('#') == 0) {
+	    auto number = copy.substr (1);
+
+	    // support for css notation
+	    if (number.size () == 3) {
+		number = number[0] + number[0] + number[1] + number[1] + number[2] + number[2];
+	    }
+
+	    // remove alpha if it's present, should look into it more closely
+	    if (number.size () > 6) {
+		sLog.error ("Color value has alpha channel, which is not supported");
+		number = number.substr (0, 6);
+	    }
+
+	    const auto color = std::stoi (number, nullptr, 16);
+
+	    // format the number as float vector
+	    copy = std::to_string (((color >> 16) & 0xFF) / 255.0) + " "
+		+ std::to_string (((color >> 8) & 0xFF) / 255.0) + " " + std::to_string ((color & 0xFF) / 255.0);
+	} else if (copy.find ('.') == std::string::npos) {
+	    // integer vector, convert it to float vector
+	    const auto intcolor = VectorBuilder::parse<glm::ivec3> (copy);
+
+	    copy = std::to_string (intcolor.r / 255.0) + " " + std::to_string (intcolor.g / 255.0) + " "
+		+ std::to_string (intcolor.b / 255.0);
+	}
+
+	// finally parse the string as a float vector
+	this->update (VectorBuilder::parse<glm::vec3> (copy));
     }
 
     [[nodiscard]] std::string dump () const override {
-        std::stringstream ss;
+	std::stringstream ss;
 
-        ss << this->name << " - color" << std::endl
-           << "\tText: " << this->text << std::endl
-           << "\tValue: " << this->toString () << std::endl;
+	ss << this->name << " - color" << std::endl
+	   << "\tText: " << this->text << std::endl
+	   << "\tValue: " << this->toString () << std::endl;
 
-        return ss.str ();
+	return ss.str ();
     }
 };
 
 class PropertyCombo final : public Property, ComboData {
-  public:
-    PropertyCombo (PropertyData data, ComboData comboData, const std::string& value) : Property (std::move(data)), ComboData (std::move(comboData)) {
-        this->PropertyCombo::update (value);
+public:
+    PropertyCombo (PropertyData data, ComboData comboData, const std::string& value) :
+	Property (std::move (data)), ComboData (std::move (comboData)) {
+	this->PropertyCombo::update (value);
     }
 
     using Property::update;
-    void update(const std::string& value) override {
-        if (this->values.contains (value) == false) {
-            sLog.error ("Combo value not found in combo options: ", value);
-            return;
-        }
-
-        // search for the value in the combo options or default to the textual value
-        this->DynamicValue::update (value);
+    void update (const std::string& value) override {
+	if (this->values.contains (value) == false) {
+	    sLog.error ("Combo value not found in combo options: ", value);
+	    return;
+	}
+
+	// search for the value in the combo options or default to the textual value
+	this->DynamicValue::update (value);
     }
 
     [[nodiscard]] std::string dump () const override {
-        std::stringstream ss;
+	std::stringstream ss;
 
-        ss << this->name << " - combo" << std::endl
-           << "\tText: " << this->text << std::endl
-           << "\tValue: " << this->toString () << std::endl
-           << "Values: " << std::endl;
+	ss << this->name << " - combo" << std::endl
+	   << "\tText: " << this->text << std::endl
+	   << "\tValue: " << this->toString () << std::endl
+	   << "Values: " << std::endl;
 
-        for (const auto& [key, value] : this->values) {
-            ss << "\t\t" << key << " = " << value << std::endl;
-        }
+	for (const auto& [key, value] : this->values) {
+	    ss << "\t\t" << key << " = " << value << std::endl;
+	}
 
-        return ss.str ();
+	return ss.str ();
     }
 };
 
 class PropertyText final : public Property {
-  public:
-    explicit PropertyText (PropertyData data) : Property (std::move(data)) {}
+public:
+    explicit PropertyText (PropertyData data) : Property (std::move (data)) { }
 
     using Property::update;
-    void update(const std::string& value) override {
-        throw std::runtime_error ("PropertyText::update() is not implemented");
+    void update (const std::string& value) override {
+	throw std::runtime_error ("PropertyText::update() is not implemented");
     }
 
-    [[nodiscard]] std::string toString () const override {
-        return this->text;
-    }
+    [[nodiscard]] std::string toString () const override { return this->text; }
 
     [[nodiscard]] std::string dump () const override {
-        std::stringstream ss;
+	std::stringstream ss;
 
-        ss << this->name << " - text" << std::endl
-           << "\tText: " << this->text << std::endl
-           << "\tValue: " << this->toString () << std::endl;
+	ss << this->name << " - text" << std::endl
+	   << "\tText: " << this->text << std::endl
+	   << "\tValue: " << this->toString () << std::endl;
 
-        return ss.str ();
+	return ss.str ();
     }
 };
 
 class PropertySceneTexture final : public Property {
-  public:
-    explicit PropertySceneTexture (PropertyData data, const std::string& value) : Property (std::move(data)) {
-        this->PropertySceneTexture::update (value);
+public:
+    explicit PropertySceneTexture (PropertyData data, const std::string& value) : Property (std::move (data)) {
+	this->PropertySceneTexture::update (value);
     }
 
-    void update(const std::string& value) override {
-        this->m_value = value;
-    }
+    void update (const std::string& value) override { this->m_value = value; }
 
     [[nodiscard]] std::string dump () const override {
-        std::stringstream ss;
+	std::stringstream ss;
 
-        ss << this->name << " - scene texture" << std::endl
-           << "\tText: " << this->text << std::endl
-           << "\tValue: " << this->m_value << std::endl;
+	ss << this->name << " - scene texture" << std::endl
+	   << "\tText: " << this->text << std::endl
+	   << "\tValue: " << this->m_value << std::endl;
 
-        return ss.str ();
+	return ss.str ();
     }
 
-  private:
+private:
     std::string m_value;
 };
 
 class PropertyFile final : public Property {
-  public:
-    explicit PropertyFile (PropertyData data, const std::string& value) : Property (std::move(data)) {
-        this->PropertyFile::update (value);
+public:
+    explicit PropertyFile (PropertyData data, const std::string& value) : Property (std::move (data)) {
+	this->PropertyFile::update (value);
     }
 
-    void update(const std::string& value) override {
-        this->m_value = value;
-    }
+    void update (const std::string& value) override { this->m_value = value; }
 
     [[nodiscard]] std::string dump () const override {
-        std::stringstream ss;
+	std::stringstream ss;
 
-        ss << this->name << " - file" << std::endl
-           << "\tText: " << this->text << std::endl
-           << "\tValue: " << this->m_value << std::endl;
+	ss << this->name << " - file" << std::endl
+	   << "\tText: " << this->text << std::endl
+	   << "\tValue: " << this->m_value << std::endl;
 
-        return ss.str ();
+	return ss.str ();
     }
 
-  private:
+private:
     std::string m_value;
 };
 
 class PropertyTextInput final : public Property {
-  public:
-    explicit PropertyTextInput (PropertyData data, const std::string& value) : Property (std::move(data)) {
-        this->PropertyTextInput::update (value);
+public:
+    explicit PropertyTextInput (PropertyData data, const std::string& value) : Property (std::move (data)) {
+	this->PropertyTextInput::update (value);
     }
 
-    void update(const std::string& value) override {
-        this->m_value = value;
-    }
+    void update (const std::string& value) override { this->m_value = value; }
 
     [[nodiscard]] std::string dump () const override {
-        std::stringstream ss;
+	std::stringstream ss;
 
-        ss << this->name << " - textinput" << std::endl
-           << "\tText: " << this->text << std::endl
-           << "\tValue: " << this->m_value << std::endl;
+	ss << this->name << " - textinput" << std::endl
+	   << "\tText: " << this->text << std::endl
+	   << "\tValue: " << this->m_value << std::endl;
 
-        return ss.str ();
+	return ss.str ();
     }
 
-  private:
+private:
     std::string m_value;
 };
 }

+ 25 - 25
src/WallpaperEngine/Data/Model/Types.h

@@ -1,9 +1,9 @@
 #pragma once
 
 #include <map>
-#include <vector>
-#include <string>
 #include <memory>
+#include <string>
+#include <vector>
 
 namespace WallpaperEngine::Data::Model {
 struct Project;
@@ -33,31 +33,31 @@ struct Effect;
 struct EffectPass;
 struct ModelStruct;
 
-using PropertySharedPtr = std::shared_ptr <Property>;
-using Properties = std::map <std::string, PropertySharedPtr>;
-using DynamicValueUniquePtr = std::unique_ptr <DynamicValue>;
-using UserSettingUniquePtr = std::unique_ptr <UserSetting>;
+using PropertySharedPtr = std::shared_ptr<Property>;
+using Properties = std::map<std::string, PropertySharedPtr>;
+using DynamicValueUniquePtr = std::unique_ptr<DynamicValue>;
+using UserSettingUniquePtr = std::unique_ptr<UserSetting>;
 
-using ShaderConstantMap = std::map <std::string, UserSettingUniquePtr>;
+using ShaderConstantMap = std::map<std::string, UserSettingUniquePtr>;
 
-using ProjectUniquePtr = std::unique_ptr <Project>;
-using WallpaperUniquePtr = std::unique_ptr <Wallpaper>;
-using SceneUniquePtr = std::unique_ptr <Scene>;
-using WebUniquePtr = std::unique_ptr <Web>;
-using VideoUniquePtr = std::unique_ptr <Video>;
-using ObjectUniquePtr = std::unique_ptr <Object>;
-using SoundUniquePtr = std::unique_ptr <Sound>;
-using ImageUniquePtr = std::unique_ptr <Image>;
-using ParticleUniquePtr = std::unique_ptr <Particle>;
-using MaterialUniquePtr = std::unique_ptr <Material>;
-using MaterialPassUniquePtr = std::unique_ptr <MaterialPass>;
-using EffectUniquePtr = std::unique_ptr <Effect>;
-using ImageAnimationLayerUniquePtr = std::unique_ptr <ImageAnimationLayer>;
-using ImageEffectUniquePtr = std::unique_ptr <ImageEffect>;
-using ImageEffectPassOverrideUniquePtr = std::unique_ptr <ImageEffectPassOverride>;
-using EffectPassUniquePtr = std::unique_ptr <EffectPass>;
-using FBOUniquePtr = std::unique_ptr <FBO>;
-using ModelUniquePtr = std::unique_ptr <ModelStruct>;
+using ProjectUniquePtr = std::unique_ptr<Project>;
+using WallpaperUniquePtr = std::unique_ptr<Wallpaper>;
+using SceneUniquePtr = std::unique_ptr<Scene>;
+using WebUniquePtr = std::unique_ptr<Web>;
+using VideoUniquePtr = std::unique_ptr<Video>;
+using ObjectUniquePtr = std::unique_ptr<Object>;
+using SoundUniquePtr = std::unique_ptr<Sound>;
+using ImageUniquePtr = std::unique_ptr<Image>;
+using ParticleUniquePtr = std::unique_ptr<Particle>;
+using MaterialUniquePtr = std::unique_ptr<Material>;
+using MaterialPassUniquePtr = std::unique_ptr<MaterialPass>;
+using EffectUniquePtr = std::unique_ptr<Effect>;
+using ImageAnimationLayerUniquePtr = std::unique_ptr<ImageAnimationLayer>;
+using ImageEffectUniquePtr = std::unique_ptr<ImageEffect>;
+using ImageEffectPassOverrideUniquePtr = std::unique_ptr<ImageEffectPassOverride>;
+using EffectPassUniquePtr = std::unique_ptr<EffectPass>;
+using FBOUniquePtr = std::unique_ptr<FBO>;
+using ModelUniquePtr = std::unique_ptr<ModelStruct>;
 
 using ObjectList = std::vector<ObjectUniquePtr>;
 using ComboMap = std::map<std::string, int>;

+ 1 - 1
src/WallpaperEngine/Data/Model/UserSetting.h

@@ -18,7 +18,7 @@ struct UserSetting {
     /** The property this setting takes the value from (if specified) */
     PropertySharedPtr property;
     /** Condition required for this setting, this should be possible to run in JS' V8 */
-    std::optional <ConditionInfo> condition;
+    std::optional<ConditionInfo> condition;
     /** TODO: Value might come from a script and not have conditions, implement this later */
 };
 } // namespace WallpaperEngine::Data::Model

+ 69 - 69
src/WallpaperEngine/Data/Model/Wallpaper.h

@@ -5,8 +5,8 @@
 #include <glm/glm.hpp>
 #include <utility>
 
-#include "Types.h"
 #include "Object.h"
+#include "Types.h"
 #include "WallpaperEngine/Data/Utils/TypeCaster.h"
 
 namespace WallpaperEngine::Data::Model {
@@ -18,100 +18,100 @@ struct WallpaperData {
 };
 
 class Wallpaper : public TypeCaster, public WallpaperData {
-  public:
-    explicit Wallpaper (WallpaperData data) noexcept : TypeCaster (), WallpaperData (std::move(data)) {};
+public:
+    explicit Wallpaper (WallpaperData data) noexcept : TypeCaster (), WallpaperData (std::move (data)) { };
     ~Wallpaper () override = default;
 };
 
 class Video final : public Wallpaper {
-  public:
-    explicit Video (WallpaperData data) noexcept : Wallpaper (std::move(data)) {}
+public:
+    explicit Video (WallpaperData data) noexcept : Wallpaper (std::move (data)) { }
 
     ~Video () override = default;
 };
 
-
 class Web final : public Wallpaper {
-  public:
-    explicit Web (WallpaperData data) noexcept : Wallpaper (std::move(data)) {}
+public:
+    explicit Web (WallpaperData data) noexcept : Wallpaper (std::move (data)) { }
 
     ~Web () override = default;
 };
 
 struct SceneData {
     struct {
-        glm::vec3 ambient;
-        glm::vec3 skylight;
-        UserSettingUniquePtr clear;
+	glm::vec3 ambient;
+	glm::vec3 skylight;
+	UserSettingUniquePtr clear;
     } colors;
     /**
      * Camera configuration
      */
     struct Camera {
-        /** Enable fade effect */
-        bool fade;
-        /** Used by the software to allow the users to preview the background or not? */
-        bool preview;
-
-        /**
-         * Bloom effect configuration
-         */
-        struct {
-            /** If bloom is enabled or not */
-            UserSettingUniquePtr enabled;
-            /** Bloom's strength to pass onto the shader */
-            UserSettingUniquePtr strength;
-            /** Bloom's threshold to pass onto the shader */
-            UserSettingUniquePtr threshold;
-        } bloom;
-        /**
-         * Parallax effect configuration
-         */
-        struct {
-            UserSettingUniquePtr enabled;
-            UserSettingUniquePtr amount;
-            UserSettingUniquePtr delay;
-            UserSettingUniquePtr mouseInfluence;
-        } parallax;
-
-        /**
-         * Shake effect configuration
-         */
-        struct {
-            UserSettingUniquePtr enabled;
-            UserSettingUniquePtr amplitude;
-            UserSettingUniquePtr roughness;
-            UserSettingUniquePtr speed;
-        } shake;
-
-        /**
-         * Position configuration
-         */
-        struct {
-            glm::vec3 center;
-            glm::vec3 eye;
-            glm::vec3 up;
-        } configuration;
-
-        /**
-         * Projection information
-         */
-        struct {
-            int width;
-            int height;
-            bool isAuto;
-            float nearz;
-            float farz;
-            float fov;
-        } projection;
+	/** Enable fade effect */
+	bool fade;
+	/** Used by the software to allow the users to preview the background or not? */
+	bool preview;
+
+	/**
+	 * Bloom effect configuration
+	 */
+	struct {
+	    /** If bloom is enabled or not */
+	    UserSettingUniquePtr enabled;
+	    /** Bloom's strength to pass onto the shader */
+	    UserSettingUniquePtr strength;
+	    /** Bloom's threshold to pass onto the shader */
+	    UserSettingUniquePtr threshold;
+	} bloom;
+	/**
+	 * Parallax effect configuration
+	 */
+	struct {
+	    UserSettingUniquePtr enabled;
+	    UserSettingUniquePtr amount;
+	    UserSettingUniquePtr delay;
+	    UserSettingUniquePtr mouseInfluence;
+	} parallax;
+
+	/**
+	 * Shake effect configuration
+	 */
+	struct {
+	    UserSettingUniquePtr enabled;
+	    UserSettingUniquePtr amplitude;
+	    UserSettingUniquePtr roughness;
+	    UserSettingUniquePtr speed;
+	} shake;
+
+	/**
+	 * Position configuration
+	 */
+	struct {
+	    glm::vec3 center;
+	    glm::vec3 eye;
+	    glm::vec3 up;
+	} configuration;
+
+	/**
+	 * Projection information
+	 */
+	struct {
+	    int width;
+	    int height;
+	    bool isAuto;
+	    float nearz;
+	    float farz;
+	    float fov;
+	} projection;
     } camera;
 
     ObjectList objects;
 };
 
 class Scene final : public Wallpaper, public SceneData {
-  public:
-    explicit Scene (WallpaperData data, SceneData sceneData) noexcept : Wallpaper (std::move (data)), SceneData (std::move (sceneData)) {}
+public:
+    explicit Scene (WallpaperData data, SceneData sceneData) noexcept :
+	Wallpaper (std::move (data)), SceneData (std::move (sceneData)) { }
 
     ~Scene () override = default;
 };

+ 54 - 44
src/WallpaperEngine/Data/Parsers/EffectParser.cpp

@@ -19,88 +19,98 @@ EffectUniquePtr EffectParser::parse (const JSON& it, const Project& project) {
     const auto dependencies = it.optional ("dependencies");
     const auto fbos = it.optional ("fbos");
 
-    return std::make_unique <Effect> (Effect {
-        .name = it.optional <std::string> ("name", ""),
-        .description = it.optional <std::string> ("description", ""),
-        .group = it.optional <std::string> ("group", ""),
-        .preview = it.optional <std::string> ("preview", ""),
-        .dependencies = dependencies.has_value () ? parseDependencies (*dependencies) : std::vector <std::string> {},
-        .passes = parseEffectPasses (it.require ("passes", "Effect file must have passes"), project),
-        .fbos = fbos.has_value () ? parseFBOs (*fbos) : std::vector <FBOUniquePtr> {},
+    return std::make_unique<Effect> (Effect {
+	.name = it.optional<std::string> ("name", ""),
+	.description = it.optional<std::string> ("description", ""),
+	.group = it.optional<std::string> ("group", ""),
+	.preview = it.optional<std::string> ("preview", ""),
+	.dependencies = dependencies.has_value () ? parseDependencies (*dependencies) : std::vector<std::string> {},
+	.passes = parseEffectPasses (it.require ("passes", "Effect file must have passes"), project),
+	.fbos = fbos.has_value () ? parseFBOs (*fbos) : std::vector<FBOUniquePtr> {},
     });
 }
 
-std::vector <std::string> EffectParser::parseDependencies (const JSON& it) {
-    std::vector <std::string> result = {};
+std::vector<std::string> EffectParser::parseDependencies (const JSON& it) {
+    std::vector<std::string> result = {};
 
     if (!it.is_array ()) {
-        return result;
+	return result;
     }
 
     for (const auto& cur : it) {
-        result.push_back (cur);
+	result.push_back (cur);
     }
 
     return result;
 }
 
-std::vector <EffectPassUniquePtr> EffectParser::parseEffectPasses (const JSON& it, const Project& project) {
-    std::vector <EffectPassUniquePtr> result = {};
+std::vector<EffectPassUniquePtr> EffectParser::parseEffectPasses (const JSON& it, const Project& project) {
+    std::vector<EffectPassUniquePtr> result = {};
 
     if (!it.is_array ()) {
-        return result;
+	return result;
     }
 
     for (const auto& cur : it) {
-        const auto binds = cur.optional ("bind");
-        const auto command = cur.optional ("command");
-        const auto material = cur.optional ("material");
-
-        // TODO: CAN TARGET BE SET IF MATERIAL IS SET?
-
-        result.push_back (std::make_unique <EffectPass> (EffectPass {
-            .material = material.has_value () ? MaterialParser::load (project, *material) : std::optional<MaterialUniquePtr> {},
-            .binds = binds.has_value () ? parseBinds (binds.value ()) : std::map<int, std::string> {},
-            .command = command.has_value () ? (command.value () == "copy" ? Command_Copy : Command_Swap) : std::optional<PassCommandType> {},
-            .source = command.has_value () ? cur.require <std::string> ("source", "Effect command must have a source") : cur.optional <std::string> ("source"),
-            .target = command.has_value () ? cur.require <std::string> ("target", "Effect command must have a target") : cur.optional <std::string> ("target"),
-        }));
+	const auto binds = cur.optional ("bind");
+	const auto command = cur.optional ("command");
+	const auto material = cur.optional ("material");
+
+	// TODO: CAN TARGET BE SET IF MATERIAL IS SET?
+
+	result.push_back (
+	    std::make_unique<EffectPass> (EffectPass {
+		.material = material.has_value () ? MaterialParser::load (project, *material)
+						  : std::optional<MaterialUniquePtr> {},
+		.binds = binds.has_value () ? parseBinds (binds.value ()) : std::map<int, std::string> {},
+		.command = command.has_value () ? (command.value () == "copy" ? Command_Copy : Command_Swap)
+						: std::optional<PassCommandType> {},
+		.source = command.has_value ()
+		    ? cur.require<std::string> ("source", "Effect command must have a source")
+		    : cur.optional<std::string> ("source"),
+		.target = command.has_value ()
+		    ? cur.require<std::string> ("target", "Effect command must have a target")
+		    : cur.optional<std::string> ("target"),
+	    })
+	);
     }
 
     return result;
 }
 
-std::map <int, std::string> EffectParser::parseBinds (const JSON& it) {
-    std::map <int, std::string> result = {};
+std::map<int, std::string> EffectParser::parseBinds (const JSON& it) {
+    std::map<int, std::string> result = {};
 
     if (!it.is_array ()) {
-        return result;
+	return result;
     }
 
     for (const auto& cur : it) {
-        result.emplace (
-            cur.require ("index", "Texture binds must have an index"),
-            cur.require ("name", "Texture bind must name the FBO that should be used")
-        );
+	result.emplace (
+	    cur.require ("index", "Texture binds must have an index"),
+	    cur.require ("name", "Texture bind must name the FBO that should be used")
+	);
     }
 
     return result;
 }
 
-std::vector <FBOUniquePtr> EffectParser::parseFBOs (const JSON& it) {
-    std::vector <FBOUniquePtr> result = {};
+std::vector<FBOUniquePtr> EffectParser::parseFBOs (const JSON& it) {
+    std::vector<FBOUniquePtr> result = {};
 
     if (!it.is_array ()) {
-        return result;
+	return result;
     }
 
     for (const auto& cur : it) {
-        result.push_back(std::make_unique<FBO>(FBO {
-            .name = cur.require <std::string> ("name", "FBO must have a name"),
-            .format = cur.optional <std::string> ("format", "rgba8888"),
-            .scale = cur.optional ("scale", 1.0f),
-            .unique = cur.optional ("unique", false),
-        }));
+	result.push_back (
+	    std::make_unique<FBO> (FBO {
+		.name = cur.require<std::string> ("name", "FBO must have a name"),
+		.format = cur.optional<std::string> ("format", "rgba8888"),
+		.scale = cur.optional ("scale", 1.0f),
+		.unique = cur.optional ("unique", false),
+	    })
+	);
     }
 
     return result;

+ 6 - 6
src/WallpaperEngine/Data/Parsers/EffectParser.h

@@ -8,14 +8,14 @@ using JSON = WallpaperEngine::Data::JSON::JSON;
 using namespace WallpaperEngine::Data::Model;
 
 class EffectParser {
-  public:
+public:
     static EffectUniquePtr load (const Project& project, const std::string& filename);
 
-  private:
+private:
     static EffectUniquePtr parse (const JSON& it, const Project& project);
-    static std::vector <std::string> parseDependencies (const JSON& it);
-    static std::vector <EffectPassUniquePtr> parseEffectPasses (const JSON& it, const Project& project);
-    static std::map <int, std::string> parseBinds (const JSON& it);
-    static std::vector <FBOUniquePtr> parseFBOs (const JSON& it);
+    static std::vector<std::string> parseDependencies (const JSON& it);
+    static std::vector<EffectPassUniquePtr> parseEffectPasses (const JSON& it, const Project& project);
+    static std::map<int, std::string> parseBinds (const JSON& it);
+    static std::vector<FBOUniquePtr> parseFBOs (const JSON& it);
 };
 } // namespace WallpaperEngine::Data::Parsers

+ 44 - 44
src/WallpaperEngine/Data/Parsers/MaterialParser.cpp

@@ -15,21 +15,21 @@ MaterialUniquePtr MaterialParser::load (const Project& project, const std::strin
 }
 
 MaterialUniquePtr MaterialParser::parse (const JSON& it, const std::string& filename, const Project& project) {
-    return std::make_unique <Material> (Material {
-        .filename = filename,
-        .passes = parsePasses (it.require ("passes", "Material must have passes to render"), project),
+    return std::make_unique<Material> (Material {
+	.filename = filename,
+	.passes = parsePasses (it.require ("passes", "Material must have passes to render"), project),
     });
 }
 
-std::vector <MaterialPassUniquePtr> MaterialParser::parsePasses (const JSON& it, const Project& project) {
-    std::vector <MaterialPassUniquePtr> result = {};
+std::vector<MaterialPassUniquePtr> MaterialParser::parsePasses (const JSON& it, const Project& project) {
+    std::vector<MaterialPassUniquePtr> result = {};
 
     if (!it.is_array ()) {
-        return result;
+	return result;
     }
 
     for (const auto& cur : it) {
-        result.push_back (parsePass (cur, project));
+	result.push_back (parsePass (cur, project));
     }
 
     return result;
@@ -41,54 +41,54 @@ MaterialPassUniquePtr MaterialParser::parsePass (const JSON& it, const Project&
     const auto combos = it.optional ("combos");
     const auto constants = it.optional ("constantshadervalues");
 
-    return std::make_unique <MaterialPass>(MaterialPass {
-        //TODO: REMOVE THIS UGLY STD::STRING CREATION
-        .blending = parseBlendMode (it.optional ("blending", std::string ("normal"))),
-        .cullmode = parseCullMode (it.optional ("cullmode", std::string ("nocull"))),
-        .depthtest = parseDepthtestMode (it.optional ("depthtest", std::string ("disabled"))),
-        .depthwrite = parseDepthwriteMode (it.optional ("depthwrite", std::string ("disabled"))),
-        .shader = it.require <std::string> ("shader", "Material pass must have a shader"),
-        .textures = textures.has_value () ? parseTextures (*textures) : TextureMap {},
-        .usertextures = usertextures.has_value () ? parseTextures (*usertextures) : TextureMap {},
-        .combos = combos.has_value () ? parseCombos (*combos) : ComboMap {},
-        .constants = constants.has_value () ? ShaderConstantParser::parse (*constants, project) : ShaderConstantMap {},
+    return std::make_unique<MaterialPass> (MaterialPass {
+	// TODO: REMOVE THIS UGLY STD::STRING CREATION
+	.blending = parseBlendMode (it.optional ("blending", std::string ("normal"))),
+	.cullmode = parseCullMode (it.optional ("cullmode", std::string ("nocull"))),
+	.depthtest = parseDepthtestMode (it.optional ("depthtest", std::string ("disabled"))),
+	.depthwrite = parseDepthwriteMode (it.optional ("depthwrite", std::string ("disabled"))),
+	.shader = it.require<std::string> ("shader", "Material pass must have a shader"),
+	.textures = textures.has_value () ? parseTextures (*textures) : TextureMap {},
+	.usertextures = usertextures.has_value () ? parseTextures (*usertextures) : TextureMap {},
+	.combos = combos.has_value () ? parseCombos (*combos) : ComboMap {},
+	.constants = constants.has_value () ? ShaderConstantParser::parse (*constants, project) : ShaderConstantMap {},
     });
 }
 
-std::map <int, std::string> MaterialParser::parseTextures (const JSON& it) {
-    std::map <int, std::string> result = {};
+std::map<int, std::string> MaterialParser::parseTextures (const JSON& it) {
+    std::map<int, std::string> result = {};
 
     if (!it.is_array ()) {
-        return result;
+	return result;
     }
 
     int index = 0;
 
     for (const auto& cur : it) {
-        if (!cur.is_null ()) {
-            if (!cur.is_string ()) {
-                sLog.error ("Detected a non-string texture, most likely a special value: ", cur.dump ());
-                result.emplace (index, "");
-            } else {
-                result.emplace (index, cur);
-            }
-        }
-
-        index++;
+	if (!cur.is_null ()) {
+	    if (!cur.is_string ()) {
+		sLog.error ("Detected a non-string texture, most likely a special value: ", cur.dump ());
+		result.emplace (index, "");
+	    } else {
+		result.emplace (index, cur);
+	    }
+	}
+
+	index++;
     }
 
     return result;
 }
 
-std::map <std::string, int> MaterialParser::parseCombos (const JSON& it) {
-    std::map <std::string, int> result = {};
+std::map<std::string, int> MaterialParser::parseCombos (const JSON& it) {
+    std::map<std::string, int> result = {};
 
     if (!it.is_object ()) {
-        return result;
+	return result;
     }
 
     for (const auto& cur : it.items ()) {
-        result.emplace (cur.key (), cur.value ());
+	result.emplace (cur.key (), cur.value ());
     }
 
     return result;
@@ -96,15 +96,15 @@ std::map <std::string, int> MaterialParser::parseCombos (const JSON& it) {
 
 BlendingMode MaterialParser::parseBlendMode (const std::string& mode) {
     if (mode == "normal") {
-        return BlendingMode_Normal;
+	return BlendingMode_Normal;
     }
 
     if (mode == "additive") {
-        return BlendingMode_Additive;
+	return BlendingMode_Additive;
     }
 
     if (mode == "translucent") {
-        return BlendingMode_Translucent;
+	return BlendingMode_Translucent;
     }
 
     sLog.error ("Unknown blending mode: ", mode, " defaulting to normal");
@@ -113,11 +113,11 @@ BlendingMode MaterialParser::parseBlendMode (const std::string& mode) {
 
 CullingMode MaterialParser::parseCullMode (const std::string& mode) {
     if (mode == "nocull") {
-        return CullingMode_Disable;
+	return CullingMode_Disable;
     }
 
     if (mode == "normal") {
-        return CullingMode_Normal;
+	return CullingMode_Normal;
     }
 
     sLog.error ("Unknown culling mode: ", mode, " defaulting to nocull");
@@ -126,11 +126,11 @@ CullingMode MaterialParser::parseCullMode (const std::string& mode) {
 
 DepthtestMode MaterialParser::parseDepthtestMode (const std::string& mode) {
     if (mode == "disabled") {
-        return DepthtestMode_Disabled;
+	return DepthtestMode_Disabled;
     }
 
     if (mode == "enabled") {
-        return DepthtestMode_Enabled;
+	return DepthtestMode_Enabled;
     }
 
     sLog.error ("Unknown depthtest mode: ", mode, " defaulting to disabled");
@@ -139,11 +139,11 @@ DepthtestMode MaterialParser::parseDepthtestMode (const std::string& mode) {
 
 DepthwriteMode MaterialParser::parseDepthwriteMode (const std::string& mode) {
     if (mode == "disabled") {
-        return DepthwriteMode_Disabled;
+	return DepthwriteMode_Disabled;
     }
 
     if (mode == "enabled") {
-        return DepthwriteMode_Enabled;
+	return DepthwriteMode_Enabled;
     }
 
     sLog.error ("Unknown depthwrite mode: ", mode, " defaulting to disabled");

+ 4 - 4
src/WallpaperEngine/Data/Parsers/MaterialParser.h

@@ -9,13 +9,13 @@ using JSON = WallpaperEngine::Data::JSON::JSON;
 using namespace WallpaperEngine::Data::Model;
 
 class MaterialParser {
-  public:
+public:
     static MaterialUniquePtr load (const Project& project, const std::string& filename);
     static MaterialUniquePtr parse (const JSON& it, const std::string& filename, const Project& project);
-    static std::vector <MaterialPassUniquePtr> parsePasses (const JSON& it, const Project& project);
+    static std::vector<MaterialPassUniquePtr> parsePasses (const JSON& it, const Project& project);
     static MaterialPassUniquePtr parsePass (const JSON& it, const Project& project);
-    static std::map <int, std::string> parseTextures (const JSON& it);
-    static std::map <std::string, int> parseCombos (const JSON& it);
+    static std::map<int, std::string> parseTextures (const JSON& it);
+    static std::map<std::string, int> parseCombos (const JSON& it);
     static BlendingMode parseBlendMode (const std::string& mode);
     static CullingMode parseCullMode (const std::string& mode);
     static DepthtestMode parseDepthtestMode (const std::string& mode);

+ 12 - 12
src/WallpaperEngine/Data/Parsers/ModelParser.cpp

@@ -16,18 +16,18 @@ ModelUniquePtr ModelParser::load (const Project& project, const std::string& fil
 }
 
 ModelUniquePtr ModelParser::parse (const JSON& file, const Project& project, const std::string& filename) {
-    const auto material = file.require <std::string> ("material", "Model must have a material");
+    const auto material = file.require<std::string> ("material", "Model must have a material");
 
-    return std::make_unique <ModelStruct> (ModelStruct {
-        .filename = filename,
-        .material = MaterialParser::load (project, material),
-        .solidlayer = file.optional ("solidlayer", false),
-        .fullscreen = file.optional ("fullscreen", false),
-        .passthrough = file.optional ("passthrough", false),
-        .autosize = file.optional ("autosize", false),
-        .nopadding = file.optional ("nopadding", false),
-        .width = file.optional <int> ("width"),
-        .height = file.optional <int> ("height"),
-        .puppet = file.optional <std::string> ("puppet"),
+    return std::make_unique<ModelStruct> (ModelStruct {
+	.filename = filename,
+	.material = MaterialParser::load (project, material),
+	.solidlayer = file.optional ("solidlayer", false),
+	.fullscreen = file.optional ("fullscreen", false),
+	.passthrough = file.optional ("passthrough", false),
+	.autosize = file.optional ("autosize", false),
+	.nopadding = file.optional ("nopadding", false),
+	.width = file.optional<int> ("width"),
+	.height = file.optional<int> ("height"),
+	.puppet = file.optional<std::string> ("puppet"),
     });
 }

+ 1 - 1
src/WallpaperEngine/Data/Parsers/ModelParser.h

@@ -8,7 +8,7 @@ using JSON = WallpaperEngine::Data::JSON::JSON;
 using namespace WallpaperEngine::Data::Model;
 
 class ModelParser {
-  public:
+public:
     static ModelUniquePtr load (const Project& project, const std::string& filename);
     static ModelUniquePtr parse (const JSON& file, const Project& project, const std::string& filename);
 };

Файловите разлики са ограничени, защото са твърде много
+ 446 - 447
src/WallpaperEngine/Data/Parsers/ObjectParser.cpp


+ 8 - 6
src/WallpaperEngine/Data/Parsers/ObjectParser.h

@@ -14,21 +14,23 @@ using JSON = WallpaperEngine::Data::JSON::JSON;
 using namespace WallpaperEngine::Data::Model;
 
 class ObjectParser {
-  public:
+public:
     static ObjectUniquePtr parse (const JSON& it, const Project& project);
 
-  private:
+private:
     static std::vector<int> parseDependencies (const JSON& it);
     static SoundUniquePtr parseSound (const JSON& it, ObjectData base);
-    static ImageUniquePtr parseImage (const JSON& it, const Project& project, ObjectData base, const std::string& image);
+    static ImageUniquePtr
+    parseImage (const JSON& it, const Project& project, ObjectData base, const std::string& image);
     static ParticleUniquePtr parseParticle (const JSON& it, const Project& project, ObjectData base);
-    static std::vector <ImageEffectUniquePtr> parseEffects (const JSON& it, const Project& project);
+    static std::vector<ImageEffectUniquePtr> parseEffects (const JSON& it, const Project& project);
     static ImageEffectUniquePtr parseEffect (const JSON& it, const Project& project);
-    static std::vector <ImageEffectPassOverrideUniquePtr> parseEffectPassOverrides (const JSON& it, const Project& project);
+    static std::vector<ImageEffectPassOverrideUniquePtr>
+    parseEffectPassOverrides (const JSON& it, const Project& project);
     static ImageEffectPassOverrideUniquePtr parseEffectPass (const JSON& it, const Project& project);
     static TextureMap parseTextureMap (const JSON& it);
     static ComboMap parseComboMap (const JSON& it);
-    static std::vector <ImageAnimationLayerUniquePtr> parseAnimationLayers (const JSON& it, const Project& project);
+    static std::vector<ImageAnimationLayerUniquePtr> parseAnimationLayers (const JSON& it, const Project& project);
     static ImageAnimationLayerUniquePtr parseAnimationLayer (const JSON& it, const Project& project);
 
     // Particle parsing helpers

+ 8 - 10
src/WallpaperEngine/Data/Parsers/PackageParser.cpp

@@ -13,14 +13,14 @@ using namespace WallpaperEngine::Data::Assets;
 using namespace WallpaperEngine::Data::Utils;
 
 PackageUniquePtr PackageParser::parse (ReadStreamSharedPtr stream) {
-    auto reader = std::make_unique <BinaryReader> (std::move (stream));
+    auto reader = std::make_unique<BinaryReader> (std::move (stream));
 
     if (const std::string header = reader->nextSizedString (); header.starts_with ("PKGV") == false) {
-        sLog.exception ("Expected header to start with PKGV, got ", header);
+	sLog.exception ("Expected header to start with PKGV, got ", header);
     }
 
-    auto result =  std::make_unique <Package> (Package {
-        .file = std::move(reader),
+    auto result = std::make_unique<Package> (Package {
+	.file = std::move (reader),
     });
 
     result->files = parseFileList (*result->file);
@@ -36,13 +36,11 @@ FileEntryList PackageParser::parseFileList (const BinaryReader& stream) {
     result.reserve (filesCount);
 
     for (uint32_t i = 0; i < filesCount; i++) {
-        result.push_back (std::make_unique<FileEntry> (FileEntry {
-            .filename = stream.nextSizedString (),
-            .offset = stream.nextUInt32 (),
-            .length = stream.nextUInt32 ()
-        }));
+	result.push_back (
+	    std::make_unique<FileEntry> (FileEntry {
+		.filename = stream.nextSizedString (), .offset = stream.nextUInt32 (), .length = stream.nextUInt32 () })
+	);
     }
 
     return result;
 }
-

+ 1 - 1
src/WallpaperEngine/Data/Parsers/PackageParser.h

@@ -1,8 +1,8 @@
 #pragma once
 
-#include <iosfwd>
 #include "WallpaperEngine/Data/Assets/Types.h"
 #include "WallpaperEngine/Data/Utils/BinaryReader.h"
+#include <iosfwd>
 
 namespace WallpaperEngine::Data::Parsers {
 using namespace WallpaperEngine::Data::Assets;

+ 27 - 27
src/WallpaperEngine/Data/Parsers/ProjectParser.cpp

@@ -17,28 +17,28 @@ ProjectUniquePtr ProjectParser::parse (const JSON& data, AssetLocatorUniquePtr c
     const auto general = data.optional ("general");
     const auto workshopId = data.optional ("workshopid");
     auto actualWorkshopId = std::to_string (--backgroundId);
-    auto type = data.require <std::string> ("type", "Project type missing");
+    auto type = data.require<std::string> ("type", "Project type missing");
 
     if (workshopId.has_value ()) {
-        if (workshopId->is_number ()) {
-            actualWorkshopId = std::to_string (workshopId->get <int> ());
-        } else if (workshopId->is_string ()) {
-            actualWorkshopId = workshopId->get <std::string> ();
-        } else {
-            sLog.error ("Invalid workshop id: ", workshopId->dump ());
-        }
+	if (workshopId->is_number ()) {
+	    actualWorkshopId = std::to_string (workshopId->get<int> ());
+	} else if (workshopId->is_string ()) {
+	    actualWorkshopId = workshopId->get<std::string> ();
+	} else {
+	    sLog.error ("Invalid workshop id: ", workshopId->dump ());
+	}
     }
 
     // lowercase for consistency
     std::ranges::transform (type, type.begin (), tolower);
 
-    auto result = std::make_unique <Project> (Project {
-        .title = data.require <std::string> ("title", "Project title missing"),
-        .type = parseType (type),
-        .workshopId = actualWorkshopId,
-        .supportsAudioProcessing = general.has_value () && general.value ().optional ("supportsaudioprocessing", false),
-        .properties = parseProperties (general),
-        .assetLocator = std::move(container),
+    auto result = std::make_unique<Project> (Project {
+	.title = data.require<std::string> ("title", "Project title missing"),
+	.type = parseType (type),
+	.workshopId = actualWorkshopId,
+	.supportsAudioProcessing = general.has_value () && general.value ().optional ("supportsaudioprocessing", false),
+	.properties = parseProperties (general),
+	.assetLocator = std::move (container),
     });
 
     result->wallpaper = WallpaperParser::parse (data.require ("file", "Project's main file missing"), *result);
@@ -48,42 +48,42 @@ ProjectUniquePtr ProjectParser::parse (const JSON& data, AssetLocatorUniquePtr c
 
 Project::Type ProjectParser::parseType (const std::string& type) {
     if (type == "scene") {
-        return Project::Type_Scene;
+	return Project::Type_Scene;
     }
 
     if (type == "video") {
-        return Project::Type_Video;
+	return Project::Type_Video;
     }
 
     if (type == "web") {
-        return Project::Type_Web;
+	return Project::Type_Web;
     }
 
     sLog.exception ("Unsupported project type ", type);
 }
 
-Properties ProjectParser::parseProperties (const std::optional <JSON>& data) {
+Properties ProjectParser::parseProperties (const std::optional<JSON>& data) {
     if (!data.has_value ()) {
-        return {};
+	return {};
     }
 
     const auto properties = data.value ().optional ("properties");
 
     if (!properties.has_value ()) {
-        return {};
+	return {};
     }
 
     Properties result = {};
 
     for (const auto& cur : properties.value ().items ()) {
-        const auto& property = PropertyParser::parse (cur.value (), cur.key ());
+	const auto& property = PropertyParser::parse (cur.value (), cur.key ());
 
-        // ignore properties that failed, these are generally groups
-        if (property == nullptr) {
-            continue;
-        }
+	// ignore properties that failed, these are generally groups
+	if (property == nullptr) {
+	    continue;
+	}
 
-        result.emplace (cur.key (), property);
+	result.emplace (cur.key (), property);
     }
 
     return result;

+ 4 - 4
src/WallpaperEngine/Data/Parsers/ProjectParser.h

@@ -2,9 +2,9 @@
 
 #include <nlohmann/json.hpp>
 
+#include "WallpaperEngine/Assets/AssetLocator.h"
 #include "WallpaperEngine/Data/JSON.h"
 #include "WallpaperEngine/Data/Model/Project.h"
-#include "WallpaperEngine/Assets/AssetLocator.h"
 
 namespace WallpaperEngine::Data::Parsers {
 using JSON = WallpaperEngine::Data::JSON::JSON;
@@ -16,11 +16,11 @@ using namespace WallpaperEngine::Data::Model;
  * Parses a project file and returns an object representing it
  */
 class ProjectParser {
-  public:
+public:
     static ProjectUniquePtr parse (const JSON& data, AssetLocatorUniquePtr container);
 
-  private:
+private:
     static Project::Type parseType (const std::string& type);
-    static Properties parseProperties (const std::optional <JSON>& data);
+    static Properties parseProperties (const std::optional<JSON>& data);
 };
 } // namespace WallpaperEngine::Data::Parsers

+ 79 - 59
src/WallpaperEngine/Data/Parsers/PropertyParser.cpp

@@ -9,121 +9,141 @@ PropertySharedPtr PropertyParser::parse (const JSON& it, const std::string& name
     const auto type = it.optional ("type");
 
     if (type == "color") {
-        return parseColor (it, name);
+	return parseColor (it, name);
     }
     if (type == "bool") {
-        return parseBoolean (it, name);
+	return parseBoolean (it, name);
     }
     if (type == "slider") {
-        return parseSlider (it, name);
+	return parseSlider (it, name);
     }
     if (type == "combo") {
-        return parseCombo (it, name);
+	return parseCombo (it, name);
     }
     if (type == "text") {
-        return parseText (it, name);
+	return parseText (it, name);
     }
     if (type == "scenetexture") {
-        return parseSceneTexture (it, name);
+	return parseSceneTexture (it, name);
     }
     if (type == "file") {
-        return parseFile (it, name);
+	return parseFile (it, name);
     }
     if (type == "textinput") {
-        return parseTextInput (it, name);
+	return parseTextInput (it, name);
     }
 
     if (type.has_value () && type != "group") {
-        // show the error and ignore this property
-        sLog.error ("Unexpected type for property: ", type);
-        sLog.error (it.dump ());
+	// show the error and ignore this property
+	sLog.error ("Unexpected type for property: ", type);
+	sLog.error (it.dump ());
     }
 
     return nullptr;
 }
 
-
 PropertySharedPtr PropertyParser::parseCombo (const JSON& it, const std::string& name) {
-    std::map <std::string, std::string> optionsMap = {};
+    std::map<std::string, std::string> optionsMap = {};
 
     const auto options = it.require ("options", "Combo property must have options");
 
     if (!options.is_array ()) {
-        sLog.exception ("Property combo options should be an array");
+	sLog.exception ("Property combo options should be an array");
     }
 
     for (auto& cur : options) {
-        if (!cur.is_object ()) {
-            continue;
-        }
+	if (!cur.is_object ()) {
+	    continue;
+	}
 
-        const auto value = cur.require ("value", "Combo option must have a value");
+	const auto value = cur.require ("value", "Combo option must have a value");
 
-        optionsMap.emplace (
-            value.is_number () ? std::to_string (value.get <int> ()) : value.get <std::string> (),
-            cur.require ("label", "Combo option must have a label")
-        );
+	optionsMap.emplace (
+	    value.is_number () ? std::to_string (value.get<int> ()) : value.get<std::string> (),
+	    cur.require ("label", "Combo option must have a label")
+	);
     }
 
     const auto value = it.require ("value", "Combo property must have a value");
 
-    return std::make_shared <PropertyCombo> (PropertyData {
-        .name = name,
-        .text = it.optional <std::string> ("text", ""),
-    }, ComboData {
-        .values = optionsMap
-    }, value.is_number () ? std::to_string (value.get <int> ()) : value.get <std::string> ());
+    return std::make_shared<PropertyCombo> (
+	PropertyData {
+	    .name = name,
+	    .text = it.optional<std::string> ("text", ""),
+	},
+	ComboData { .values = optionsMap },
+	value.is_number () ? std::to_string (value.get<int> ()) : value.get<std::string> ()
+    );
 }
 
 PropertySharedPtr PropertyParser::parseColor (const JSON& it, const std::string& name) {
-    return std::make_shared <PropertyColor> (PropertyData {
-        .name = name,
-        .text = it.optional <std::string> ("text", ""),
-    }, it.require ("value", "Property must have a value"));
+    return std::make_shared<PropertyColor> (
+	PropertyData {
+	    .name = name,
+	    .text = it.optional<std::string> ("text", ""),
+	},
+	it.require ("value", "Property must have a value")
+    );
 }
 
 PropertySharedPtr PropertyParser::parseBoolean (const JSON& it, const std::string& name) {
-    return std::make_shared <PropertyBoolean> (PropertyData {
-        .name = name,
-        .text = it.optional <std::string> ("text", ""),
-    }, it.require ("value", "Property must have a value"));
+    return std::make_shared<PropertyBoolean> (
+	PropertyData {
+	    .name = name,
+	    .text = it.optional<std::string> ("text", ""),
+	},
+	it.require ("value", "Property must have a value")
+    );
 }
 
 PropertySharedPtr PropertyParser::parseSlider (const JSON& it, const std::string& name) {
-    return std::make_shared <PropertySlider> (PropertyData {
-        .name = name,
-        .text = it.optional <std::string> ("text", ""),
-    }, SliderData {
-        .min = it.optional ("min", 0.0f),
-        .max = it.optional ("max", 0.0f),
-        .step = it.optional ("step", 0.0f),
-    }, it.require ("value", "Property must have a value"));
+    return std::make_shared<PropertySlider> (
+	PropertyData {
+	    .name = name,
+	    .text = it.optional<std::string> ("text", ""),
+	},
+	SliderData {
+	    .min = it.optional ("min", 0.0f),
+	    .max = it.optional ("max", 0.0f),
+	    .step = it.optional ("step", 0.0f),
+	},
+	it.require ("value", "Property must have a value")
+    );
 }
 
 PropertySharedPtr PropertyParser::parseText (const JSON& it, const std::string& name) {
-    return std::make_shared <PropertyText> (PropertyData {
-        .name = name,
-        .text = it.optional <std::string> ("text", ""),
+    return std::make_shared<PropertyText> (PropertyData {
+	.name = name,
+	.text = it.optional<std::string> ("text", ""),
     });
 }
 
 PropertySharedPtr PropertyParser::parseSceneTexture (const JSON& it, const std::string& name) {
-    return std::make_shared <PropertySceneTexture> (PropertyData {
-        .name = name,
-        .text = it.optional <std::string> ("text", ""),
-    }, it.require ("value", "Property must have a value"));
+    return std::make_shared<PropertySceneTexture> (
+	PropertyData {
+	    .name = name,
+	    .text = it.optional<std::string> ("text", ""),
+	},
+	it.require ("value", "Property must have a value")
+    );
 }
 
 PropertySharedPtr PropertyParser::parseFile (const JSON& it, const std::string& name) {
-    return std::make_shared <PropertyFile> (PropertyData {
-        .name = name,
-        .text = it.optional <std::string> ("text", ""),
-    }, it.optional <std::string> ("value", ""));
+    return std::make_shared<PropertyFile> (
+	PropertyData {
+	    .name = name,
+	    .text = it.optional<std::string> ("text", ""),
+	},
+	it.optional<std::string> ("value", "")
+    );
 }
 
 PropertySharedPtr PropertyParser::parseTextInput (const JSON& it, const std::string& name) {
-    return std::make_shared <PropertyTextInput> (PropertyData {
-        .name = name,
-        .text = it.optional <std::string> ("text", ""),
-    }, it.require ("value", "Property must have a value").dump ());
+    return std::make_shared<PropertyTextInput> (
+	PropertyData {
+	    .name = name,
+	    .text = it.optional<std::string> ("text", ""),
+	},
+	it.require ("value", "Property must have a value").dump ()
+    );
 }

+ 2 - 2
src/WallpaperEngine/Data/Parsers/PropertyParser.h

@@ -7,10 +7,10 @@ using JSON = WallpaperEngine::Data::JSON::JSON;
 using namespace WallpaperEngine::Data::Model;
 
 class PropertyParser {
-  public:
+public:
     static PropertySharedPtr parse (const JSON& it, const std::string& name);
 
-  private:
+private:
     static PropertySharedPtr parseCombo (const JSON& it, const std::string& name);
     static PropertySharedPtr parseColor (const JSON& it, const std::string& name);
     static PropertySharedPtr parseBoolean (const JSON& it, const std::string& name);

+ 3 - 3
src/WallpaperEngine/Data/Parsers/ShaderConstantParser.cpp

@@ -1,20 +1,20 @@
 #include "ShaderConstantParser.h"
 
-#include "WallpaperEngine/Data/Parsers/UserSettingParser.h"
 #include "WallpaperEngine/Data/Model/Project.h"
+#include "WallpaperEngine/Data/Parsers/UserSettingParser.h"
 
 using namespace WallpaperEngine::Data::Parsers;
 using namespace WallpaperEngine::Data::Model;
 
 ShaderConstantMap ShaderConstantParser::parse (const JSON& it, const Project& project) {
     if (!it.is_object ()) {
-        return {};
+	return {};
     }
 
     ShaderConstantMap result = {};
 
     for (const auto& cur : it.items ()) {
-        result.emplace (cur.key(), UserSettingParser::parse (cur.value(), project.properties));
+	result.emplace (cur.key (), UserSettingParser::parse (cur.value (), project.properties));
     }
 
     return result;

+ 1 - 1
src/WallpaperEngine/Data/Parsers/ShaderConstantParser.h

@@ -8,7 +8,7 @@ using JSON = WallpaperEngine::Data::JSON::JSON;
 using namespace WallpaperEngine::Data::Model;
 
 class ShaderConstantParser {
-  public:
+public:
     static ShaderConstantMap parse (const JSON& it, const Project& project);
 };
 } // namespace WallpaperEngine::Data::Parsers

+ 186 - 181
src/WallpaperEngine/Data/Parsers/TextureParser.cpp

@@ -1,5 +1,5 @@
-#include <cstring>
 #include <cmath>
+#include <cstring>
 
 #include <lz4.h>
 #include <nlohmann/json.hpp>
@@ -18,18 +18,18 @@ TextureUniquePtr TextureParser::parse (const BinaryReader& file) {
     parseContainer (*result, file);
 
     for (uint32_t image = 0; image < result->imageCount; image++) {
-        const uint32_t mipmapCount = file.nextUInt32 ();
-        MipmapList mipmaps;
+	const uint32_t mipmapCount = file.nextUInt32 ();
+	MipmapList mipmaps;
 
-        for (uint32_t mipmap = 0; mipmap < mipmapCount; mipmap++) {
-            mipmaps.emplace_back (parseMipmap (file, *result));
-        }
+	for (uint32_t mipmap = 0; mipmap < mipmapCount; mipmap++) {
+	    mipmaps.emplace_back (parseMipmap (file, *result));
+	}
 
-        result->images.emplace (image, mipmaps);
+	result->images.emplace (image, mipmaps);
     }
 
     if (!result->isAnimated ()) {
-        return result;
+	return result;
     }
 
     parseAnimations (*result, file);
@@ -42,51 +42,51 @@ MipmapSharedPtr TextureParser::parseMipmap (const BinaryReader& file, const Text
 
     // TEXB0004 has some extra data in the header that has to be handled
     if (header.containerVersion == ContainerVersion_TEXB0004) {
-        // some integers that we can ignore as they only seem to affect
-        // the editor
-        std::ignore = file.nextUInt32 ();
-        std::ignore = file.nextUInt32 ();
-        // this format includes some json in the header that we might need
-        // to parse at some point...
-        result->json = file.nextNullTerminatedString ();
-        // last ignorable integer
-        std::ignore = file.nextUInt32 ();
+	// some integers that we can ignore as they only seem to affect
+	// the editor
+	std::ignore = file.nextUInt32 ();
+	std::ignore = file.nextUInt32 ();
+	// this format includes some json in the header that we might need
+	// to parse at some point...
+	result->json = file.nextNullTerminatedString ();
+	// last ignorable integer
+	std::ignore = file.nextUInt32 ();
     }
 
     result->width = file.nextUInt32 ();
     result->height = file.nextUInt32 ();
 
-    if (header.containerVersion == ContainerVersion_TEXB0004 ||
-        header.containerVersion == ContainerVersion_TEXB0003 ||
-        header.containerVersion == ContainerVersion_TEXB0002) {
-        result->compression = file.nextUInt32 ();
-        result->uncompressedSize = file.nextInt ();
+    if (header.containerVersion == ContainerVersion_TEXB0004 || header.containerVersion == ContainerVersion_TEXB0003
+	|| header.containerVersion == ContainerVersion_TEXB0002) {
+	result->compression = file.nextUInt32 ();
+	result->uncompressedSize = file.nextInt ();
     }
 
     result->compressedSize = file.nextInt ();
 
     if (result->compression == 0) {
-        // this might be better named as mipmap_bytes_size instead of compressedSize
-        // as in uncompressed files this variable actually holds the file length
-        result->uncompressedSize = result->compressedSize;
+	// this might be better named as mipmap_bytes_size instead of compressedSize
+	// as in uncompressed files this variable actually holds the file length
+	result->uncompressedSize = result->compressedSize;
     }
 
-    result->uncompressedData = std::unique_ptr<char[]> (new char [result->uncompressedSize]);
+    result->uncompressedData = std::unique_ptr<char[]> (new char[result->uncompressedSize]);
 
     if (result->compression == 1) {
-        result->compressedData = std::unique_ptr<char[]> (new char [result->compressedSize]);
-        // read the compressed data into the buffer
-        file.next (result->compressedData.get (), result->compressedSize);
-        // finally decompress it
-        int bytes = LZ4_decompress_safe (
-            result->compressedData.get (), result->uncompressedData.get (), result->compressedSize,
-            result->uncompressedSize
-        );
-
-        if (bytes < 0)
-            sLog.exception ("Cannot decompress texture data, LZ4_decompress_safe returned an error");
+	result->compressedData = std::unique_ptr<char[]> (new char[result->compressedSize]);
+	// read the compressed data into the buffer
+	file.next (result->compressedData.get (), result->compressedSize);
+	// finally decompress it
+	int bytes = LZ4_decompress_safe (
+	    result->compressedData.get (), result->uncompressedData.get (), result->compressedSize,
+	    result->uncompressedSize
+	);
+
+	if (bytes < 0) {
+	    sLog.exception ("Cannot decompress texture data, LZ4_decompress_safe returned an error");
+	}
     } else {
-        file.next (result->uncompressedData.get (), result->uncompressedSize);
+	file.next (result->uncompressedData.get (), result->uncompressedSize);
     }
 
     return result;
@@ -109,25 +109,25 @@ FrameSharedPtr TextureParser::parseFrame (const BinaryReader& file) {
 
 TextureFormat TextureParser::parseTextureFormat (uint32_t value) {
     switch (value) {
-        case TextureFormat_UNKNOWN:
-        case TextureFormat_ARGB8888:
-        case TextureFormat_RGB888:
-        case TextureFormat_RGB565:
-        case TextureFormat_DXT5:
-        case TextureFormat_DXT3:
-        case TextureFormat_DXT1:
-        case TextureFormat_RG88:
-        case TextureFormat_R8:
-        case TextureFormat_RG1616f:
-        case TextureFormat_R16f:
-        case TextureFormat_BC7:
-        case TextureFormat_RGBa1010102:
-        case TextureFormat_RGBA16161616f:
-        case TextureFormat_RGB161616f:
-            return static_cast<TextureFormat> (value);
-
-        default:
-            sLog.exception ("unknown texture format: ", value);
+	case TextureFormat_UNKNOWN:
+	case TextureFormat_ARGB8888:
+	case TextureFormat_RGB888:
+	case TextureFormat_RGB565:
+	case TextureFormat_DXT5:
+	case TextureFormat_DXT3:
+	case TextureFormat_DXT1:
+	case TextureFormat_RG88:
+	case TextureFormat_R8:
+	case TextureFormat_RG1616f:
+	case TextureFormat_R16f:
+	case TextureFormat_BC7:
+	case TextureFormat_RGBa1010102:
+	case TextureFormat_RGBA16161616f:
+	case TextureFormat_RGB161616f:
+	    return static_cast<TextureFormat> (value);
+
+	default:
+	    sLog.exception ("unknown texture format: ", value);
     }
 }
 
@@ -136,14 +136,15 @@ void TextureParser::parseTextureHeader (Texture& header, const BinaryReader& fil
 
     file.next (magic, 9);
 
-    if (strncmp (magic, "TEXV0005", 9) != 0)
-        sLog.exception ("unexpected texture container type: ", std::string_view (magic, 9));
+    if (strncmp (magic, "TEXV0005", 9) != 0) {
+	sLog.exception ("unexpected texture container type: ", std::string_view (magic, 9));
+    }
 
     file.next (magic, 9);
 
-    if (strncmp (magic, "TEXI0001", 9) != 0)
-        sLog.exception ("unexpected texture sub-container type: ", std::string_view (magic, 9));
-
+    if (strncmp (magic, "TEXI0001", 9) != 0) {
+	sLog.exception ("unexpected texture sub-container type: ", std::string_view (magic, 9));
+    }
 
     header.format = parseTextureFormat (file.nextUInt32 ());
     header.flags = parseTextureFlags (file.nextUInt32 ());
@@ -164,27 +165,27 @@ void TextureParser::parseContainer (Texture& header, const BinaryReader& file) {
     header.imageCount = file.nextUInt32 ();
 
     if (strncmp (magic, "TEXB0004", 9) == 0) {
-        header.containerVersion = ContainerVersion_TEXB0004;
-        header.freeImageFormat = parseFIF (file.nextUInt32 ());
-        header.isVideoMp4 = file.nextUInt32 () == 1;
-
-        if (header.freeImageFormat == FIF_UNKNOWN && header.isVideoMp4) {
-            header.freeImageFormat = FIF_MP4;
-        }
-
-        // default to TEXB0003 format here
-        if (header.freeImageFormat != FIF_MP4) {
-            header.containerVersion = ContainerVersion_TEXB0003;
-        }
+	header.containerVersion = ContainerVersion_TEXB0004;
+	header.freeImageFormat = parseFIF (file.nextUInt32 ());
+	header.isVideoMp4 = file.nextUInt32 () == 1;
+
+	if (header.freeImageFormat == FIF_UNKNOWN && header.isVideoMp4) {
+	    header.freeImageFormat = FIF_MP4;
+	}
+
+	// default to TEXB0003 format here
+	if (header.freeImageFormat != FIF_MP4) {
+	    header.containerVersion = ContainerVersion_TEXB0003;
+	}
     } else if (strncmp (magic, "TEXB0003", 9) == 0) {
-        header.containerVersion = ContainerVersion_TEXB0003;
-        header.freeImageFormat = parseFIF (file.nextUInt32 ());
+	header.containerVersion = ContainerVersion_TEXB0003;
+	header.freeImageFormat = parseFIF (file.nextUInt32 ());
     } else if (strncmp (magic, "TEXB0002", 9) == 0) {
-        header.containerVersion = ContainerVersion_TEXB0002;
+	header.containerVersion = ContainerVersion_TEXB0002;
     } else if (strncmp (magic, "TEXB0001", 9) == 0) {
-        header.containerVersion = ContainerVersion_TEXB0001;
+	header.containerVersion = ContainerVersion_TEXB0001;
     } else {
-        sLog.exception ("unknown texture format type: ", std::string_view (magic, 9));
+	sLog.exception ("unknown texture format type: ", std::string_view (magic, 9));
     }
 }
 
@@ -195,62 +196,63 @@ void TextureParser::parseAnimations (Texture& header, const BinaryReader& file)
     file.next (magic, 9);
 
     if (strncmp (magic, "TEXS0002", 9) == 0) {
-        header.animatedVersion = AnimatedVersion_TEXS0002;
+	header.animatedVersion = AnimatedVersion_TEXS0002;
     } else if (strncmp (magic, "TEXS0003", 9) == 0) {
-        header.animatedVersion = AnimatedVersion_TEXS0003;
+	header.animatedVersion = AnimatedVersion_TEXS0003;
     } else {
-        sLog.exception ("found animation information of unknown type: ", std::string_view (magic, 9));
+	sLog.exception ("found animation information of unknown type: ", std::string_view (magic, 9));
     }
 
     uint32_t frameCount = file.nextUInt32 ();
 
     if (header.animatedVersion == AnimatedVersion_TEXS0003) {
-        header.gifWidth = file.nextUInt32 ();
-        header.gifHeight = file.nextUInt32 ();
+	header.gifWidth = file.nextUInt32 ();
+	header.gifHeight = file.nextUInt32 ();
     }
 
     while (frameCount-- > 0) {
-        header.frames.push_back (parseFrame (file));
+	header.frames.push_back (parseFrame (file));
     }
 
     // ensure gif width and height is right for TEXS0002
     if (header.animatedVersion == AnimatedVersion_TEXS0002) {
-        header.gifWidth = (*header.frames.begin ())->width1;
-        header.gifHeight = (*header.frames.begin ())->height1;
+	header.gifWidth = (*header.frames.begin ())->width1;
+	header.gifHeight = (*header.frames.begin ())->height1;
     }
 
     // Calculate spritesheet grid dimensions from animation frames
     // Spritesheets are grid-based textures where each frame is at a specific position
     if (!header.frames.empty () && header.width > 0 && header.height > 0) {
-        auto& firstFrame = *header.frames.front ();
-        float frameWidth = firstFrame.width1;
-        float frameHeight = firstFrame.height1;
-
-        if (frameWidth > 0.0f && frameHeight > 0.0f) {
-            const uint32_t cols = static_cast<uint32_t> (std::round (static_cast<double> (header.width) / frameWidth));
-            const uint32_t rows = static_cast<uint32_t> (std::round (static_cast<double> (header.height) / frameHeight));
-            const uint32_t frameCount = static_cast<uint32_t> (header.frames.size ());
-
-            // Only populate spritesheet metadata if the inferred grid can actually hold all frames
-            // This prevents GIFs (where frameWidth == textureWidth) from being treated as 1×1 spritesheets
-            if (cols > 0 && rows > 0 && cols * rows >= frameCount) {
-                header.spritesheetCols = cols;
-                header.spritesheetRows = rows;
-                header.spritesheetFrames = frameCount;
-
-                float totalDuration = 0.0f;
-                for (const auto& frame : header.frames) {
-                    totalDuration += frame->frametime;
-                }
-                header.spritesheetDuration = totalDuration;
-            }
-        }
+	auto& firstFrame = *header.frames.front ();
+	float frameWidth = firstFrame.width1;
+	float frameHeight = firstFrame.height1;
+
+	if (frameWidth > 0.0f && frameHeight > 0.0f) {
+	    const uint32_t cols = static_cast<uint32_t> (std::round (static_cast<double> (header.width) / frameWidth));
+	    const uint32_t rows
+		= static_cast<uint32_t> (std::round (static_cast<double> (header.height) / frameHeight));
+	    const uint32_t frameCount = static_cast<uint32_t> (header.frames.size ());
+
+	    // Only populate spritesheet metadata if the inferred grid can actually hold all frames
+	    // This prevents GIFs (where frameWidth == textureWidth) from being treated as 1×1 spritesheets
+	    if (cols > 0 && rows > 0 && cols * rows >= frameCount) {
+		header.spritesheetCols = cols;
+		header.spritesheetRows = rows;
+		header.spritesheetFrames = frameCount;
+
+		float totalDuration = 0.0f;
+		for (const auto& frame : header.frames) {
+		    totalDuration += frame->frametime;
+		}
+		header.spritesheetDuration = totalDuration;
+	    }
+	}
     }
 }
 
 uint32_t TextureParser::parseTextureFlags (uint32_t value) {
     if (value < TextureFlags_All) {
-        return value;
+	return value;
     }
 
     sLog.exception ("unknown texture flags: ", value);
@@ -258,90 +260,93 @@ uint32_t TextureParser::parseTextureFlags (uint32_t value) {
 
 FIF TextureParser::parseFIF (uint32_t value) {
     switch (value) {
-        case FIF_UNKNOWN:
-        case FIF_BMP:
-        case FIF_ICO:
-        case FIF_JPEG:
-        case FIF_JNG:
-        case FIF_KOALA:
-        case FIF_LBM:
-        case FIF_MNG:
-        case FIF_PBM:
-        case FIF_PBMRAW:
-        case FIF_PCD:
-        case FIF_PCX:
-        case FIF_PGM:
-        case FIF_PGMRAW:
-        case FIF_PNG:
-        case FIF_PPM:
-        case FIF_PPMRAW:
-        case FIF_RAS:
-        case FIF_TARGA:
-        case FIF_TIFF:
-        case FIF_WBMP:
-        case FIF_PSD:
-        case FIF_CUT:
-        case FIF_XBM:
-        case FIF_XPM:
-        case FIF_DDS:
-        case FIF_GIF:
-        case FIF_HDR:
-        case FIF_FAXG3:
-        case FIF_SGI:
-        case FIF_EXR:
-        case FIF_J2K:
-        case FIF_JP2:
-        case FIF_PFM:
-        case FIF_PICT:
-        case FIF_RAW:
-        case FIF_WEBP:
-        case FIF_JXR:
-            return static_cast<FIF> (value);
-
-        default:
-            sLog.exception ("unknown free image format: ", value);
+	case FIF_UNKNOWN:
+	case FIF_BMP:
+	case FIF_ICO:
+	case FIF_JPEG:
+	case FIF_JNG:
+	case FIF_KOALA:
+	case FIF_LBM:
+	case FIF_MNG:
+	case FIF_PBM:
+	case FIF_PBMRAW:
+	case FIF_PCD:
+	case FIF_PCX:
+	case FIF_PGM:
+	case FIF_PGMRAW:
+	case FIF_PNG:
+	case FIF_PPM:
+	case FIF_PPMRAW:
+	case FIF_RAS:
+	case FIF_TARGA:
+	case FIF_TIFF:
+	case FIF_WBMP:
+	case FIF_PSD:
+	case FIF_CUT:
+	case FIF_XBM:
+	case FIF_XPM:
+	case FIF_DDS:
+	case FIF_GIF:
+	case FIF_HDR:
+	case FIF_FAXG3:
+	case FIF_SGI:
+	case FIF_EXR:
+	case FIF_J2K:
+	case FIF_JP2:
+	case FIF_PFM:
+	case FIF_PICT:
+	case FIF_RAW:
+	case FIF_WEBP:
+	case FIF_JXR:
+	    return static_cast<FIF> (value);
+
+	default:
+	    sLog.exception ("unknown free image format: ", value);
     }
 }
 
-TextureUniquePtr TextureParser::parse (const BinaryReader& file, const std::string& filename,
-                                       std::function<std::string(const std::string&)> metadataLoader) {
+TextureUniquePtr TextureParser::parse (
+    const BinaryReader& file, const std::string& filename,
+    std::function<std::string (const std::string&)> metadataLoader
+) {
     // Parse the binary .tex file first
     auto result = parse (file);
 
     // Try to load optional .tex-json metadata for spritesheet data
     if (metadataLoader) {
-        parseSpritesheetMetadata (*result, filename, metadataLoader);
+	parseSpritesheetMetadata (*result, filename, metadataLoader);
     }
 
     return result;
 }
 
-void TextureParser::parseSpritesheetMetadata (Texture& header, const std::string& filename,
-                                              std::function<std::string(const std::string&)> metadataLoader) {
+void TextureParser::parseSpritesheetMetadata (
+    Texture& header, const std::string& filename, std::function<std::string (const std::string&)> metadataLoader
+) {
     try {
-        std::string texJsonContent = metadataLoader (filename + ".tex-json");
-        nlohmann::json texJson = nlohmann::json::parse (texJsonContent);
-
-        // Check for spritesheet sequences
-        if (texJson.contains ("spritesheetsequences") && texJson["spritesheetsequences"].is_array ()) {
-            auto& sequences = texJson["spritesheetsequences"];
-            if (!sequences.empty ()) {
-                auto& firstSeq = sequences[0];
-                int frames = firstSeq.value ("frames", 0);
-                float frameWidth = firstSeq.value ("width", 0.0f);
-                float frameHeight = firstSeq.value ("height", 0.0f);
-                float duration = firstSeq.value ("duration", 1.0f);
-
-                if (frames > 0 && frameWidth > 0.0f && frameHeight > 0.0f && header.width > 0 && header.height > 0) {
-                    // Calculate grid dimensions from texture size and frame size
-                    header.spritesheetCols = static_cast<uint32_t> (std::round (header.width / frameWidth));
-                    header.spritesheetRows = static_cast<uint32_t> (std::round (header.height / frameHeight));
-                    header.spritesheetFrames = static_cast<uint32_t> (frames);
-                    header.spritesheetDuration = duration;
-                }
-            }
-        }
+	std::string texJsonContent = metadataLoader (filename + ".tex-json");
+	nlohmann::json texJson = nlohmann::json::parse (texJsonContent);
+
+	// Check for spritesheet sequences
+	if (texJson.contains ("spritesheetsequences") && texJson["spritesheetsequences"].is_array ()) {
+	    auto& sequences = texJson["spritesheetsequences"];
+	    if (!sequences.empty ()) {
+		auto& firstSeq = sequences[0];
+		int frames = firstSeq.value ("frames", 0);
+		float frameWidth = firstSeq.value ("width", 0.0f);
+		float frameHeight = firstSeq.value ("height", 0.0f);
+		float duration = firstSeq.value ("duration", 1.0f);
+
+		if (frames > 0 && frameWidth > 0.0f && frameHeight > 0.0f && header.width > 0 && header.height > 0) {
+		    // Calculate grid dimensions from texture size and frame size
+		    header.spritesheetCols = static_cast<uint32_t> (std::round (header.width / frameWidth));
+		    header.spritesheetRows = static_cast<uint32_t> (std::round (header.height / frameHeight));
+		    header.spritesheetFrames = static_cast<uint32_t> (frames);
+		    header.spritesheetDuration = duration;
+		}
+	    }
+	}
     } catch (const std::exception&) {
-        // .tex-json file is optional, only used for spritesheet data
+	// .tex-json file is optional, only used for spritesheet data
     }
 }

+ 10 - 7
src/WallpaperEngine/Data/Parsers/TextureParser.h

@@ -2,8 +2,8 @@
 
 #include "WallpaperEngine/Data/Assets/Texture.h"
 
-#include <iostream>
 #include <functional>
+#include <iostream>
 
 #include "WallpaperEngine/Data/Model/Types.h"
 #include "WallpaperEngine/Data/Utils/BinaryReader.h"
@@ -13,19 +13,22 @@ using namespace WallpaperEngine::Data::Utils;
 using namespace WallpaperEngine::Data::Assets;
 
 class TextureParser {
-  public:
+public:
     static TextureUniquePtr parse (const BinaryReader& file);
-    static TextureUniquePtr parse (const BinaryReader& file, const std::string& filename,
-                                    std::function<std::string(const std::string&)> metadataLoader);
+    static TextureUniquePtr parse (
+	const BinaryReader& file, const std::string& filename,
+	std::function<std::string (const std::string&)> metadataLoader
+    );
     static MipmapSharedPtr parseMipmap (const BinaryReader& file, const Texture& header);
     static FrameSharedPtr parseFrame (const BinaryReader& file);
 
-  private:
+private:
     static void parseTextureHeader (Texture& header, const BinaryReader& file);
     static void parseContainer (Texture& header, const BinaryReader& file);
     static void parseAnimations (Texture& header, const BinaryReader& file);
-    static void parseSpritesheetMetadata (Texture& header, const std::string& filename,
-                                          std::function<std::string(const std::string&)> metadataLoader);
+    static void parseSpritesheetMetadata (
+	Texture& header, const std::string& filename, std::function<std::string (const std::string&)> metadataLoader
+    );
     static TextureFormat parseTextureFormat (uint32_t value);
     static uint32_t parseTextureFlags (uint32_t value);
     static FIF parseFIF (uint32_t value);

+ 47 - 46
src/WallpaperEngine/Data/Parsers/UserSettingParser.cpp

@@ -1,84 +1,85 @@
 #include "UserSettingParser.h"
 
-#include "WallpaperEngine/Data/Model/UserSetting.h"
 #include "WallpaperEngine/Data/Model/Property.h"
+#include "WallpaperEngine/Data/Model/UserSetting.h"
 
 using namespace WallpaperEngine::Data::Parsers;
 using namespace WallpaperEngine::Data::Builders;
 
 UserSettingUniquePtr UserSettingParser::parse (const json& data, const Properties& properties) {
-    auto value = std::make_unique <DynamicValue> ();
+    auto value = std::make_unique<DynamicValue> ();
     PropertySharedPtr property;
     std::optional<ConditionInfo> condition;
     auto valueIt = data;
     std::string content = data.dump ();
 
     if (data.is_object ()) {
-        const auto user = data.optional ("user");
-        const auto script = data.optional ("script");
-        valueIt = data.require ("value", "User setting must have a value");
+	const auto user = data.optional ("user");
+	const auto script = data.optional ("script");
+	valueIt = data.require ("value", "User setting must have a value");
 
-        // TODO: PARSE SCRIPT VALUES
-        if (script.has_value () && !script->is_null ()) {
-            sLog.error ("Found user setting with script value: ", script.value ().dump ());
-        }
+	// TODO: PARSE SCRIPT VALUES
+	if (script.has_value () && !script->is_null ()) {
+	    sLog.error ("Found user setting with script value: ", script.value ().dump ());
+	}
 
-        if (user.has_value () && !user->is_null ()) {
-            std::string source;
+	if (user.has_value () && !user->is_null ()) {
+	    std::string source;
 
-            if (const auto& it = *user; it.is_string ()) {
-                source = it;
-            } else {
-                condition = ConditionInfo {
-                    .name = it.require <std::string> ("name", "Name for conditional setting must be present"),
-                    .condition = it.require <std::string> ("condition", "Condition for conditional setting must be present"),
-                };
+	    if (const auto& it = *user; it.is_string ()) {
+		source = it;
+	    } else {
+		condition = ConditionInfo {
+		    .name = it.require<std::string> ("name", "Name for conditional setting must be present"),
+		    .condition
+		    = it.require<std::string> ("condition", "Condition for conditional setting must be present"),
+		};
 
-                source = condition.value ().name;
-            }
+		source = condition.value ().name;
+	    }
 
-            if (const auto propertyIt = properties.find (source); propertyIt != properties.end ()) {
-                property = propertyIt->second;
-            }
-        }
+	    if (const auto propertyIt = properties.find (source); propertyIt != properties.end ()) {
+		property = propertyIt->second;
+	    }
+	}
     }
 
     // actual value parsing
     if (valueIt.is_string ()) {
-        std::string str = valueIt;
+	std::string str = valueIt;
 
-        // TODO: VALIDATE THIS IS RIGHT?
-        if (int size = VectorBuilder::preparseSize (str); size == 2) {
-            value->update (static_cast<glm::vec2> (valueIt));
-        } else if (size == 3) {
-            value->update (static_cast<glm::vec3> (valueIt));
-        } else {
-            value->update (static_cast<glm::vec4> (valueIt));
-        }
+	// TODO: VALIDATE THIS IS RIGHT?
+	if (int size = VectorBuilder::preparseSize (str); size == 2) {
+	    value->update (static_cast<glm::vec2> (valueIt));
+	} else if (size == 3) {
+	    value->update (static_cast<glm::vec3> (valueIt));
+	} else {
+	    value->update (static_cast<glm::vec4> (valueIt));
+	}
     } else if (valueIt.is_number_integer ()) {
-        value->update (valueIt.get <int> ());
+	value->update (valueIt.get<int> ());
     } else if (valueIt.is_number_float ()) {
-        value->update (valueIt.get <float> ());
+	value->update (valueIt.get<float> ());
     } else if (valueIt.is_boolean ()) {
-        value->update (valueIt.get <bool> ());
+	value->update (valueIt.get<bool> ());
     } else if (valueIt.is_null ()) {
-        // null value with no connection to property
-        value->update ();
+	// null value with no connection to property
+	value->update ();
     }
 
     // TODO: This might need to be removed if it causes issues with default values
     // Connect to property if one is specified (this allows property overrides to propagate)
     if (property != nullptr) {
-        if (condition.has_value ()) {
-            value->attachCondition (condition.value ());
-        }
+	if (condition.has_value ()) {
+	    value->attachCondition (condition.value ());
+	}
 
-        value->connect (property.get());
+	value->connect (property.get ());
     }
 
-    return std::make_unique <UserSetting> (UserSetting {
-        .value = std::move (value),
-        .property = property,
-        .condition = condition,
+    return std::make_unique<UserSetting> (UserSetting {
+	.value = std::move (value),
+	.property = property,
+	.condition = condition,
     });
 }

+ 1 - 1
src/WallpaperEngine/Data/Parsers/UserSettingParser.h

@@ -10,7 +10,7 @@ using json = WallpaperEngine::Data::JSON::JSON;
 using namespace WallpaperEngine::Data::Model;
 
 class UserSettingParser {
-  public:
+public:
     static UserSettingUniquePtr parse (const json& data, const Properties& properties);
 };
 } // namespace WallpaperEngine::Data::Parsers

+ 16 - 18
src/WallpaperEngine/Data/Parsers/WallpaperParser.cpp

@@ -10,14 +10,14 @@ using namespace WallpaperEngine::Data::Parsers;
 
 WallpaperUniquePtr WallpaperParser::parse (const JSON& file, Project& project) {
     switch (project.type) {
-        case Project::Type_Scene:
-            return parseScene (file, project);
-        case Project::Type_Video:
-            return parseVideo (file, project);
-        case Project::Type_Web:
-            return parseWeb (file, project);
-        default:
-            sLog.exception ("Unexpected project type value found... This is likely a bug");
+	case Project::Type_Scene:
+	    return parseScene (file, project);
+	case Project::Type_Video:
+	    return parseVideo (file, project);
+	case Project::Type_Web:
+	    return parseWeb (file, project);
+	default:
+	    sLog.exception ("Unexpected project type value found... This is likely a bug");
     }
 }
 
@@ -25,7 +25,8 @@ SceneUniquePtr WallpaperParser::parseScene (const JSON& file, Project& project)
     const auto scene = JSON::parse (project.assetLocator->readString (file));
     const auto camera = scene.require ("camera", "Scenes must have a camera section");
     const auto general = scene.require ("general", "Scenes must have a general section");
-    const auto projection = general.require ("orthogonalprojection", "General section must have orthogonal projection info");
+    const auto projection
+	= general.require ("orthogonalprojection", "General section must have orthogonal projection info");
     const auto objects = scene.require ("objects", "Scenes must have an objects section");
     const auto& properties = project.properties;
 
@@ -82,16 +83,13 @@ SceneUniquePtr WallpaperParser::parseScene (const JSON& file, Project& project)
 }
 
 VideoUniquePtr WallpaperParser::parseVideo (const JSON& file, Project& project) {
-    return std::make_unique <Video> (WallpaperData {
-        .filename = file,
-        .project = project
-    });
+    return std::make_unique<Video> (WallpaperData { .filename = file, .project = project });
 }
 
-WebUniquePtr  WallpaperParser::parseWeb (const JSON& file, Project& project) {
-    return std::make_unique <Web> (WallpaperData {
-        .filename = file,
-        .project = project,
+WebUniquePtr WallpaperParser::parseWeb (const JSON& file, Project& project) {
+    return std::make_unique<Web> (WallpaperData {
+	.filename = file,
+	.project = project,
     });
 }
 
@@ -99,7 +97,7 @@ ObjectList WallpaperParser::parseObjects (const JSON& objects, const Project& pr
     ObjectList result = {};
 
     for (const auto& cur : objects) {
-        result.emplace_back (ObjectParser::parse (cur, project));
+	result.emplace_back (ObjectParser::parse (cur, project));
     }
 
     return result;

+ 2 - 2
src/WallpaperEngine/Data/Parsers/WallpaperParser.h

@@ -8,10 +8,10 @@ using JSON = WallpaperEngine::Data::JSON::JSON;
 using namespace WallpaperEngine::Data::Model;
 
 class WallpaperParser {
-  public:
+public:
     static WallpaperUniquePtr parse (const JSON& file, Project& project);
 
-  private:
+private:
     static SceneUniquePtr parseScene (const JSON& file, Project& project);
     static VideoUniquePtr parseVideo (const JSON& file, Project& project);
     static WebUniquePtr parseWeb (const JSON& file, Project& project);

+ 9 - 27
src/WallpaperEngine/Data/Utils/BinaryReader.cpp

@@ -1,5 +1,5 @@
-#include <iostream>
 #include <bit>
+#include <iostream>
 
 #include "BinaryReader.h"
 
@@ -15,15 +15,9 @@ uint32_t BinaryReader::nextUInt32 () const {
     this->m_input->read (buffer, 4);
 
     if constexpr (std::endian::native == std::endian::little) {
-        return (buffer [3] & 0xFF) << 24 |
-               (buffer [2] & 0xFF) << 16 |
-               (buffer [1] & 0xFF) << 8 |
-               (buffer [0] & 0xFF);
+	return (buffer[3] & 0xFF) << 24 | (buffer[2] & 0xFF) << 16 | (buffer[1] & 0xFF) << 8 | (buffer[0] & 0xFF);
     } else {
-        return (buffer [0] & 0xFF) << 24 |
-               (buffer [1] & 0xFF) << 16 |
-               (buffer [2] & 0xFF) << 8 |
-               (buffer [3] & 0xFF);
+	return (buffer[0] & 0xFF) << 24 | (buffer[1] & 0xFF) << 16 | (buffer[2] & 0xFF) << 8 | (buffer[3] & 0xFF);
     }
 }
 
@@ -33,15 +27,9 @@ int BinaryReader::nextInt () const {
     this->m_input->read (buffer, 4);
 
     if constexpr (std::endian::native == std::endian::little) {
-        return (buffer [3] & 0xFF) << 24 |
-               (buffer [2] & 0xFF) << 16 |
-               (buffer [1] & 0xFF) << 8 |
-               (buffer [0] & 0xFF);
+	return (buffer[3] & 0xFF) << 24 | (buffer[2] & 0xFF) << 16 | (buffer[1] & 0xFF) << 8 | (buffer[0] & 0xFF);
     } else {
-        return (buffer [0] & 0xFF) << 24 |
-               (buffer [1] & 0xFF) << 16 |
-               (buffer [2] & 0xFF) << 8 |
-               (buffer [3] & 0xFF);
+	return (buffer[0] & 0xFF) << 24 | (buffer[1] & 0xFF) << 16 | (buffer[2] & 0xFF) << 8 | (buffer[3] & 0xFF);
     }
 }
 
@@ -49,17 +37,16 @@ float BinaryReader::nextFloat () const {
     float result;
     static_assert (std::endian::native == std::endian::little, "Only little endian is supported for floats");
 
-    this->m_input->read (reinterpret_cast<char*>(&result), sizeof (result));
+    this->m_input->read (reinterpret_cast<char*> (&result), sizeof (result));
 
     return result;
 }
 
-
 std::string BinaryReader::nextNullTerminatedString () const {
     std::string output;
 
     while (const auto c = this->next ()) {
-        output += c;
+	output += c;
     }
 
     return output;
@@ -74,10 +61,7 @@ std::string BinaryReader::nextSizedString () const {
     return output;
 }
 
-
-void BinaryReader::next (char* out, size_t size) const {
-    this->m_input->read (out, size);
-}
+void BinaryReader::next (char* out, size_t size) const { this->m_input->read (out, size); }
 
 char BinaryReader::next () const {
     char buffer;
@@ -85,6 +69,4 @@ char BinaryReader::next () const {
     return buffer;
 }
 
-std::istream& BinaryReader::base () const {
-    return *this->m_input;
-}
+std::istream& BinaryReader::base () const { return *this->m_input; }

+ 3 - 3
src/WallpaperEngine/Data/Utils/BinaryReader.h

@@ -9,7 +9,7 @@ using ReadStream = std::istream;
 using ReadStreamSharedPtr = std::shared_ptr<ReadStream>;
 
 class BinaryReader {
-  public:
+public:
     explicit BinaryReader (ReadStreamSharedPtr file);
 
     [[nodiscard]] uint32_t nextUInt32 () const;
@@ -17,12 +17,12 @@ class BinaryReader {
     [[nodiscard]] float nextFloat () const;
     [[nodiscard]] std::string nextNullTerminatedString () const;
     [[nodiscard]] std::string nextSizedString () const;
-    void next(char* out, size_t size) const;
+    void next (char* out, size_t size) const;
     [[nodiscard]] char next () const;
 
     [[nodiscard]] std::istream& base () const;
 
-  private:
+private:
     ReadStreamSharedPtr m_input;
 };
 

+ 14 - 21
src/WallpaperEngine/Data/Utils/MemoryStream.h

@@ -3,29 +3,22 @@
 #include <iostream>
 
 namespace WallpaperEngine::Data::Utils {
-struct MemoryStream : std::istream, private std::streambuf
-{
-    MemoryStream (std::unique_ptr <char[]> buffer, const size_t size) :
-        std::istream (this),
-        m_buffer (std::move (buffer))
-    {
-        this->setg(
-            this->m_buffer.get (),
-            this->m_buffer.get (),
-            this->m_buffer.get () + size
-        );
+struct MemoryStream : std::istream, private std::streambuf {
+    MemoryStream (std::unique_ptr<char[]> buffer, const size_t size) :
+	std::istream (this), m_buffer (std::move (buffer)) {
+	this->setg (this->m_buffer.get (), this->m_buffer.get (), this->m_buffer.get () + size);
     }
 
-    std::streambuf::pos_type seekoff(std::streambuf::off_type off,
-                     std::ios_base::seekdir dir,
-                     std::ios_base::openmode which) override {
-        if (dir == std::ios_base::cur)
-            gbump(off);
-        else if (dir == std::ios_base::end)
-            setg(eback(), egptr() + off, egptr());
-        else if (dir == std::ios_base::beg)
-            setg(eback(), eback() + off, egptr());
-        return gptr() - eback();
+    std::streambuf::pos_type
+    seekoff (std::streambuf::off_type off, std::ios_base::seekdir dir, std::ios_base::openmode which) override {
+	if (dir == std::ios_base::cur) {
+	    gbump (off);
+	} else if (dir == std::ios_base::end) {
+	    setg (eback (), egptr () + off, egptr ());
+	} else if (dir == std::ios_base::beg) {
+	    setg (eback (), eback () + off, egptr ());
+	}
+	return gptr () - eback ();
     }
 
     std::unique_ptr<char[]> m_buffer;

+ 4 - 8
src/WallpaperEngine/Data/Utils/SFINAE.h

@@ -5,18 +5,14 @@
 
 namespace WallpaperEngine::Data::Utils::SFINAE {
 // sfinae to detect the type for template specialization
-template <typename T>
-struct is_glm_vec : std::false_type {};
+template <typename T> struct is_glm_vec : std::false_type { };
 
-template <glm::length_t L, typename S, glm::qualifier Q>
-struct is_glm_vec<glm::vec<L, S, Q>> : std::true_type {};
+template <glm::length_t L, typename S, glm::qualifier Q> struct is_glm_vec<glm::vec<L, S, Q>> : std::true_type { };
 
 // traits used to guess the type of the vector and it's length
-template <typename T>
-struct GlmVecTraits;
+template <typename T> struct GlmVecTraits;
 
-template <glm::length_t L, typename T, glm::qualifier Q>
-struct GlmVecTraits<glm::vec<L, T, Q>> {
+template <glm::length_t L, typename T, glm::qualifier Q> struct GlmVecTraits<glm::vec<L, T, Q>> {
     static constexpr int length = L;
     using type = T;
     static constexpr glm::qualifier qualifier = Q;

+ 11 - 13
src/WallpaperEngine/Data/Utils/TypeCaster.h

@@ -10,27 +10,25 @@ namespace WallpaperEngine::Data::Utils {
  * Uses typeid from C++17, so base types must have a virtual, default destructor
  */
 class TypeCaster {
-  public:
-    virtual ~TypeCaster() = default;
+public:
+    virtual ~TypeCaster () = default;
 
     template <class T> [[nodiscard]] const T* as () const {
-        if (is<T> ()) {
-            return static_cast <const T*> (this);
-        }
+	if (is<T> ()) {
+	    return static_cast<const T*> (this);
+	}
 
-        throw std::bad_cast ();
+	throw std::bad_cast ();
     }
 
     template <class T> [[nodiscard]] T* as () {
-        if (is<T> ()) {
-            return static_cast <T*> (this);
-        }
+	if (is<T> ()) {
+	    return static_cast<T*> (this);
+	}
 
-        throw std::bad_cast ();
+	throw std::bad_cast ();
     }
 
-    template <class T> [[nodiscard]] bool is () const {
-        return typeid(*this) == typeid(T);
-    }
+    template <class T> [[nodiscard]] bool is () const { return typeid (*this) == typeid (T); }
 };
 } // namespace WallpaperEngine::Data::Utils

+ 152 - 162
src/WallpaperEngine/Debugging/CallStack.cpp

@@ -38,24 +38,24 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 //
 
 #include "CallStack.h"
-#include <vector>
-#include <string>
-#include <cstdlib>
-#include <cstdio>
 #include <cassert>
+#include <cstdio>
+#include <cstdlib>
+#include <string>
+#include <vector>
 
 #if defined(_WIN32)
-#include <windows.h>
 #include <imagehlp.h>
+#include <windows.h>
 #if defined(__MINGW32__)
-#define PACKAGE         1 // Supress cmake error.
+#define PACKAGE 1 // Supress cmake error.
 #define PACKAGE_VERSION 1 // Supress cmake error.
 #include <bfd.h>
 #include <cxxabi.h>
 #endif
 #else
-#include <execinfo.h>
 #include <cxxabi.h>
+#include <execinfo.h>
 #endif
 
 using namespace WallpaperEngine::Debugging;
@@ -64,32 +64,22 @@ using namespace std;
 const char* CallStack::Unknown_Function = "[unknown function]";
 const char* CallStack::Unknown_Module = "[unknown module]";
 
-CallStack::CallStack(void)
-{
-    /* Nothing to do */
-}
+CallStack::CallStack (void) { /* Nothing to do */ }
 
-CallStack::~CallStack(void)
-{
-    /* Nothing to do */
-}
+CallStack::~CallStack (void) { /* Nothing to do */ }
 
-string CallStack::Demangle(const char* name)
-{
+string CallStack::Demangle (const char* name) {
 #if defined(_MSC_VER)
-    return string(name);
+    return string (name);
 #else
     string dname;
     int status = 0;
-    char* pdname = abi::__cxa_demangle(name, NULL, 0, &status);
-    if(status == 0)
-    {
-        dname.assign(pdname);
-        free(pdname);
-    }
-    else
-    {
-        dname.assign(CallStack::Unknown_Function);
+    char* pdname = abi::__cxa_demangle (name, NULL, 0, &status);
+    if (status == 0) {
+	dname.assign (pdname);
+	free (pdname);
+    } else {
+	dname.assign (CallStack::Unknown_Function);
     }
     return dname;
 #endif
@@ -99,76 +89,71 @@ string CallStack::Demangle(const char* name)
 class noncopyable // Like the one in boost.
 {
 protected:
-    noncopyable(void) { /* Nothing to do */ }
+    noncopyable (void) { /* Nothing to do */ }
+
 private:
-    noncopyable(const noncopyable&);
-    noncopyable& operator = (const noncopyable&);
+    noncopyable (const noncopyable&);
+    noncopyable& operator= (const noncopyable&);
 };
 // A global thread mutex class.
-class mutex : noncopyable
-{
+class mutex : noncopyable {
 public:
-    mutex(void) { InitializeCriticalSection(&cs); }
-    ~mutex(void) { DeleteCriticalSection(&cs); }
-    void lock(void) { EnterCriticalSection(&cs); }
-    void unlock(void) { LeaveCriticalSection(&cs); }
+    mutex (void) { InitializeCriticalSection (&cs); }
+    ~mutex (void) { DeleteCriticalSection (&cs); }
+    void lock (void) { EnterCriticalSection (&cs); }
+    void unlock (void) { LeaveCriticalSection (&cs); }
+
 private:
     CRITICAL_SECTION cs;
 } cs;
 #if defined(__MINGW32__)
-class bfd_usage : noncopyable
-{
+class bfd_usage : noncopyable {
 public:
-    bfd_usage(void) : abfd(NULL), sec(NULL), symbol_table(NULL)
-    {
-        char procname[MAX_PATH];
-        GetModuleFileName(NULL, procname, sizeof(procname));
-
-        bfd_init();
-        abfd = bfd_openr(procname, NULL); // Obtain the bfd pointer.
-        if(abfd == NULL)
-        {
-            fprintf(stderr, "Error: Failed to parse the executable format.\n");
-            return;
-        }
-
-        char** matching = NULL;
-        if(!(bfd_check_format(abfd, bfd_object) && // Whether the executable format is supported.
-                    bfd_check_format_matches(abfd, bfd_object, &matching) && // Whether the executable format is supported.
-                    (bfd_get_file_flags(abfd) & HAS_SYMS))) // Whether BFD has symbols
-        {
-            bfd_close(abfd);
-            free(matching);
-            fprintf(stderr, "Error: Failed to parse the executable format.\n");
-            return;
-        }
-        free(matching);
-
-        // Obtain the symbol table.
-        unsigned int dummy = 0;
-        if(bfd_read_minisymbols(abfd, FALSE, reinterpret_cast<void**>(&symbol_table), &dummy) == 0 &&
-                bfd_read_minisymbols(abfd, TRUE, reinterpret_cast<void**>(&symbol_table), &dummy) < 0)
-        {
-            free(symbol_table);
-            bfd_close(abfd);
-            fprintf(stderr, "Error: Failed to obtain the symbol table from the executable.\n");
-            return;
-        }
+    bfd_usage (void) : abfd (NULL), sec (NULL), symbol_table (NULL) {
+	char procname[MAX_PATH];
+	GetModuleFileName (NULL, procname, sizeof (procname));
+
+	bfd_init ();
+	abfd = bfd_openr (procname, NULL); // Obtain the bfd pointer.
+	if (abfd == NULL) {
+	    fprintf (stderr, "Error: Failed to parse the executable format.\n");
+	    return;
+	}
+
+	char** matching = NULL;
+	if (!(bfd_check_format (abfd, bfd_object) && // Whether the executable format is supported.
+	      bfd_check_format_matches (abfd, bfd_object, &matching) && // Whether the executable format is supported.
+	      (bfd_get_file_flags (abfd) & HAS_SYMS))) // Whether BFD has symbols
+	{
+	    bfd_close (abfd);
+	    free (matching);
+	    fprintf (stderr, "Error: Failed to parse the executable format.\n");
+	    return;
+	}
+	free (matching);
+
+	// Obtain the symbol table.
+	unsigned int dummy = 0;
+	if (bfd_read_minisymbols (abfd, FALSE, reinterpret_cast<void**> (&symbol_table), &dummy) == 0
+	    && bfd_read_minisymbols (abfd, TRUE, reinterpret_cast<void**> (&symbol_table), &dummy) < 0) {
+	    free (symbol_table);
+	    bfd_close (abfd);
+	    fprintf (stderr, "Error: Failed to obtain the symbol table from the executable.\n");
+	    return;
+	}
     }
 
-    ~bfd_usage(void)
-    {
-        free(symbol_table);
-        bfd_close(abfd);
+    ~bfd_usage (void) {
+	free (symbol_table);
+	bfd_close (abfd);
     }
 
-    string get_function_name(DWORD offset)
-    {
-        fnis_para para;
-        para.symbol_table = symbol_table;
-        para.counter = offset;
-        bfd_map_over_sections(abfd, &find_function_name_in_section, &para); // Call the corresponding functions.
-        return para.function;
+    string get_function_name (DWORD offset) {
+	fnis_para para;
+	para.symbol_table = symbol_table;
+	para.counter = offset;
+	bfd_map_over_sections (abfd, &find_function_name_in_section, &para); // Call the corresponding functions.
+	return para.function;
     }
 
 private:
@@ -176,43 +161,45 @@ private:
     asection* sec;
     asymbol** symbol_table;
 
-    class fnis_para
-    {
+    class fnis_para {
     public:
-        string function;
-        asymbol** symbol_table;
-        bfd_vma counter;
+	string function;
+	asymbol** symbol_table;
+	bfd_vma counter;
     };
-    static void find_function_name_in_section(bfd* tabfd, asection* tsec, void* tpara)
-    {
-        fnis_para& para = *static_cast<fnis_para*>(tpara);
-        if(!para.function.empty()) return; // We have got the name.
-        if(!(bfd_get_section_flags(tabfd, tsec) & SEC_ALLOC)) return; // Allocate space for this section.
-        bfd_vma vma = bfd_get_section_vma(tabfd, tsec);
-        if(para.counter < vma || vma+bfd_get_section_size(tsec) <= para.counter) return;
-        const char* function = NULL;
-        const char* file = NULL;
-        unsigned int line = 0;
-        // Get corresponding file and function name, and line number.
-        if(bfd_find_nearest_line(tabfd, tsec, para.symbol_table, para.counter-vma, &file, &function, &line) && function)
-        {
-            para.function = CallStack::Demangle(function);
-        }
+    static void find_function_name_in_section (bfd* tabfd, asection* tsec, void* tpara) {
+	fnis_para& para = *static_cast<fnis_para*> (tpara);
+	if (!para.function.empty ()) {
+	    return; // We have got the name.
+	}
+	if (!(bfd_get_section_flags (tabfd, tsec) & SEC_ALLOC)) {
+	    return; // Allocate space for this section.
+	}
+	bfd_vma vma = bfd_get_section_vma (tabfd, tsec);
+	if (para.counter < vma || vma + bfd_get_section_size (tsec) <= para.counter) {
+	    return;
+	}
+	const char* function = NULL;
+	const char* file = NULL;
+	unsigned int line = 0;
+	// Get corresponding file and function name, and line number.
+	if (bfd_find_nearest_line (tabfd, tsec, para.symbol_table, para.counter - vma, &file, &function, &line)
+	    && function) {
+	    para.function = CallStack::Demangle (function);
+	}
     }
 };
 #endif // __MINGW32__
 #endif // _WIN32
 
-void CallStack::GetCalls(vector<CallStack::CallInfo>& calls)
-{
+void CallStack::GetCalls (vector<CallStack::CallInfo>& calls) {
 #if defined(_WIN32)
 
     // Prepare context.
-    cs.lock();
-    if(!SymInitialize(GetCurrentProcess(), 0, TRUE))
-    {
-        fprintf(stderr, "Error: Failed to initialize symbol context.\n");
-        return;
+    cs.lock ();
+    if (!SymInitialize (GetCurrentProcess (), 0, TRUE)) {
+	fprintf (stderr, "Error: Failed to initialize symbol context.\n");
+	return;
     }
 #ifdef __MINGW32__
     bfd_usage bfdu;
@@ -224,12 +211,12 @@ void CallStack::GetCalls(vector<CallStack::CallInfo>& calls)
 #else
     const DWORD machine = IMAGE_FILE_MACHINE_I386;
 #endif
-    const HANDLE process = GetCurrentProcess();
-    const HANDLE thread = GetCurrentThread();
+    const HANDLE process = GetCurrentProcess ();
+    const HANDLE thread = GetCurrentThread ();
     STACKFRAME frame = { 0 };
     CONTEXT context = { 0 };
     context.ContextFlags = CONTEXT_FULL;
-    RtlCaptureContext(&context);
+    RtlCaptureContext (&context);
 #if defined(_M_AMD64)
     frame.AddrPC.Offset = context.Rip;
     frame.AddrPC.Mode = AddrModeFlat;
@@ -247,81 +234,84 @@ void CallStack::GetCalls(vector<CallStack::CallInfo>& calls)
 #endif
     int limit = 0;
     const bool has_limit = (limit != 0);
-    char symbol_buffer[sizeof(IMAGEHLP_SYMBOL)+255];
+    char symbol_buffer[sizeof (IMAGEHLP_SYMBOL) + 255];
     char module_name_raw[MAX_PATH];
 
     // Go over stack.
-    calls.clear();
-    while(StackWalk(machine, process, thread, &frame, &context, 0, SymFunctionTableAccess, SymGetModuleBase, 0))
-    {
-        if(has_limit && limit == 0) break; --limit;
+    calls.clear ();
+    while (StackWalk (machine, process, thread, &frame, &context, 0, SymFunctionTableAccess, SymGetModuleBase, 0)) {
+	if (has_limit && limit == 0) {
+	    break;
+	}
+	--limit;
 
-        IMAGEHLP_SYMBOL* symbol = reinterpret_cast<IMAGEHLP_SYMBOL*>(symbol_buffer);
-        symbol->SizeOfStruct = (sizeof(*symbol))+255;
-        symbol->MaxNameLength = 254;
+	IMAGEHLP_SYMBOL* symbol = reinterpret_cast<IMAGEHLP_SYMBOL*> (symbol_buffer);
+	symbol->SizeOfStruct = (sizeof (*symbol)) + 255;
+	symbol->MaxNameLength = 254;
 
 #if defined(_WIN64)
-        const DWORD64 module_base = SymGetModuleBase(process, frame.AddrPC.Offset);
+	const DWORD64 module_base = SymGetModuleBase (process, frame.AddrPC.Offset);
 #else
-        const DWORD module_base = SymGetModuleBase(process, frame.AddrPC.Offset);
+	const DWORD module_base = SymGetModuleBase (process, frame.AddrPC.Offset);
 #endif
-        string module_name = Unknown_Module;
-        if(module_base && GetModuleFileNameA(reinterpret_cast<HINSTANCE>(module_base), module_name_raw, MAX_PATH)) module_name = module_name_raw;
+	string module_name = Unknown_Module;
+	if (module_base && GetModuleFileNameA (reinterpret_cast<HINSTANCE> (module_base), module_name_raw, MAX_PATH)) {
+	    module_name = module_name_raw;
+	}
 
 #if defined(__MINGW32__)
-        string function = bfdu.get_function_name(frame.AddrPC.Offset);
-        if(function.empty())
-        {
-            DWORD64 dummy = 0;
-            const bool got_symbol = SymGetSymFromAddr(process, frame.AddrPC.Offset, &dummy, symbol);
-            function= (got_symbol) ? (symbol->Name) : Unknown_Function;
-        }
+	string function = bfdu.get_function_name (frame.AddrPC.Offset);
+	if (function.empty ()) {
+	    DWORD64 dummy = 0;
+	    const bool got_symbol = SymGetSymFromAddr (process, frame.AddrPC.Offset, &dummy, symbol);
+	    function = (got_symbol) ? (symbol->Name) : Unknown_Function;
+	}
 #else
 #if defined(_WIN64)
-        DWORD64 dummy = 0;
+	DWORD64 dummy = 0;
 #else
-        DWORD dummy = 0;
+	DWORD dummy = 0;
 #endif
-        const bool got_symbol = SymGetSymFromAddr(process, frame.AddrPC.Offset, &dummy, symbol);
-        const string function = (got_symbol) ? symbol->Name : Unknown_Function;
+	const bool got_symbol = SymGetSymFromAddr (process, frame.AddrPC.Offset, &dummy, symbol);
+	const string function = (got_symbol) ? symbol->Name : Unknown_Function;
 
 #endif
 
-        calls.push_back(CallInfo(frame.AddrPC.Offset, function, module_name));
+	calls.push_back (CallInfo (frame.AddrPC.Offset, function, module_name));
     }
 
-    SymCleanup(GetCurrentProcess());
-    cs.unlock();
+    SymCleanup (GetCurrentProcess ());
+    cs.unlock ();
 
 #else // For Linux and Unix.
 
     const int BufferSize = 256;
     void* buffer[BufferSize];
-    const int ncalls = backtrace(buffer, sizeof(buffer));
-    char** callstrings = backtrace_symbols(buffer, ncalls);
+    const int ncalls = backtrace (buffer, sizeof (buffer));
+    char** callstrings = backtrace_symbols (buffer, ncalls);
 
-    if(callstrings == NULL)
-    {
-        fprintf(stderr, "Error: Failed to obtain the symbol table from the executable.\n");
-        return;
+    if (callstrings == NULL) {
+	fprintf (stderr, "Error: Failed to obtain the symbol table from the executable.\n");
+	return;
     }
 
-    calls.clear();
-    for(int i = 0; i < ncalls; ++i)
-    {
-        const string funinfo(callstrings[i]);
-        const int posleftparenthesis = funinfo.rfind('(');
-        const int posplus = funinfo.rfind('+');
-        const int posleftbracket = funinfo.rfind('[');
-        const int posrightbracket = funinfo.rfind(']');
-
-        long long unsigned int offset = strtoull(funinfo.substr(posleftbracket+1, posrightbracket-posleftbracket-1).c_str(), NULL, 0);
-        const string module_name = funinfo.substr(0, posleftparenthesis);
-        const string function = Demangle(funinfo.substr(posleftparenthesis+1, posplus-posleftparenthesis-1).c_str());
-
-        calls.push_back(CallInfo(offset, function, module_name));
-     }
-     free(callstrings);
+    calls.clear ();
+    for (int i = 0; i < ncalls; ++i) {
+	const string funinfo (callstrings[i]);
+	const int posleftparenthesis = funinfo.rfind ('(');
+	const int posplus = funinfo.rfind ('+');
+	const int posleftbracket = funinfo.rfind ('[');
+	const int posrightbracket = funinfo.rfind (']');
+
+	long long unsigned int offset
+	    = strtoull (funinfo.substr (posleftbracket + 1, posrightbracket - posleftbracket - 1).c_str (), NULL, 0);
+	const string module_name = funinfo.substr (0, posleftparenthesis);
+	const string function
+	    = Demangle (funinfo.substr (posleftparenthesis + 1, posplus - posleftparenthesis - 1).c_str ());
+
+	calls.push_back (CallInfo (offset, function, module_name));
+    }
+    free (callstrings);
 
 #endif // _WIN32
 }

+ 13 - 13
src/WallpaperEngine/Debugging/CallStack.h

@@ -37,8 +37,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 // mailto: zhangjunqcc@gmail.com
 //
 
-#ifndef    __CALLSTACK_H__
-#define    __CALLSTACK_H__
+#ifndef __CALLSTACK_H__
+#define __CALLSTACK_H__
 
 #include <string>
 #include <vector>
@@ -49,25 +49,25 @@ using namespace std;
 
 class CallStack {
 public:
-    CallStack(void);
-    ~CallStack(void);
+    CallStack (void);
+    ~CallStack (void);
 
     static const char* Unknown_Function;
     static const char* Unknown_Module;
 
     class CallInfo {
     public:
-        CallInfo(void) { /* Nothing to do */ }
-        CallInfo(long long unsigned int toffset, const string& tfunction, const string& tmodule)
-            : offset(toffset), function(tfunction), module(tmodule) { /* Nothing to do */ }
-        ~CallInfo(void) { /* Nothing to do */ }
-        long unsigned int offset;
-        string function;
-        string module;
+	CallInfo (void) { /* Nothing to do */ }
+	CallInfo (long long unsigned int toffset, const string& tfunction, const string& tmodule) :
+	    offset (toffset), function (tfunction), module (tmodule) { /* Nothing to do */ }
+	~CallInfo (void) { /* Nothing to do */ }
+	long unsigned int offset;
+	string function;
+	string module;
     };
 
-    static void GetCalls(vector<CallStack::CallInfo>& calls); // Get the call information.
-    static string Demangle(const char* name);                 // Demangle the C++ function name.
+    static void GetCalls (vector<CallStack::CallInfo>& calls); // Get the call information.
+    static string Demangle (const char* name); // Demangle the C++ function name.
 };
 
 }

+ 22 - 23
src/WallpaperEngine/FileSystem/Adapters/Directory.cpp

@@ -10,60 +10,59 @@ using namespace WallpaperEngine::FileSystem;
 using namespace WallpaperEngine::FileSystem::Adapters;
 
 ReadStreamSharedPtr DirectoryAdapter::open (const std::filesystem::path& path) const {
-    auto finalpath = std::filesystem::canonical(this->basepath / path);
+    auto finalpath = std::filesystem::canonical (this->basepath / path);
 
     if (finalpath.string ().find (this->basepath.string ()) != 0) {
-        throw std::filesystem::filesystem_error ("Cannot find file", path, std::error_code ());
+	throw std::filesystem::filesystem_error ("Cannot find file", path, std::error_code ());
     }
 
     const auto status = std::filesystem::status (finalpath);
 
     if (!std::filesystem::exists (finalpath)) {
-        throw std::filesystem::filesystem_error ("Cannot find file", path, std::error_code ());
+	throw std::filesystem::filesystem_error ("Cannot find file", path, std::error_code ());
     }
 
     if (!std::filesystem::is_regular_file (status)) {
-        throw std::filesystem::filesystem_error ("Expected file but found a directory", path, std::error_code ());
+	throw std::filesystem::filesystem_error ("Expected file but found a directory", path, std::error_code ());
     }
 
-    return std::make_shared <std::ifstream> (finalpath);
+    return std::make_shared<std::ifstream> (finalpath);
 }
 
 bool DirectoryAdapter::exists (const std::filesystem::path& path) const {
     try {
-        const auto finalpath = std::filesystem::canonical(this->basepath / path);
+	const auto finalpath = std::filesystem::canonical (this->basepath / path);
 
-        if (finalpath.string ().find (this->basepath.string ()) != 0) {
-            return false;
-        }
+	if (finalpath.string ().find (this->basepath.string ()) != 0) {
+	    return false;
+	}
 
-        const auto status = std::filesystem::status (finalpath);
+	const auto status = std::filesystem::status (finalpath);
 
-        if (!std::filesystem::exists (finalpath)) {
-            return false;
-        }
+	if (!std::filesystem::exists (finalpath)) {
+	    return false;
+	}
 
-        if (!std::filesystem::is_regular_file (status)) {
-            return false;
-        }
+	if (!std::filesystem::is_regular_file (status)) {
+	    return false;
+	}
 
-        return true;
+	return true;
     } catch (std::filesystem::filesystem_error&) {
-        return false;
+	return false;
     }
 }
 
 std::filesystem::path DirectoryAdapter::physicalPath (const std::filesystem::path& path) const {
-    auto finalpath = std::filesystem::canonical(this->basepath / path);
+    auto finalpath = std::filesystem::canonical (this->basepath / path);
 
     if (finalpath.string ().find (this->basepath.string ()) != 0) {
-        throw std::filesystem::filesystem_error ("Cannot find file", path, std::error_code ());
+	throw std::filesystem::filesystem_error ("Cannot find file", path, std::error_code ());
     }
 
     return finalpath;
 }
 
-
 bool DirectoryFactory::handlesMountpoint (const std::filesystem::path& path) const {
     const auto finalpath = std::filesystem::canonical (path);
     const auto status = std::filesystem::status (finalpath);
@@ -76,11 +75,11 @@ AdapterSharedPtr DirectoryFactory::create (const std::filesystem::path& path) co
     const auto status = std::filesystem::status (finalpath);
 
     if (!std::filesystem::exists (finalpath)) {
-        throw std::filesystem::filesystem_error ("Cannot find directory", path, std::error_code ());
+	throw std::filesystem::filesystem_error ("Cannot find directory", path, std::error_code ());
     }
 
     if (!std::filesystem::is_directory (status)) {
-        throw std::filesystem::filesystem_error ("Expected directory but found a file", path, std::error_code ());
+	throw std::filesystem::filesystem_error ("Expected directory but found a file", path, std::error_code ());
     }
 
     return std::make_unique<DirectoryAdapter> (finalpath);

+ 3 - 3
src/WallpaperEngine/FileSystem/Adapters/Directory.h

@@ -9,12 +9,12 @@ namespace WallpaperEngine::FileSystem::Adapters {
 struct DirectoryFactory final : Factory {
     DirectoryFactory () = default;
 
-    [[nodiscard]] bool handlesMountpoint(const std::filesystem::path& path) const override;
-    [[nodiscard]] AdapterSharedPtr create(const std::filesystem::path& path) const override;
+    [[nodiscard]] bool handlesMountpoint (const std::filesystem::path& path) const override;
+    [[nodiscard]] AdapterSharedPtr create (const std::filesystem::path& path) const override;
 };
 
 struct DirectoryAdapter final : Adapter {
-    explicit DirectoryAdapter (std::filesystem::path path) : basepath (std::move(path)) {}
+    explicit DirectoryAdapter (std::filesystem::path path) : basepath (std::move (path)) { }
 
     [[nodiscard]] ReadStreamSharedPtr open (const std::filesystem::path& path) const override;
     [[nodiscard]] bool exists (const std::filesystem::path& path) const override;

+ 12 - 12
src/WallpaperEngine/FileSystem/Adapters/Package.cpp

@@ -1,5 +1,5 @@
-#include <memory>
 #include <fstream>
+#include <memory>
 
 #include "Package.h"
 
@@ -16,29 +16,29 @@ using namespace WallpaperEngine::FileSystem::Adapters;
 ReadStreamSharedPtr PackageAdapter::open (const std::filesystem::path& path) const {
     // find the file entry
     const auto it = std::ranges::find_if (this->package->files, [&path] (const auto& file) {
-        return file->filename == path.string ();
+	return file->filename == path.string ();
     });
 
     if (it == this->package->files.end ()) {
-        throw std::filesystem::filesystem_error ("Cannot find file", path, std::error_code ());
+	throw std::filesystem::filesystem_error ("Cannot find file", path, std::error_code ());
     }
 
     // read file into memory
-    auto buffer = std::make_unique <char[]> (it->get ()->length);
+    auto buffer = std::make_unique<char[]> (it->get ()->length);
 
     // go to the file's position and read into the buffer
     this->package->file->base ().seekg (it->get ()->offset + this->package->baseOffset, std::ios::beg);
     this->package->file->next (buffer.get (), it->get ()->length);
 
     // create a memory stream and return that
-    return std::make_shared <MemoryStream> (std::move (buffer), it->get ()->length);
+    return std::make_shared<MemoryStream> (std::move (buffer), it->get ()->length);
 }
 
 bool PackageAdapter::exists (const std::filesystem::path& path) const {
     for (const auto& file : this->package->files) {
-        if (file->filename == path.string ()) {
-            return true;
-        }
+	if (file->filename == path.string ()) {
+	    return true;
+	}
     }
 
     return false;
@@ -52,13 +52,13 @@ bool PackageFactory::handlesMountpoint (const std::filesystem::path& path) const
     const auto finalpath = std::filesystem::canonical (path);
     const auto status = std::filesystem::status (finalpath);
 
-    return std::filesystem::exists (finalpath) && std::filesystem::is_regular_file (status) && finalpath.extension () == ".pkg";
+    return std::filesystem::exists (finalpath) && std::filesystem::is_regular_file (status)
+	&& finalpath.extension () == ".pkg";
 }
 
 AdapterSharedPtr PackageFactory::create (const std::filesystem::path& path) const {
-    const auto stream = std::make_shared <std::ifstream> (path, std::ios::binary);
+    const auto stream = std::make_shared<std::ifstream> (path, std::ios::binary);
     auto package = Data::Parsers::PackageParser::parse (stream);
 
-    return std::make_unique <PackageAdapter> (std::move (package));
+    return std::make_unique<PackageAdapter> (std::move (package));
 }
-

+ 2 - 2
src/WallpaperEngine/FileSystem/Adapters/Package.h

@@ -4,8 +4,8 @@
 #include <utility>
 
 #include "Types.h"
-#include "WallpaperEngine/Data/Assets/Types.h"
 #include "WallpaperEngine/Data/Assets/Package.h"
+#include "WallpaperEngine/Data/Assets/Types.h"
 
 namespace WallpaperEngine::FileSystem::Adapters {
 using namespace WallpaperEngine::Data::Assets;
@@ -18,7 +18,7 @@ struct PackageFactory final : Factory {
 };
 
 struct PackageAdapter final : Adapter {
-    explicit PackageAdapter (PackageUniquePtr package) : package (std::move(package)) {};
+    explicit PackageAdapter (PackageUniquePtr package) : package (std::move (package)) { };
 
     [[nodiscard]] ReadStreamSharedPtr open (const std::filesystem::path& path) const override;
     [[nodiscard]] bool exists (const std::filesystem::path& path) const override;

+ 1 - 1
src/WallpaperEngine/FileSystem/Adapters/Types.h

@@ -1,7 +1,7 @@
 #pragma once
 
-#include <filesystem>
 #include "WallpaperEngine/Data/Utils/BinaryReader.h"
+#include <filesystem>
 
 namespace WallpaperEngine::FileSystem::Adapters {
 using namespace WallpaperEngine::Data::Utils;

+ 8 - 16
src/WallpaperEngine/FileSystem/Adapters/Virtual.cpp

@@ -11,49 +11,41 @@ ReadStreamSharedPtr VirtualAdapter::open (const std::filesystem::path& path) con
     const auto file = this->files.find (path);
 
     if (file == this->files.end ()) {
-        throw std::filesystem::filesystem_error ("Cannot find file", path, std::error_code ());
+	throw std::filesystem::filesystem_error ("Cannot find file", path, std::error_code ());
     }
 
     return file->second;
 }
 
-bool VirtualAdapter::exists (const std::filesystem::path& path) const {
-    return this->files.contains (path);
-}
+bool VirtualAdapter::exists (const std::filesystem::path& path) const { return this->files.contains (path); }
 
 std::filesystem::path VirtualAdapter::physicalPath (const std::filesystem::path& path) const {
     throw std::filesystem::filesystem_error ("Virtual adapter does not support realpath", path, std::error_code ());
 }
 
-
 void VirtualAdapter::add (const std::filesystem::path& path, const char* data) {
     size_t length = strlen (data);
-    auto buffer = std::make_unique <char[]> (length);
+    auto buffer = std::make_unique<char[]> (length);
     std::memcpy (buffer.get (), data, length);
 
-    this->add (path, std::make_shared <MemoryStream> (std::move (buffer), length));
+    this->add (path, std::make_shared<MemoryStream> (std::move (buffer), length));
 }
 
-void VirtualAdapter::add (const std::filesystem::path& path, const JSON& data) {
-    this->add (path, data.dump ());
-}
+void VirtualAdapter::add (const std::filesystem::path& path, const JSON& data) { this->add (path, data.dump ()); }
 
 void VirtualAdapter::add (const std::filesystem::path& path, const std::string& data) {
-    auto buffer = std::make_unique <char[]> (data.size ());
+    auto buffer = std::make_unique<char[]> (data.size ());
     std::memcpy (buffer.get (), data.data (), data.size ());
 
-    this->add (path, std::make_shared <MemoryStream> (std::move (buffer), data.size ()));
+    this->add (path, std::make_shared<MemoryStream> (std::move (buffer), data.size ()));
 }
 
 void VirtualAdapter::add (const std::filesystem::path& path, MemoryStreamSharedPtr stream) {
     this->files.insert_or_assign (path, stream);
 }
 
-bool VirtualFactory::handlesMountpoint (const std::filesystem::path& path) const {
-    return path.string () == "virtual";
-}
+bool VirtualFactory::handlesMountpoint (const std::filesystem::path& path) const { return path.string () == "virtual"; }
 
 AdapterSharedPtr VirtualFactory::create (const std::filesystem::path& path) const {
     return std::make_unique<VirtualAdapter> ();
 }
-

+ 2 - 2
src/WallpaperEngine/FileSystem/Adapters/Virtual.h

@@ -5,8 +5,8 @@
 
 #include "Types.h"
 
-#include "WallpaperEngine/Data/Utils/MemoryStream.h"
 #include "WallpaperEngine/Data/JSON.h"
+#include "WallpaperEngine/Data/Utils/MemoryStream.h"
 #include <map>
 
 namespace WallpaperEngine::FileSystem::Adapters {
@@ -27,6 +27,6 @@ struct VirtualAdapter final : Adapter {
     void add (const std::filesystem::path& path, const std::string& data);
     void add (const std::filesystem::path& path, MemoryStreamSharedPtr stream);
 
-    std::map <std::filesystem::path, MemoryStreamSharedPtr> files;
+    std::map<std::filesystem::path, MemoryStreamSharedPtr> files;
 };
 }

+ 22 - 21
src/WallpaperEngine/FileSystem/Container.cpp

@@ -19,7 +19,7 @@ using namespace WallpaperEngine::FileSystem::Adapters;
  * behind to trust the input data without much validation
  * @see https://en.cppreference.com/w/cpp/filesystem/path/lexically_normal
  */
-std::filesystem::path normalize_path(const std::filesystem::path& input_path) {
+std::filesystem::path normalize_path (const std::filesystem::path& input_path) {
     return input_path.lexically_normal ();
 }
 
@@ -55,41 +55,42 @@ std::filesystem::path Container::physicalPath (const std::filesystem::path& path
 AdapterSharedPtr Container::mount (const std::filesystem::path& path, const std::filesystem::path& mountPoint) {
     // check if any adapter can handle the path
     for (const auto& factory : this->m_factories) {
-        if (factory->handlesMountpoint (path) == false) {
-            continue;
-        }
+	if (factory->handlesMountpoint (path) == false) {
+	    continue;
+	}
 
-        return this->m_mountpoints.emplace_back (mountPoint, factory->create (path)).second;
+	return this->m_mountpoints.emplace_back (mountPoint, factory->create (path)).second;
     }
 
     throw std::filesystem::filesystem_error (
-        "The specified mount cannot be handled by any of the filesystem adapters", path, std::error_code ());
+	"The specified mount cannot be handled by any of the filesystem adapters", path, std::error_code ()
+    );
 }
 
-VirtualAdapter& Container::getVFS () const {
-    return *this->m_vfs;
-}
+VirtualAdapter& Container::getVFS () const { return *this->m_vfs; }
 
 Adapter& Container::resolveAdapterForFile (const std::filesystem::path& path) const {
     const auto normalized = normalize_path (path);
 
     for (const auto& [root, adapter] : this->m_mountpoints) {
-        if (normalized.string().starts_with (root.string()) == false) {
-            continue;
-        }
+	if (normalized.string ().starts_with (root.string ()) == false) {
+	    continue;
+	}
 
-        if (const auto relative = normalized.string ().substr (root.string ().length ());
-            adapter->exists (relative) == false) {
-            continue;
-        }
+	if (const auto relative = normalized.string ().substr (root.string ().length ());
+	    adapter->exists (relative) == false) {
+	    continue;
+	}
 
-        return *adapter;
+	return *adapter;
     }
 
-    if (normalized.string().starts_with ("/") == false) {
-        // try resolving as absolute, just in case it's relative to the root
-        return this->resolveAdapterForFile ("/" + normalized.string());
+    if (normalized.string ().starts_with ("/") == false) {
+	// try resolving as absolute, just in case it's relative to the root
+	return this->resolveAdapterForFile ("/" + normalized.string ());
     }
 
-    throw std::filesystem::filesystem_error ("Cannot find requested file in any of the mountpoints", path, std::error_code ());
+    throw std::filesystem::filesystem_error (
+	"Cannot find requested file in any of the mountpoints", path, std::error_code ()
+    );
 }

+ 2 - 2
src/WallpaperEngine/FileSystem/Container.h

@@ -11,7 +11,7 @@ using namespace WallpaperEngine::Data::Utils;
 using namespace WallpaperEngine::FileSystem::Adapters;
 
 class Container {
-  public:
+public:
     Container ();
     ~Container () = default;
 
@@ -52,7 +52,7 @@ class Container {
      */
     VirtualAdapter& getVFS () const;
 
-  private:
+private:
     /**
      * Searches for an adapter to handle the given file
      *

+ 8 - 15
src/WallpaperEngine/Input/Drivers/GLFWMouseInput.cpp

@@ -5,13 +5,12 @@
 
 using namespace WallpaperEngine::Input::Drivers;
 
-GLFWMouseInput::GLFWMouseInput (const Render::Drivers::GLFWOpenGLDriver& driver) :
-    m_driver (driver) {}
+GLFWMouseInput::GLFWMouseInput (const Render::Drivers::GLFWOpenGLDriver& driver) : m_driver (driver) { }
 
 void GLFWMouseInput::update () {
     if (!this->m_driver.getApp ().getContext ().settings.mouse.enabled) {
-        this->m_reportedPosition = {0, 0};
-        return;
+	this->m_reportedPosition = { 0, 0 };
+	return;
     }
 
     const int leftClickState = glfwGetMouseButton (this->m_driver.getWindow (), GLFW_MOUSE_BUTTON_LEFT);
@@ -22,23 +21,17 @@ void GLFWMouseInput::update () {
 
     // update current mouse position
     glfwGetCursorPos (this->m_driver.getWindow (), &this->m_mousePosition.x, &this->m_mousePosition.y);
-    
+
     // Convert from GLFW coordinate system (Y=0 at top) to OpenGL coordinate system (Y=0 at bottom)
     const glm::ivec2 framebufferSize = this->m_driver.getFramebufferSize ();
     this->m_mousePosition.y = static_cast<double> (framebufferSize.y) - this->m_mousePosition.y;
-    
+
     // interpolate to the new position
     this->m_reportedPosition = glm::mix (this->m_reportedPosition, this->m_mousePosition, 1.0);
 }
 
-glm::dvec2 GLFWMouseInput::position () const {
-    return this->m_reportedPosition;
-}
+glm::dvec2 GLFWMouseInput::position () const { return this->m_reportedPosition; }
 
-WallpaperEngine::Input::MouseClickStatus GLFWMouseInput::leftClick () const {
-    return m_leftClick;
-}
+WallpaperEngine::Input::MouseClickStatus GLFWMouseInput::leftClick () const { return m_leftClick; }
 
-WallpaperEngine::Input::MouseClickStatus GLFWMouseInput::rightClick () const {
-    return m_rightClick;
-}
+WallpaperEngine::Input::MouseClickStatus GLFWMouseInput::rightClick () const { return m_rightClick; }

+ 2 - 2
src/WallpaperEngine/Input/Drivers/GLFWMouseInput.h

@@ -13,7 +13,7 @@ namespace WallpaperEngine::Input::Drivers {
  * Handles mouse input for the background
  */
 class GLFWMouseInput final : public MouseInput {
-  public:
+public:
     explicit GLFWMouseInput (const Render::Drivers::GLFWOpenGLDriver& driver);
 
     /**
@@ -36,7 +36,7 @@ class GLFWMouseInput final : public MouseInput {
      */
     [[nodiscard]] MouseClickStatus rightClick () const override;
 
-  private:
+private:
     const Render::Drivers::GLFWOpenGLDriver& m_driver;
 
     /**

+ 13 - 10
src/WallpaperEngine/Input/Drivers/WaylandMouseInput.cpp

@@ -5,31 +5,34 @@
 using namespace WallpaperEngine::Input::Drivers;
 
 WaylandMouseInput::WaylandMouseInput (const WallpaperEngine::Render::Drivers::WaylandOpenGLDriver& driver) :
-    m_waylandDriver (driver) {}
+    m_waylandDriver (driver) { }
 
-void WaylandMouseInput::update () {}
+void WaylandMouseInput::update () { }
 
 glm::dvec2 WaylandMouseInput::position () const {
     if (!this->m_waylandDriver.getApp ().getContext ().settings.mouse.enabled) {
-        return {0, 0};
+	return { 0, 0 };
     }
 
-    if (m_waylandDriver.viewportInFocus && m_waylandDriver.viewportInFocus->rendering)
-        return m_waylandDriver.viewportInFocus->mousePos;
+    if (m_waylandDriver.viewportInFocus && m_waylandDriver.viewportInFocus->rendering) {
+	return m_waylandDriver.viewportInFocus->mousePos;
+    }
 
-    return {0, 0};
+    return { 0, 0 };
 }
 
 WallpaperEngine::Input::MouseClickStatus WaylandMouseInput::leftClick () const {
-    if (m_waylandDriver.viewportInFocus && m_waylandDriver.viewportInFocus->rendering)
-        return m_waylandDriver.viewportInFocus->leftClick;
+    if (m_waylandDriver.viewportInFocus && m_waylandDriver.viewportInFocus->rendering) {
+	return m_waylandDriver.viewportInFocus->leftClick;
+    }
 
     return MouseClickStatus::Released;
 }
 
 WallpaperEngine::Input::MouseClickStatus WaylandMouseInput::rightClick () const {
-    if (m_waylandDriver.viewportInFocus && m_waylandDriver.viewportInFocus->rendering)
-        return m_waylandDriver.viewportInFocus->rightClick;
+    if (m_waylandDriver.viewportInFocus && m_waylandDriver.viewportInFocus->rendering) {
+	return m_waylandDriver.viewportInFocus->rightClick;
+    }
 
     return MouseClickStatus::Released;
 }

+ 2 - 2
src/WallpaperEngine/Input/Drivers/WaylandMouseInput.h

@@ -15,7 +15,7 @@ namespace WallpaperEngine::Input::Drivers {
  * Handles mouse input for the background
  */
 class WaylandMouseInput final : public MouseInput {
-  public:
+public:
     explicit WaylandMouseInput (const WallpaperEngine::Render::Drivers::WaylandOpenGLDriver& driver);
 
     /**
@@ -38,7 +38,7 @@ class WaylandMouseInput final : public MouseInput {
      */
     [[nodiscard]] MouseClickStatus rightClick () const override;
 
-  private:
+private:
     /**
      * Wayland: Driver
      */

+ 3 - 7
src/WallpaperEngine/Input/InputContext.cpp

@@ -3,12 +3,8 @@
 using namespace WallpaperEngine::Input;
 using namespace WallpaperEngine::Render::Drivers;
 
-InputContext::InputContext (MouseInput& mouseInput) : m_mouse (mouseInput) {}
+InputContext::InputContext (MouseInput& mouseInput) : m_mouse (mouseInput) { }
 
-void InputContext::update () {
-    this->m_mouse.update ();
-}
+void InputContext::update () { this->m_mouse.update (); }
 
-const MouseInput& InputContext::getMouseInput () const {
-    return this->m_mouse;
-}
+const MouseInput& InputContext::getMouseInput () const { return this->m_mouse; }

+ 2 - 2
src/WallpaperEngine/Input/InputContext.h

@@ -8,7 +8,7 @@ class VideoDriver;
 
 namespace WallpaperEngine::Input {
 class InputContext {
-  public:
+public:
     explicit InputContext (MouseInput& mouseInput);
 
     /**
@@ -18,7 +18,7 @@ class InputContext {
 
     [[nodiscard]] const MouseInput& getMouseInput () const;
 
-  private:
+private:
     MouseInput& m_mouse;
 };
 } // namespace WallpaperEngine::Input

+ 4 - 7
src/WallpaperEngine/Input/MouseInput.h

@@ -3,25 +3,22 @@
 #include <glm/vec2.hpp>
 
 namespace WallpaperEngine::Input {
-enum MouseClickStatus : int {
-    Released = 0,
-    Clicked = 1
-};
+enum MouseClickStatus : int { Released = 0, Clicked = 1 };
 
 /**
  * Handles mouse input for the background
- * 
+ *
  * Coordinate System Convention:
  * - Engine uses OpenGL bottom-left origin (Y=0 at bottom, Y=height at top)
  * - Window systems (GLFW/Wayland) use top-left origin (Y=0 at top, Y=height at bottom)
  * - CEF/web uses top-left origin (Y=0 at top, Y=height at bottom)
- * 
+ *
  * Input drivers convert from window system coordinates to OpenGL coordinates.
  * Render code normalizes OpenGL coordinates (0=bottom, 1=top).
  * Web wallpapers convert from OpenGL coordinates to CEF coordinates.
  */
 class MouseInput {
-  public:
+public:
     virtual ~MouseInput () = default;
     /**
      * Takes current mouse position and updates it

+ 4 - 10
src/WallpaperEngine/Logging/Log.cpp

@@ -5,24 +5,18 @@
 
 using namespace WallpaperEngine::Logging;
 
-Log::Log () {
-    assert (this->sInstance == nullptr);
-}
+Log::Log () { assert (this->sInstance == nullptr); }
 
 Log& Log::get () {
     if (sInstance == nullptr) {
-        sInstance = std::make_unique<Log> ();
+	sInstance = std::make_unique<Log> ();
     }
 
     return *sInstance;
 }
 
-void Log::addOutput (std::ostream* stream) {
-    this->mOutputs.push_back (stream);
-}
+void Log::addOutput (std::ostream* stream) { this->mOutputs.push_back (stream); }
 
-void Log::addError (std::ostream* stream) {
-    this->mErrors.push_back (stream);
-}
+void Log::addError (std::ostream* stream) { this->mErrors.push_back (stream); }
 
 std::unique_ptr<Log> Log::sInstance = nullptr;

+ 36 - 31
src/WallpaperEngine/Logging/Log.h

@@ -11,73 +11,78 @@ namespace WallpaperEngine::Logging {
  * Singleton class, simplifies logging for the whole app
  */
 class Log {
-  public:
+public:
     Log ();
 
     void addOutput (std::ostream* stream);
     void addError (std::ostream* stream);
 
     template <typename... Data> void out (Data... data) {
-        std::string str = this->buildBuffer (data...);
+	std::string str = this->buildBuffer (data...);
 
-        // then send it to all the outputs configured
-        for (const auto cur : this->mOutputs)
-            *cur << str << std::endl;
+	// then send it to all the outputs configured
+	for (const auto cur : this->mOutputs) {
+	    *cur << str << std::endl;
+	}
     }
 
     template <typename... Data> void debug (Data... data) {
 #if (!NDEBUG) && (!ERRORONLY)
-        std::string str = this->buildBuffer (data...);
+	std::string str = this->buildBuffer (data...);
 
-        // then send it to all the outputs configured
-        for (const auto cur : this->mOutputs)
-            *cur << str << std::endl;
+	// then send it to all the outputs configured
+	for (const auto cur : this->mOutputs) {
+	    *cur << str << std::endl;
+	}
 #endif /* DEBUG */
     }
 
     template <typename... Data> void debugerror (Data... data) {
 #if (!NDEBUG) && (ERRORONLY)
-        std::string str = this->buildBuffer (data...);
+	std::string str = this->buildBuffer (data...);
 
-        // then send it to all the outputs configured
-        for (const auto cur : this->mOutputs)
-            *cur << str << std::endl;
+	// then send it to all the outputs configured
+	for (const auto cur : this->mOutputs) {
+	    *cur << str << std::endl;
+	}
 #endif /* DEBUG */
     }
 
     template <typename... Data> void error (Data... data) {
-        std::string str = this->buildBuffer (data...);
+	std::string str = this->buildBuffer (data...);
 
-        // then send it to all the outputs configured
-        for (const auto cur : this->mErrors)
-            *cur << str << std::endl;
+	// then send it to all the outputs configured
+	for (const auto cur : this->mErrors) {
+	    *cur << str << std::endl;
+	}
     }
 
     template <class EX, typename... Data> [[noreturn]] void exception (Data... data) {
-        std::string str = this->buildBuffer (data...);
-        // then send it to all the outputs configured
-        for (const auto cur : this->mErrors)
-            *cur << str << std::endl;
-
-        // now throw the exception
-        throw EX (str);
+	std::string str = this->buildBuffer (data...);
+	// then send it to all the outputs configured
+	for (const auto cur : this->mErrors) {
+	    *cur << str << std::endl;
+	}
+
+	// now throw the exception
+	throw EX (str);
     }
 
     template <typename... Data> [[noreturn]] void exception (Data... data) {
-        this->exception<std::runtime_error> (data...);
+	this->exception<std::runtime_error> (data...);
     }
 
     static Log& get ();
 
-  private:
+private:
     template <typename... Data> std::string buildBuffer (Data... data) {
-        // buffer the string first
-        std::stringbuf buffer;
-        std::ostream bufferStream (&buffer);
+	// buffer the string first
+	std::stringbuf buffer;
+	std::ostream bufferStream (&buffer);
 
-        ((bufferStream << std::forward<Data> (data)), ...);
+	((bufferStream << std::forward<Data> (data)), ...);
 
-        return buffer.str ();
+	return buffer.str ();
     }
 
     std::vector<std::ostream*> mOutputs = {};

+ 37 - 66
src/WallpaperEngine/Render/CFBO.cpp

@@ -3,14 +3,12 @@
 
 using namespace WallpaperEngine::Render;
 
-CFBO::CFBO (std::string name, const TextureFormat format, const uint32_t flags, const float scale,
-            uint32_t realWidth, uint32_t realHeight, uint32_t textureWidth, uint32_t textureHeight) :
-    m_scale (scale),
-    m_name (std::move (name)),
-    m_format (format),
-    m_flags (flags) {
+CFBO::CFBO (
+    std::string name, const TextureFormat format, const uint32_t flags, const float scale, uint32_t realWidth,
+    uint32_t realHeight, uint32_t textureWidth, uint32_t textureHeight
+) : m_scale (scale), m_name (std::move (name)), m_format (format), m_flags (flags) {
     // create an empty texture that'll be free'd so the FBO is transparent
-    constexpr GLenum drawBuffers [1] = {GL_COLOR_ATTACHMENT0};
+    constexpr GLenum drawBuffers[1] = { GL_COLOR_ATTACHMENT0 };
     // create the main framebuffer
     glGenFramebuffers (1, &this->m_framebuffer);
     glBindFramebuffer (GL_FRAMEBUFFER, this->m_framebuffer);
@@ -26,22 +24,22 @@ CFBO::CFBO (std::string name, const TextureFormat format, const uint32_t flags,
 #endif /* DEBUG */
     // set filtering parameters, otherwise the texture is not rendered
     if (flags & TextureFlags_ClampUVs) {
-        glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
-        glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+	glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+	glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
     } else if (flags & TextureFlags_ClampUVsBorder) {
-        glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
-        glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
+	glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
+	glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
     } else {
-        glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
-        glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
+	glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+	glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
     }
 
     if (flags & TextureFlags_NoInterpolation) {
-        glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
-        glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+	glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+	glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
     } else {
-        glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
-        glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+	glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+	glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
     }
 
     glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY, 8.0f);
@@ -52,13 +50,14 @@ CFBO::CFBO (std::string name, const TextureFormat format, const uint32_t flags,
     glDrawBuffers (1, drawBuffers);
 
     // ensure first framebuffer is okay
-    if (glCheckFramebufferStatus (GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
-        sLog.exception ("Framebuffers are not properly set");
+    if (glCheckFramebufferStatus (GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
+	sLog.exception ("Framebuffers are not properly set");
+    }
 
     // clear the framebuffer
     glClear (GL_COLOR_BUFFER_BIT);
 
-    this->m_resolution = {textureWidth, textureHeight, realWidth, realHeight};
+    this->m_resolution = { textureWidth, textureHeight, realWidth, realHeight };
 
     // create the textureframe entries
     const auto frame = std::make_shared<Frame> ();
@@ -81,74 +80,46 @@ CFBO::~CFBO () {
     glDeleteFramebuffers (1, &this->m_framebuffer);
 }
 
-const std::string& CFBO::getName () const {
-    return this->m_name;
-}
+const std::string& CFBO::getName () const { return this->m_name; }
 
-const float& CFBO::getScale () const {
-    return this->m_scale;
-}
+const float& CFBO::getScale () const { return this->m_scale; }
 
-TextureFormat CFBO::getFormat () const {
-    return this->m_format;
-}
+TextureFormat CFBO::getFormat () const { return this->m_format; }
 
-uint32_t CFBO::getFlags () const {
-    return this->m_flags;
-}
+uint32_t CFBO::getFlags () const { return this->m_flags; }
 
-GLuint CFBO::getFramebuffer () const {
-    return this->m_framebuffer;
-}
+GLuint CFBO::getFramebuffer () const { return this->m_framebuffer; }
 
-GLuint CFBO::getDepthbuffer () const {
-    return this->m_depthbuffer;
-}
+GLuint CFBO::getDepthbuffer () const { return this->m_depthbuffer; }
 
-GLuint CFBO::getTextureID (uint32_t imageIndex) const {
-    return this->m_texture;
-}
+GLuint CFBO::getTextureID (uint32_t imageIndex) const { return this->m_texture; }
 
-uint32_t CFBO::getTextureWidth (uint32_t imageIndex) const {
-    return this->m_resolution.x;
-}
+uint32_t CFBO::getTextureWidth (uint32_t imageIndex) const { return this->m_resolution.x; }
 
-uint32_t CFBO::getTextureHeight (uint32_t imageIndex) const {
-    return this->m_resolution.y;
-}
+uint32_t CFBO::getTextureHeight (uint32_t imageIndex) const { return this->m_resolution.y; }
 
-uint32_t CFBO::getRealWidth () const {
-    return this->m_resolution.z;
-}
+uint32_t CFBO::getRealWidth () const { return this->m_resolution.z; }
 
-uint32_t CFBO::getRealHeight () const {
-    return this->m_resolution.w;
-}
+uint32_t CFBO::getRealHeight () const { return this->m_resolution.w; }
 
-const std::vector<FrameSharedPtr>& CFBO::getFrames () const {
-    return this->m_frames;
-}
+const std::vector<FrameSharedPtr>& CFBO::getFrames () const { return this->m_frames; }
 
-const glm::vec4* CFBO::getResolution () const {
-    return &this->m_resolution;
-}
+const glm::vec4* CFBO::getResolution () const { return &this->m_resolution; }
 
-bool CFBO::isAnimated () const {
-    return false;
-}
+bool CFBO::isAnimated () const { return false; }
 
 uint32_t CFBO::getSpritesheetCols () const {
-    return 0;  // FBOs don't have spritesheets
+    return 0; // FBOs don't have spritesheets
 }
 
 uint32_t CFBO::getSpritesheetRows () const {
-    return 0;  // FBOs don't have spritesheets
+    return 0; // FBOs don't have spritesheets
 }
 
 uint32_t CFBO::getSpritesheetFrames () const {
-    return 0;  // FBOs don't have spritesheets
+    return 0; // FBOs don't have spritesheets
 }
 
 float CFBO::getSpritesheetDuration () const {
-    return 0.0f;  // FBOs don't have spritesheets
+    return 0.0f; // FBOs don't have spritesheets
 }

+ 6 - 4
src/WallpaperEngine/Render/CFBO.h

@@ -8,9 +8,11 @@ using namespace WallpaperEngine::Render;
 
 namespace WallpaperEngine::Render {
 class CFBO final : public TextureProvider {
-  public:
-    CFBO (std::string name, const TextureFormat format, const uint32_t flags, const float scale,
-          uint32_t realWidth, uint32_t realHeight, uint32_t textureWidth, uint32_t textureHeight);
+public:
+    CFBO (
+	std::string name, const TextureFormat format, const uint32_t flags, const float scale, uint32_t realWidth,
+	uint32_t realHeight, uint32_t textureWidth, uint32_t textureHeight
+    );
     ~CFBO () override;
 
     [[nodiscard]] const std::string& getName () const;
@@ -32,7 +34,7 @@ class CFBO final : public TextureProvider {
     [[nodiscard]] uint32_t getSpritesheetFrames () const override;
     [[nodiscard]] float getSpritesheetDuration () const override;
 
-  private:
+private:
     GLuint m_framebuffer = GL_NONE;
     GLuint m_depthbuffer = GL_NONE;
     GLuint m_texture = GL_NONE;

+ 4 - 12
src/WallpaperEngine/Render/CObject.cpp

@@ -7,18 +7,10 @@ using namespace WallpaperEngine::Render;
 using namespace WallpaperEngine::Render::Wallpapers;
 
 CObject::CObject (Wallpapers::CScene& scene, const Object& object) :
-    Helpers::ContextAware (scene),
-    m_scene (scene),
-    m_object (object) {}
+    Helpers::ContextAware (scene), m_scene (scene), m_object (object) { }
 
-Wallpapers::CScene& CObject::getScene () const {
-    return this->m_scene;
-}
+Wallpapers::CScene& CObject::getScene () const { return this->m_scene; }
 
-const AssetLocator& CObject::getAssetLocator () const {
-    return this->getScene ().getAssetLocator ();
-}
+const AssetLocator& CObject::getAssetLocator () const { return this->getScene ().getAssetLocator (); }
 
-int CObject::getId () const {
-    return this->m_object.id;
-}
+int CObject::getId () const { return this->m_object.id; }

+ 12 - 14
src/WallpaperEngine/Render/CObject.h

@@ -12,26 +12,24 @@ class CScene;
 
 namespace WallpaperEngine::Render {
 class CObject : public Helpers::ContextAware {
-  public:
+public:
     template <class T> [[nodiscard]] const T* as () const {
-        if (is <T> ()) {
-            return static_cast <const T*> (this);
-        }
+	if (is<T> ()) {
+	    return static_cast<const T*> (this);
+	}
 
-        throw std::bad_cast ();
+	throw std::bad_cast ();
     }
 
     template <class T> [[nodiscard]] T* as () {
-        if (is <T> ()) {
-            return static_cast <T*> (this);
-        }
+	if (is<T> ()) {
+	    return static_cast<T*> (this);
+	}
 
-        throw std::bad_cast ();
+	throw std::bad_cast ();
     }
 
-    template <class T> [[nodiscard]] bool is () const {
-        return typeid (*this) == typeid(T);
-    }
+    template <class T> [[nodiscard]] bool is () const { return typeid (*this) == typeid (T); }
 
     virtual void render () = 0;
 
@@ -39,11 +37,11 @@ class CObject : public Helpers::ContextAware {
     [[nodiscard]] const AssetLocator& getAssetLocator () const;
     [[nodiscard]] int getId () const;
 
-  protected:
+protected:
     CObject (Wallpapers::CScene& scene, const Object& object);
     virtual ~CObject () override = default;
 
-  private:
+private:
     Wallpapers::CScene& m_scene;
     const Object& m_object;
 };

+ 120 - 145
src/WallpaperEngine/Render/CTexture.cpp

@@ -10,151 +10,143 @@
 
 using namespace WallpaperEngine::Render;
 
-CTexture::CTexture (TextureUniquePtr header) : m_header (std::move(header)) {
+CTexture::CTexture (TextureUniquePtr header) : m_header (std::move (header)) {
     // ensure the header is parsed
     this->setupResolution ();
-    const GLint internalFormat = this->setupInternalFormat();
+    const GLint internalFormat = this->setupInternalFormat ();
 
     // allocate texture ids list
-    this->m_textureID = new GLuint [this->m_header->imageCount];
+    this->m_textureID = new GLuint[this->m_header->imageCount];
     // ask opengl for the correct amount of textures
     glGenTextures (this->m_header->imageCount, this->m_textureID);
 
     for (const auto& [index, mipmaps] : this->m_header->images) {
-        this->setupOpenGLParameters (index);
-
-        int level = 0;
-
-        for (const auto& mipmap : mipmaps) {
-            stbi_uc* handle = nullptr;
-            const void* dataptr = mipmap->uncompressedData.get ();
-            int width = mipmap->width;
-            int height = mipmap->height;
-            const uint32_t bufferSize = mipmap->uncompressedSize;
-            GLenum textureFormat = GL_RGBA;
-
-            if (this->m_header->freeImageFormat != FIF_UNKNOWN) {
-                int fileChannels;
-
-                dataptr = handle = stbi_load_from_memory (
-                    reinterpret_cast <unsigned char*> (mipmap->uncompressedData.get ()),
-                    mipmap->uncompressedSize,
-                    &width,
-                    &height,
-                    &fileChannels,
-                    4);
-            } else {
-                if (this->m_header->format == TextureFormat_R8) {
-                    // red textures are 1-byte-per-pixel, so it's alignment has to be set manually
-                    glPixelStorei (GL_UNPACK_ALIGNMENT, 1);
-                    textureFormat = GL_RED;
-                } else if (this->m_header->format == TextureFormat_RG88) {
-                    textureFormat = GL_RG;
-                }
-            }
-
-            switch (internalFormat) {
-                case GL_RGBA8:
-                case GL_RG8:
-                case GL_R8:
-                    glTexImage2D (
-                        GL_TEXTURE_2D, level, internalFormat, width, height, 0, textureFormat,
-                        GL_UNSIGNED_BYTE, dataptr);
-                    break;
-                case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
-                case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
-                case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
-                    glCompressedTexImage2D (
-                        GL_TEXTURE_2D, level, internalFormat, width, height, 0, bufferSize,
-                        dataptr);
-                    break;
-                default: sLog.exception ("Cannot load texture, unknown format", this->m_header->format);
-            }
-
-            // stbi_image buffer won't be used anymore, so free memory
-            if (this->m_header->freeImageFormat != FIF_UNKNOWN) {
-                stbi_image_free (handle);
-            }
-
-            level ++;
-        }
+	this->setupOpenGLParameters (index);
+
+	int level = 0;
+
+	for (const auto& mipmap : mipmaps) {
+	    stbi_uc* handle = nullptr;
+	    const void* dataptr = mipmap->uncompressedData.get ();
+	    int width = mipmap->width;
+	    int height = mipmap->height;
+	    const uint32_t bufferSize = mipmap->uncompressedSize;
+	    GLenum textureFormat = GL_RGBA;
+
+	    if (this->m_header->freeImageFormat != FIF_UNKNOWN) {
+		int fileChannels;
+
+		dataptr = handle = stbi_load_from_memory (
+		    reinterpret_cast<unsigned char*> (mipmap->uncompressedData.get ()), mipmap->uncompressedSize,
+		    &width, &height, &fileChannels, 4
+		);
+	    } else {
+		if (this->m_header->format == TextureFormat_R8) {
+		    // red textures are 1-byte-per-pixel, so it's alignment has to be set manually
+		    glPixelStorei (GL_UNPACK_ALIGNMENT, 1);
+		    textureFormat = GL_RED;
+		} else if (this->m_header->format == TextureFormat_RG88) {
+		    textureFormat = GL_RG;
+		}
+	    }
+
+	    switch (internalFormat) {
+		case GL_RGBA8:
+		case GL_RG8:
+		case GL_R8:
+		    glTexImage2D (
+			GL_TEXTURE_2D, level, internalFormat, width, height, 0, textureFormat, GL_UNSIGNED_BYTE, dataptr
+		    );
+		    break;
+		case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
+		case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
+		case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
+		    glCompressedTexImage2D (
+			GL_TEXTURE_2D, level, internalFormat, width, height, 0, bufferSize, dataptr
+		    );
+		    break;
+		default:
+		    sLog.exception ("Cannot load texture, unknown format", this->m_header->format);
+	    }
+
+	    // stbi_image buffer won't be used anymore, so free memory
+	    if (this->m_header->freeImageFormat != FIF_UNKNOWN) {
+		stbi_image_free (handle);
+	    }
+
+	    level++;
+	}
     }
 }
 
 void CTexture::setupResolution () {
     if (this->isAnimated ()) {
-        this->m_resolution = {
-            this->m_header->textureWidth, this->m_header->textureHeight,
-            this->m_header->gifWidth, this->m_header->gifHeight
-        };
+	this->m_resolution = { this->m_header->textureWidth, this->m_header->textureHeight, this->m_header->gifWidth,
+			       this->m_header->gifHeight };
     } else {
-        if (this->m_header->freeImageFormat != FIF_UNKNOWN) {
-            // wpengine-texture format always has one mipmap
-            // get first image size
-            const auto element = this->m_header->images.find (0)->second.begin ();
-
-            // set the texture resolution
-            this->m_resolution = {
-                (*element)->width, (*element)->height,
-                this->m_header->width, this->m_header->height
-            };
-        } else {
-            // set the texture resolution
-            this->m_resolution = {
-                this->m_header->textureWidth, this->m_header->textureHeight,
-                this->m_header->width, this->m_header->height
-            };
-        }
+	if (this->m_header->freeImageFormat != FIF_UNKNOWN) {
+	    // wpengine-texture format always has one mipmap
+	    // get first image size
+	    const auto element = this->m_header->images.find (0)->second.begin ();
+
+	    // set the texture resolution
+	    this->m_resolution
+		= { (*element)->width, (*element)->height, this->m_header->width, this->m_header->height };
+	} else {
+	    // set the texture resolution
+	    this->m_resolution = { this->m_header->textureWidth, this->m_header->textureHeight, this->m_header->width,
+				   this->m_header->height };
+	}
     }
 }
 
 GLint CTexture::setupInternalFormat () const {
     if (this->m_header->freeImageFormat != FIF_UNKNOWN) {
-        return GL_RGBA8;
+	return GL_RGBA8;
     }
 
     // detect the image format and hand it to openGL to be used
     switch (this->m_header->format) {
-        case TextureFormat_DXT5:
-            return GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
-        case TextureFormat_DXT3:
-            return GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
-        case TextureFormat_DXT1:
-            return GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
-        case TextureFormat_ARGB8888:
-            return GL_RGBA8;
-        case TextureFormat_R8:
-            return GL_R8;
-        case TextureFormat_RG88:
-            return GL_RG8;
-        default:
-            sLog.exception ("Cannot determine texture format");
+	case TextureFormat_DXT5:
+	    return GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
+	case TextureFormat_DXT3:
+	    return GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
+	case TextureFormat_DXT1:
+	    return GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
+	case TextureFormat_ARGB8888:
+	    return GL_RGBA8;
+	case TextureFormat_R8:
+	    return GL_R8;
+	case TextureFormat_RG88:
+	    return GL_RG8;
+	default:
+	    sLog.exception ("Cannot determine texture format");
     }
 }
 
 void CTexture::setupOpenGLParameters (const uint32_t textureID) const {
     // bind the texture to assign information to it
-    glBindTexture (GL_TEXTURE_2D, this->m_textureID [textureID]);
+    glBindTexture (GL_TEXTURE_2D, this->m_textureID[textureID]);
 
     // set mipmap levels
     glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
-    glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, this->m_header->images [textureID].size () - 1);
+    glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, this->m_header->images[textureID].size () - 1);
 
     // setup texture wrapping and filtering
     if (this->m_header->flags & TextureFlags_ClampUVs) {
-        glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
-        glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+	glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+	glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
     } else {
-        glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
-        glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
+	glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+	glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
     }
 
     if (this->m_header->flags & TextureFlags_NoInterpolation) {
-        glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
-        glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
+	glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+	glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
     } else {
-        glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
-        glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
+	glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+	glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
     }
 
     glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY, 8.0f);
@@ -162,24 +154,27 @@ void CTexture::setupOpenGLParameters (const uint32_t textureID) const {
 
 GLuint CTexture::getTextureID (const uint32_t imageIndex) const {
     // ensure we do not go out of bounds
-    if (imageIndex >= this->m_header->imageCount)
-        return this->m_textureID [0];
+    if (imageIndex >= this->m_header->imageCount) {
+	return this->m_textureID[0];
+    }
 
-    return this->m_textureID [imageIndex];
+    return this->m_textureID[imageIndex];
 }
 
 uint32_t CTexture::getTextureWidth (const uint32_t imageIndex) const {
-    if (imageIndex >= this->m_header->imageCount)
-        return this->getHeader ().textureWidth;
+    if (imageIndex >= this->m_header->imageCount) {
+	return this->getHeader ().textureWidth;
+    }
 
-    return (*this->m_header->images [imageIndex].begin ())->width;
+    return (*this->m_header->images[imageIndex].begin ())->width;
 }
 
 uint32_t CTexture::getTextureHeight (const uint32_t imageIndex) const {
-    if (imageIndex >= this->m_header->imageCount)
-        return this->getHeader ().textureHeight;
+    if (imageIndex >= this->m_header->imageCount) {
+	return this->getHeader ().textureHeight;
+    }
 
-    return (*this->m_header->images [imageIndex].begin ())->height;
+    return (*this->m_header->images[imageIndex].begin ())->height;
 }
 
 uint32_t CTexture::getRealWidth () const {
@@ -190,42 +185,22 @@ uint32_t CTexture::getRealHeight () const {
     return this->isAnimated () ? this->getHeader ().gifHeight : this->getHeader ().height;
 }
 
-TextureFormat CTexture::getFormat () const {
-    return this->getHeader ().format;
-}
+TextureFormat CTexture::getFormat () const { return this->getHeader ().format; }
 
-uint32_t CTexture::getFlags () const {
-    return this->getHeader ().flags;
-}
+uint32_t CTexture::getFlags () const { return this->getHeader ().flags; }
 
-const Texture& CTexture::getHeader () const {
-    return *this->m_header;
-}
+const Texture& CTexture::getHeader () const { return *this->m_header; }
 
-const glm::vec4* CTexture::getResolution () const {
-    return &this->m_resolution;
-}
+const glm::vec4* CTexture::getResolution () const { return &this->m_resolution; }
 
-const std::vector<FrameSharedPtr>& CTexture::getFrames () const {
-    return this->getHeader ().frames;
-}
+const std::vector<FrameSharedPtr>& CTexture::getFrames () const { return this->getHeader ().frames; }
 
-bool CTexture::isAnimated () const {
-    return this->getHeader ().isAnimated ();
-}
+bool CTexture::isAnimated () const { return this->getHeader ().isAnimated (); }
 
-uint32_t CTexture::getSpritesheetCols () const {
-    return this->getHeader ().spritesheetCols;
-}
+uint32_t CTexture::getSpritesheetCols () const { return this->getHeader ().spritesheetCols; }
 
-uint32_t CTexture::getSpritesheetRows () const {
-    return this->getHeader ().spritesheetRows;
-}
+uint32_t CTexture::getSpritesheetRows () const { return this->getHeader ().spritesheetRows; }
 
-uint32_t CTexture::getSpritesheetFrames () const {
-    return this->getHeader ().spritesheetFrames;
-}
+uint32_t CTexture::getSpritesheetFrames () const { return this->getHeader ().spritesheetFrames; }
 
-float CTexture::getSpritesheetDuration () const {
-    return this->getHeader ().spritesheetDuration;
-}
+float CTexture::getSpritesheetDuration () const { return this->getHeader ().spritesheetDuration; }

+ 2 - 2
src/WallpaperEngine/Render/CTexture.h

@@ -15,7 +15,7 @@ using namespace WallpaperEngine::Data::Assets;
  * A normal texture file in WallpaperEngine's format
  */
 class CTexture final : public TextureProvider {
-  public:
+public:
     explicit CTexture (TextureUniquePtr header);
 
     [[nodiscard]] GLuint getTextureID (uint32_t imageIndex) const override;
@@ -33,7 +33,7 @@ class CTexture final : public TextureProvider {
     [[nodiscard]] uint32_t getSpritesheetFrames () const override;
     [[nodiscard]] float getSpritesheetDuration () const override;
 
-  private:
+private:
     /**
      * @return The texture header
      */

+ 82 - 98
src/WallpaperEngine/Render/CWallpaper.cpp

@@ -4,8 +4,8 @@
 #include "WallpaperEngine/Render/Wallpapers/CVideo.h"
 #include "WallpaperEngine/Render/Wallpapers/CWeb.h"
 
-#include "WallpaperEngine/Data/Model/Wallpaper.h"
 #include "WallpaperEngine/Data/Model/Project.h"
+#include "WallpaperEngine/Data/Model/Wallpaper.h"
 
 #include <glm/glm.hpp>
 #include <glm/gtc/type_ptr.hpp>
@@ -13,14 +13,10 @@
 using namespace WallpaperEngine::Render;
 
 CWallpaper::CWallpaper (
-    const Wallpaper& wallpaperData, RenderContext& context,AudioContext& audioContext,
-    const WallpaperState::TextureUVsScaling& scalingMode,
-    const uint32_t& clampMode
+    const Wallpaper& wallpaperData, RenderContext& context, AudioContext& audioContext,
+    const WallpaperState::TextureUVsScaling& scalingMode, const uint32_t& clampMode
 ) :
-    ContextAware (context),
-    FBOProvider (nullptr),
-    m_wallpaperData (wallpaperData),
-    m_audioContext (audioContext),
+    ContextAware (context), FBOProvider (nullptr), m_wallpaperData (wallpaperData), m_audioContext (audioContext),
     m_state (scalingMode, clampMode) {
     // generate the VAO to stop opengl from complaining
     glGenVertexArrays (1, &this->m_vaoBuffer);
@@ -28,11 +24,11 @@ CWallpaper::CWallpaper (
 
     this->setupShaders ();
 
-    constexpr GLfloat texCoords [] = {0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f};
+    constexpr GLfloat texCoords[] = { 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f };
 
     // inverted positions so the final texture is rendered properly
-    constexpr GLfloat position [] = {-1.0f, 1.0f,  0.0f, 1.0,  1.0f, 0.0f, -1.0f, -1.0f, 0.0f,
-                                     -1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f,  -1.0f, 0.0f};
+    constexpr GLfloat position[] = { -1.0f, 1.0f,  0.0f, 1.0,  1.0f, 0.0f, -1.0f, -1.0f, 0.0f,
+				     -1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f,  -1.0f, 0.0f };
 
     glGenBuffers (1, &this->m_texCoordBuffer);
     glBindBuffer (GL_ARRAY_BUFFER, this->m_texCoordBuffer);
@@ -45,21 +41,13 @@ CWallpaper::CWallpaper (
 
 CWallpaper::~CWallpaper () = default;
 
-const AssetLocator& CWallpaper::getAssetLocator () const {
-    return *this->m_wallpaperData.project.assetLocator;
-}
+const AssetLocator& CWallpaper::getAssetLocator () const { return *this->m_wallpaperData.project.assetLocator; }
 
-const Wallpaper& CWallpaper::getWallpaperData () const {
-    return this->m_wallpaperData;
-}
+const Wallpaper& CWallpaper::getWallpaperData () const { return this->m_wallpaperData; }
 
-GLuint CWallpaper::getWallpaperFramebuffer () const {
-    return this->m_sceneFBO->getFramebuffer ();
-}
+GLuint CWallpaper::getWallpaperFramebuffer () const { return this->m_sceneFBO->getFramebuffer (); }
 
-GLuint CWallpaper::getWallpaperTexture () const {
-    return this->m_sceneFBO->getTextureID (0);
-}
+GLuint CWallpaper::getWallpaperTexture () const { return this->m_sceneFBO->getTextureID (0); }
 
 void CWallpaper::setupShaders () {
     // reserve shaders in OpenGL
@@ -67,14 +55,14 @@ void CWallpaper::setupShaders () {
 
     // give shader's source code to OpenGL to be compiled
     const char* sourcePointer = "#version 330\n"
-                                "precision highp float;\n"
-                                "in vec3 a_Position;\n"
-                                "in vec2 a_TexCoord;\n"
-                                "out vec2 v_TexCoord;\n"
-                                "void main () {\n"
-                                "gl_Position = vec4 (a_Position, 1.0);\n"
-                                "v_TexCoord = a_TexCoord;\n"
-                                "}";
+				"precision highp float;\n"
+				"in vec3 a_Position;\n"
+				"in vec2 a_TexCoord;\n"
+				"out vec2 v_TexCoord;\n"
+				"void main () {\n"
+				"gl_Position = vec4 (a_Position, 1.0);\n"
+				"v_TexCoord = a_TexCoord;\n"
+				"}";
 
     glShaderSource (vertexShaderID, 1, &sourcePointer, nullptr);
     glCompileShader (vertexShaderID);
@@ -87,17 +75,17 @@ void CWallpaper::setupShaders () {
     glGetShaderiv (vertexShaderID, GL_INFO_LOG_LENGTH, &infoLogLength);
 
     if (infoLogLength > 0) {
-        const auto logBuffer = new char [infoLogLength + 1];
-        // ensure logBuffer ends with a \0
-        memset (logBuffer, 0, infoLogLength + 1);
-        // get information about the error
-        glGetShaderInfoLog (vertexShaderID, infoLogLength, nullptr, logBuffer);
-        // throw an exception about the issue
-        const std::string message = logBuffer;
-        // free the buffer
-        delete [] logBuffer;
-        // throw an exception
-        sLog.exception (message);
+	const auto logBuffer = new char[infoLogLength + 1];
+	// ensure logBuffer ends with a \0
+	memset (logBuffer, 0, infoLogLength + 1);
+	// get information about the error
+	glGetShaderInfoLog (vertexShaderID, infoLogLength, nullptr, logBuffer);
+	// throw an exception about the issue
+	const std::string message = logBuffer;
+	// free the buffer
+	delete[] logBuffer;
+	// throw an exception
+	sLog.exception (message);
     }
 
     // reserve shaders in OpenGL
@@ -105,13 +93,13 @@ void CWallpaper::setupShaders () {
 
     // give shader's source code to OpenGL to be compiled
     sourcePointer = "#version 330\n"
-                    "precision highp float;\n"
-                    "uniform sampler2D g_Texture0;\n"
-                    "in vec2 v_TexCoord;\n"
-                    "out vec4 out_FragColor;\n"
-                    "void main () {\n"
-                    "out_FragColor = texture (g_Texture0, v_TexCoord);\n"
-                    "}";
+		    "precision highp float;\n"
+		    "uniform sampler2D g_Texture0;\n"
+		    "in vec2 v_TexCoord;\n"
+		    "out vec4 out_FragColor;\n"
+		    "void main () {\n"
+		    "out_FragColor = texture (g_Texture0, v_TexCoord);\n"
+		    "}";
 
     glShaderSource (fragmentShaderID, 1, &sourcePointer, nullptr);
     glCompileShader (fragmentShaderID);
@@ -124,17 +112,17 @@ void CWallpaper::setupShaders () {
     glGetShaderiv (fragmentShaderID, GL_INFO_LOG_LENGTH, &infoLogLength);
 
     if (infoLogLength > 0) {
-        const auto logBuffer = new char [infoLogLength + 1];
-        // ensure logBuffer ends with a \0
-        memset (logBuffer, 0, infoLogLength + 1);
-        // get information about the error
-        glGetShaderInfoLog (fragmentShaderID, infoLogLength, nullptr, logBuffer);
-        // throw an exception about the issue
-        const std::string message = logBuffer;
-        // free the buffer
-        delete [] logBuffer;
-        // throw an exception
-        sLog.exception (message);
+	const auto logBuffer = new char[infoLogLength + 1];
+	// ensure logBuffer ends with a \0
+	memset (logBuffer, 0, infoLogLength + 1);
+	// get information about the error
+	glGetShaderInfoLog (fragmentShaderID, infoLogLength, nullptr, logBuffer);
+	// throw an exception about the issue
+	const std::string message = logBuffer;
+	// free the buffer
+	delete[] logBuffer;
+	// throw an exception
+	sLog.exception (message);
     }
 
     // create the final program
@@ -151,17 +139,17 @@ void CWallpaper::setupShaders () {
     glGetProgramiv (this->m_shader, GL_INFO_LOG_LENGTH, &infoLogLength);
 
     if (infoLogLength > 0) {
-        const auto logBuffer = new char [infoLogLength + 1];
-        // ensure logBuffer ends with a \0
-        memset (logBuffer, 0, infoLogLength + 1);
-        // get information about the error
-        glGetProgramInfoLog (this->m_shader, infoLogLength, nullptr, logBuffer);
-        // throw an exception about the issue
-        const std::string message = logBuffer;
-        // free the buffer
-        delete [] logBuffer;
-        // throw an exception
-        sLog.exception (message);
+	const auto logBuffer = new char[infoLogLength + 1];
+	// ensure logBuffer ends with a \0
+	memset (logBuffer, 0, infoLogLength + 1);
+	// get information about the error
+	glGetProgramInfoLog (this->m_shader, infoLogLength, nullptr, logBuffer);
+	// throw an exception about the issue
+	const std::string message = logBuffer;
+	// free the buffer
+	delete[] logBuffer;
+	// throw an exception
+	sLog.exception (message);
     }
 
     // after being liked shaders can be dettached and deleted
@@ -177,15 +165,13 @@ void CWallpaper::setupShaders () {
     this->a_TexCoord = glGetAttribLocation (this->m_shader, "a_TexCoord");
 }
 
-void CWallpaper::setDestinationFramebuffer (GLuint framebuffer) {
-    this->m_destFramebuffer = framebuffer;
-}
+void CWallpaper::setDestinationFramebuffer (GLuint framebuffer) { this->m_destFramebuffer = framebuffer; }
 
 void CWallpaper::updateUVs (const glm::ivec4& viewport, const bool vflip) {
     // update UVs if something has changed, otherwise use old values
     if (this->m_state.hasChanged (viewport, vflip, this->getWidth (), this->getHeight ())) {
-        // Update wallpaper state
-        this->m_state.updateState (viewport, vflip, this->getWidth (), this->getHeight ());
+	// Update wallpaper state
+	this->m_state.updateState (viewport, vflip, this->getWidth (), this->getHeight ());
     }
 }
 
@@ -202,8 +188,8 @@ void CWallpaper::render (const glm::ivec4& viewport, const bool vflip) {
     updateUVs (viewport, vflip);
     auto [ustart, uend, vstart, vend] = this->m_state.getTextureUVs ();
 
-    const GLfloat texCoords [] = {
-        ustart, vstart, uend, vstart, ustart, vend, ustart, vend, uend, vstart, uend, vend,
+    const GLfloat texCoords[] = {
+	ustart, vstart, uend, vstart, ustart, vend, ustart, vend, uend, vstart, uend, vend,
     };
 
     glViewport (viewport.x, viewport.y, viewport.z, viewport.w);
@@ -240,7 +226,7 @@ void CWallpaper::render (const glm::ivec4& viewport, const bool vflip) {
 #endif /* !NDEBUG */
 }
 
-void CWallpaper::setPause (bool newState) {}
+void CWallpaper::setPause (bool newState) { }
 
 void CWallpaper::setupFramebuffers () {
     const uint32_t width = this->getWidth ();
@@ -249,32 +235,27 @@ void CWallpaper::setupFramebuffers () {
 
     // create framebuffer for the scene
     this->m_sceneFBO = this->create (
-        "_rt_FullFrameBuffer", TextureFormat_ARGB8888, clamp, 1.0, {width,
-        height}, {width, height});
+	"_rt_FullFrameBuffer", TextureFormat_ARGB8888, clamp, 1.0, { width, height }, { width, height }
+    );
 
     this->alias ("_rt_MipMappedFrameBuffer", "_rt_FullFrameBuffer");
 }
 
-AudioContext& CWallpaper::getAudioContext () const {
-    return this->m_audioContext;
-}
+AudioContext& CWallpaper::getAudioContext () const { return this->m_audioContext; }
 
-const WallpaperState& CWallpaper::getState () const {
-    return this->m_state;
-}
+const WallpaperState& CWallpaper::getState () const { return this->m_state; }
 
 std::shared_ptr<const CFBO> CWallpaper::findFBO (const std::string& name) const {
     const auto fbo = this->find (name);
 
-    if (fbo == nullptr)
-        sLog.exception ("Cannot find FBO ", name);
+    if (fbo == nullptr) {
+	sLog.exception ("Cannot find FBO ", name);
+    }
 
     return fbo;
 }
 
-std::shared_ptr<const CFBO> CWallpaper::getFBO () const {
-    return this->m_sceneFBO;
-}
+std::shared_ptr<const CFBO> CWallpaper::getFBO () const { return this->m_sceneFBO; }
 
 std::unique_ptr<CWallpaper> CWallpaper::fromWallpaper (
     const Wallpaper& wallpaper, RenderContext& context, AudioContext& audioContext,
@@ -282,18 +263,21 @@ std::unique_ptr<CWallpaper> CWallpaper::fromWallpaper (
     const uint32_t& clampMode
 ) {
     if (wallpaper.is<Scene> ()) {
-        return std::make_unique <WallpaperEngine::Render::Wallpapers::CScene> (
-            wallpaper, context, audioContext, scalingMode, clampMode);
+	return std::make_unique<WallpaperEngine::Render::Wallpapers::CScene> (
+	    wallpaper, context, audioContext, scalingMode, clampMode
+	);
     }
 
     if (wallpaper.is<Video> ()) {
-        return std::make_unique<WallpaperEngine::Render::Wallpapers::CVideo> (
-            wallpaper, context, audioContext, scalingMode, clampMode);
+	return std::make_unique<WallpaperEngine::Render::Wallpapers::CVideo> (
+	    wallpaper, context, audioContext, scalingMode, clampMode
+	);
     }
 
     if (wallpaper.is<Web> ()) {
-        return std::make_unique<WallpaperEngine::Render::Wallpapers::CWeb> (
-            wallpaper, context, audioContext, *browserContext, scalingMode, clampMode);
+	return std::make_unique<WallpaperEngine::Render::Wallpapers::CWeb> (
+	    wallpaper, context, audioContext, *browserContext, scalingMode, clampMode
+	);
     }
 
     sLog.exception ("Unsupported wallpaper type");

Някои файлове не бяха показани, защото твърде много файлове са промени