mirror of
https://github.com/Almamu/linux-wallpaperengine.git
synced 2025-09-14 13:56:48 +08:00
Compare commits
4 Commits
ac1a7ae4f9
...
73f716da84
Author | SHA1 | Date | |
---|---|---|---|
![]() |
73f716da84 | ||
![]() |
be0fc25e72 | ||
![]() |
3c334aac29 | ||
![]() |
555b488951 |
@ -1,31 +0,0 @@
|
|||||||
---
|
|
||||||
name: Background doesn't load properly
|
|
||||||
about: Use this to report backgrounds that are not loading (cannot find files, black
|
|
||||||
image, effects not working, etc)
|
|
||||||
title: "[BGFIX]"
|
|
||||||
labels: bug
|
|
||||||
assignees: Almamu
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
**Wallpaper Engine Background(s)**
|
|
||||||
|
|
||||||
Link(s) to the background(s) in the steam workshop or their background ID(s).
|
|
||||||
|
|
||||||
**Console output**
|
|
||||||
|
|
||||||
When a background cannot be loaded, it's usually due to some unexpected error that is logged into the terminal. Please attach the program's output so we can properly debug it if needed.
|
|
||||||
|
|
||||||
**Screenshots**
|
|
||||||
|
|
||||||
If you have any screenshot of it working on Windows that'll help so we can compare both outputs
|
|
||||||
|
|
||||||
**Desktop (please complete the following information):**
|
|
||||||
|
|
||||||
- OS: [e.g. Arch Linux]
|
|
||||||
- Desktop Environment: [e.g. GNOME, CINNAMON, KDE...]
|
|
||||||
- Window Manager: [if in doubt, just leave it empty]
|
|
||||||
|
|
||||||
**Additional context**
|
|
||||||
|
|
||||||
Any additional information about your setup
|
|
58
.github/ISSUE_TEMPLATE/bug-report.yml
vendored
Normal file
58
.github/ISSUE_TEMPLATE/bug-report.yml
vendored
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
name: "Bug Report"
|
||||||
|
description: "Report a bug or unexpected behavior."
|
||||||
|
labels: [bug]
|
||||||
|
body:
|
||||||
|
- type: markdown
|
||||||
|
attributes:
|
||||||
|
value: |
|
||||||
|
Please fill out this form to report a bug.
|
||||||
|
- type: input
|
||||||
|
id: summary
|
||||||
|
attributes:
|
||||||
|
label: Bug Summary
|
||||||
|
description: Briefly describe the bug.
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: textarea
|
||||||
|
id: steps
|
||||||
|
attributes:
|
||||||
|
label: Steps to Reproduce
|
||||||
|
description: Step-by-step instructions to reproduce the bug.
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: textarea
|
||||||
|
id: expected
|
||||||
|
attributes:
|
||||||
|
label: Expected Behavior
|
||||||
|
validations:
|
||||||
|
required: false
|
||||||
|
- type: textarea
|
||||||
|
id: actual
|
||||||
|
attributes:
|
||||||
|
label: Actual Behavior / Logs
|
||||||
|
validations:
|
||||||
|
required: false
|
||||||
|
- type: input
|
||||||
|
id: os
|
||||||
|
attributes:
|
||||||
|
label: Operating System and Version
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: input
|
||||||
|
id: de
|
||||||
|
attributes:
|
||||||
|
label: Desktop Environment (GNOME, KDE, etc.)
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: input
|
||||||
|
id: x11_wayland
|
||||||
|
attributes:
|
||||||
|
label: Display Server (X11/Wayland)
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: textarea
|
||||||
|
id: extra
|
||||||
|
attributes:
|
||||||
|
label: Additional Context or Screenshots
|
||||||
|
validations:
|
||||||
|
required: false
|
46
.github/ISSUE_TEMPLATE/compatibility-issue.yml
vendored
Normal file
46
.github/ISSUE_TEMPLATE/compatibility-issue.yml
vendored
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
name: "Wallpaper Compatibility Issue"
|
||||||
|
description: "Report a problem with a specific Wallpaper Engine wallpaper."
|
||||||
|
labels: [compatibility, wallpaper]
|
||||||
|
body:
|
||||||
|
- type: input
|
||||||
|
id: wallpaper
|
||||||
|
attributes:
|
||||||
|
label: Wallpaper Name, URL or ID
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: textarea
|
||||||
|
id: issue
|
||||||
|
attributes:
|
||||||
|
label: Describe the Issue
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: textarea
|
||||||
|
id: expected
|
||||||
|
attributes:
|
||||||
|
label: Expected Behavior
|
||||||
|
validations:
|
||||||
|
required: false
|
||||||
|
- type: textarea
|
||||||
|
id: logs
|
||||||
|
attributes:
|
||||||
|
label: Logs or Crash Output
|
||||||
|
validations:
|
||||||
|
required: false
|
||||||
|
- type: input
|
||||||
|
id: os
|
||||||
|
attributes:
|
||||||
|
label: Operating System and Version
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: input
|
||||||
|
id: de
|
||||||
|
attributes:
|
||||||
|
label: Desktop Environment (GNOME, KDE, etc.)
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: input
|
||||||
|
id: x11_wayland
|
||||||
|
attributes:
|
||||||
|
label: Display Server (X11/Wayland)
|
||||||
|
validations:
|
||||||
|
required: true
|
32
.github/ISSUE_TEMPLATE/feature-request.yml
vendored
Normal file
32
.github/ISSUE_TEMPLATE/feature-request.yml
vendored
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
name: "Feature Request"
|
||||||
|
description: "Propose a new feature or enhancement."
|
||||||
|
labels: [enhancement]
|
||||||
|
body:
|
||||||
|
- type: markdown
|
||||||
|
attributes:
|
||||||
|
value: |
|
||||||
|
Use this form to suggest new features or improvements.
|
||||||
|
- type: textarea
|
||||||
|
id: feature
|
||||||
|
attributes:
|
||||||
|
label: Describe the Feature
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: textarea
|
||||||
|
id: problem
|
||||||
|
attributes:
|
||||||
|
label: Problem this Feature Addresses (if any)
|
||||||
|
validations:
|
||||||
|
required: false
|
||||||
|
- type: textarea
|
||||||
|
id: alternatives
|
||||||
|
attributes:
|
||||||
|
label: Alternatives Considered
|
||||||
|
validations:
|
||||||
|
required: false
|
||||||
|
- type: textarea
|
||||||
|
id: context
|
||||||
|
attributes:
|
||||||
|
label: Additional Context or Mockups
|
||||||
|
validations:
|
||||||
|
required: false
|
38
.github/ISSUE_TEMPLATE/installation-help.yml
vendored
Normal file
38
.github/ISSUE_TEMPLATE/installation-help.yml
vendored
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
name: "Installation/Usage Help"
|
||||||
|
description: "Request help with installing or using linux-wallpaperengine."
|
||||||
|
labels: [question, support]
|
||||||
|
body:
|
||||||
|
- type: markdown
|
||||||
|
attributes:
|
||||||
|
value: |
|
||||||
|
Need help? Fill this out so we can assist you better.
|
||||||
|
- type: textarea
|
||||||
|
id: issue
|
||||||
|
attributes:
|
||||||
|
label: What are you trying to do, and what's the problem?
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: textarea
|
||||||
|
id: attempted
|
||||||
|
attributes:
|
||||||
|
label: What have you tried so far?
|
||||||
|
validations:
|
||||||
|
required: false
|
||||||
|
- type: textarea
|
||||||
|
id: error_logs
|
||||||
|
attributes:
|
||||||
|
label: Errors or Log Output
|
||||||
|
validations:
|
||||||
|
required: false
|
||||||
|
- type: input
|
||||||
|
id: system
|
||||||
|
attributes:
|
||||||
|
label: OS, Desktop Environment, X11/Wayland
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: input
|
||||||
|
id: install_method
|
||||||
|
attributes:
|
||||||
|
label: Installation Method (e.g., AUR, Flatpak, build from source)
|
||||||
|
validations:
|
||||||
|
required: true
|
10
.github/ISSUE_TEMPLATE/other-issues.md
vendored
10
.github/ISSUE_TEMPLATE/other-issues.md
vendored
@ -1,10 +0,0 @@
|
|||||||
---
|
|
||||||
name: Other issues
|
|
||||||
about: Use this to report general issues with the software
|
|
||||||
title: ''
|
|
||||||
labels: ''
|
|
||||||
assignees: Almamu
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
|
|
22
.github/ISSUE_TEMPLATE/refactor.yml
vendored
Normal file
22
.github/ISSUE_TEMPLATE/refactor.yml
vendored
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
name: "Code Cleanup / Refactor"
|
||||||
|
description: "Suggest internal improvements like refactoring or technical debt cleanup."
|
||||||
|
labels: [refactor, maintenance]
|
||||||
|
body:
|
||||||
|
- type: textarea
|
||||||
|
id: what
|
||||||
|
attributes:
|
||||||
|
label: What needs improvement?
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: textarea
|
||||||
|
id: why
|
||||||
|
attributes:
|
||||||
|
label: Why is this necessary or beneficial?
|
||||||
|
validations:
|
||||||
|
required: false
|
||||||
|
- type: textarea
|
||||||
|
id: impact
|
||||||
|
attributes:
|
||||||
|
label: Potential Impact on Users
|
||||||
|
validations:
|
||||||
|
required: false
|
@ -198,7 +198,8 @@ if(X11_SUPPORT_FOUND)
|
|||||||
src/WallpaperEngine/Render/Drivers/Output/CX11Output.cpp
|
src/WallpaperEngine/Render/Drivers/Output/CX11Output.cpp
|
||||||
src/WallpaperEngine/Render/Drivers/Output/CX11Output.h
|
src/WallpaperEngine/Render/Drivers/Output/CX11Output.h
|
||||||
src/WallpaperEngine/Render/Drivers/Detectors/CX11FullScreenDetector.cpp
|
src/WallpaperEngine/Render/Drivers/Detectors/CX11FullScreenDetector.cpp
|
||||||
src/WallpaperEngine/Render/Drivers/Detectors/CX11FullScreenDetector.h)
|
src/WallpaperEngine/Render/Drivers/Detectors/CX11FullScreenDetector.h
|
||||||
|
src/WallpaperEngine/Data/Model/UserSetting.h)
|
||||||
SET(X11_INCLUDES
|
SET(X11_INCLUDES
|
||||||
${X11_INCLUDE_DIR}
|
${X11_INCLUDE_DIR}
|
||||||
${XRANDR_INCLUDE_DIR})
|
${XRANDR_INCLUDE_DIR})
|
||||||
@ -510,9 +511,41 @@ add_executable(
|
|||||||
src/WallpaperEngine/Core/Objects/Images/Materials/CPass.cpp
|
src/WallpaperEngine/Core/Objects/Images/Materials/CPass.cpp
|
||||||
src/WallpaperEngine/Core/Objects/Images/Materials/CPass.h
|
src/WallpaperEngine/Core/Objects/Images/Materials/CPass.h
|
||||||
|
|
||||||
|
src/WallpaperEngine/Data/Model/Types.h
|
||||||
|
src/WallpaperEngine/Data/Model/Project.h
|
||||||
|
src/WallpaperEngine/Data/Model/Wallpaper.h
|
||||||
|
src/WallpaperEngine/Data/Model/Object.h
|
||||||
|
src/WallpaperEngine/Data/Model/Material.h
|
||||||
|
src/WallpaperEngine/Data/Model/Effect.h
|
||||||
|
src/WallpaperEngine/Data/Model/Model.h
|
||||||
|
src/WallpaperEngine/Data/Utils/TypeCaster.cpp
|
||||||
|
src/WallpaperEngine/Data/Utils/TypeCaster.h
|
||||||
|
src/WallpaperEngine/Data/Parsers/ProjectParser.cpp
|
||||||
|
src/WallpaperEngine/Data/Parsers/ProjectParser.h
|
||||||
|
src/WallpaperEngine/Data/Parsers/WallpaperParser.cpp
|
||||||
|
src/WallpaperEngine/Data/Parsers/WallpaperParser.h
|
||||||
|
src/WallpaperEngine/Data/Parsers/UserSettingParser.cpp
|
||||||
|
src/WallpaperEngine/Data/Parsers/UserSettingParser.h
|
||||||
|
src/WallpaperEngine/Data/Parsers/ObjectParser.cpp
|
||||||
|
src/WallpaperEngine/Data/Parsers/ObjectParser.h
|
||||||
|
src/WallpaperEngine/Data/Parsers/MaterialParser.cpp
|
||||||
|
src/WallpaperEngine/Data/Parsers/MaterialParser.h
|
||||||
|
src/WallpaperEngine/Data/Parsers/ModelParser.cpp
|
||||||
|
src/WallpaperEngine/Data/Parsers/ModelParser.h
|
||||||
|
src/WallpaperEngine/Data/Parsers/ShaderConstantParser.cpp
|
||||||
|
src/WallpaperEngine/Data/Parsers/ShaderConstantParser.h
|
||||||
|
src/WallpaperEngine/Data/Builders/UserSettingBuilder.h
|
||||||
|
src/WallpaperEngine/Data/Builders/VectorBuilder.cpp
|
||||||
|
src/WallpaperEngine/Data/Builders/VectorBuilder.h
|
||||||
|
|
||||||
${WAYLAND_SOURCES}
|
${WAYLAND_SOURCES}
|
||||||
${X11_SOURCES}
|
${X11_SOURCES}
|
||||||
${DEMOMODE_SOURCES})
|
${DEMOMODE_SOURCES}
|
||||||
|
src/WallpaperEngine/Data/Dumpers/StringPrinter.cpp
|
||||||
|
src/WallpaperEngine/Data/Dumpers/StringPrinter.h
|
||||||
|
src/WallpaperEngine/Data/JSON.cpp
|
||||||
|
src/WallpaperEngine/Data/Parsers/EffectParser.cpp
|
||||||
|
src/WallpaperEngine/Data/Parsers/EffectParser.h)
|
||||||
|
|
||||||
target_link_libraries (linux-wallpaperengine PUBLIC
|
target_link_libraries (linux-wallpaperengine PUBLIC
|
||||||
${OPENGL_LIBRARIES}
|
${OPENGL_LIBRARIES}
|
||||||
|
@ -26,8 +26,11 @@ CApplicationContext::CApplicationContext (int argc, char* argv []) :
|
|||||||
|
|
||||||
backgroundGroup.add_argument ("background id")
|
backgroundGroup.add_argument ("background id")
|
||||||
.help ("The background to use as default for screens with no background specified")
|
.help ("The background to use as default for screens with no background specified")
|
||||||
|
.default_value ("")
|
||||||
.action([this](const std::string& value) -> void {
|
.action([this](const std::string& value) -> void {
|
||||||
|
if (!value.empty()) {
|
||||||
this->settings.general.defaultBackground = translateBackground (value);
|
this->settings.general.defaultBackground = translateBackground (value);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
backgroundMode.add_argument ("-w", "--window")
|
backgroundMode.add_argument ("-w", "--window")
|
||||||
@ -252,8 +255,13 @@ CApplicationContext::CApplicationContext (int argc, char* argv []) :
|
|||||||
" Runs the background 2317494988 on two screens, one on HDMI-1 and the other on HDMI-2\n\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 (argc, argv);
|
program.parse_known_args (argc, argv);
|
||||||
|
|
||||||
|
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.audio.volume = std::max(0, std::min (this->settings.audio.volume, 128));
|
||||||
this->settings.screenshot.delay = std::max (0, std::min (this->settings.screenshot.delay, 5));
|
this->settings.screenshot.delay = std::max (0, std::min (this->settings.screenshot.delay, 5));
|
||||||
|
|
||||||
@ -286,6 +294,9 @@ CApplicationContext::CApplicationContext (int argc, char* argv []) :
|
|||||||
this->settings.screenshot.take = false;
|
this->settings.screenshot.take = false;
|
||||||
this->settings.render.pauseOnFullscreen = false;
|
this->settings.render.pauseOnFullscreen = false;
|
||||||
#endif /* DEMOMODE */
|
#endif /* DEMOMODE */
|
||||||
|
} catch (const std::runtime_error& e) {
|
||||||
|
throw std::runtime_error (std::string (e.what()) + ". Use " + std::string (argv[0]) + " --help for more information");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int CApplicationContext::getArgc () const {
|
int CApplicationContext::getArgc () const {
|
||||||
|
@ -12,6 +12,9 @@
|
|||||||
#include "WallpaperEngine/Core/Wallpapers/CWeb.h"
|
#include "WallpaperEngine/Core/Wallpapers/CWeb.h"
|
||||||
#include "WallpaperEngine/Render/Drivers/CVideoFactories.h"
|
#include "WallpaperEngine/Render/Drivers/CVideoFactories.h"
|
||||||
|
|
||||||
|
#include "WallpaperEngine/Data/Parsers/ProjectParser.h"
|
||||||
|
#include "WallpaperEngine/Data/Dumpers/StringPrinter.h"
|
||||||
|
|
||||||
#if DEMOMODE
|
#if DEMOMODE
|
||||||
#include "recording.h"
|
#include "recording.h"
|
||||||
#endif /* DEMOMODE */
|
#endif /* DEMOMODE */
|
||||||
@ -37,18 +40,18 @@ CWallpaperApplication::CWallpaperApplication (CApplicationContext& context) :
|
|||||||
void CWallpaperApplication::setupContainer (const std::shared_ptr<CCombinedContainer>& container, const std::string& bg) const {
|
void CWallpaperApplication::setupContainer (const std::shared_ptr<CCombinedContainer>& container, const std::string& bg) const {
|
||||||
const std::filesystem::path basepath = bg;
|
const std::filesystem::path basepath = bg;
|
||||||
|
|
||||||
container->add (std::make_shared<CDirectory> (basepath));
|
container->add (std::make_unique<CDirectory> (basepath));
|
||||||
container->addPkg (basepath / "scene.pkg");
|
container->addPkg (basepath / "scene.pkg");
|
||||||
container->addPkg (basepath / "gifscene.pkg");
|
container->addPkg (basepath / "gifscene.pkg");
|
||||||
|
|
||||||
try {
|
try {
|
||||||
container->add (std::make_shared <CDirectory> (this->m_context.settings.general.assets));
|
container->add (std::make_unique <CDirectory> (this->m_context.settings.general.assets));
|
||||||
} catch (CAssetLoadException&) {
|
} catch (CAssetLoadException&) {
|
||||||
sLog.exception ("Cannot find a valid assets folder, resolved to ", this->m_context.settings.general.assets);
|
sLog.exception ("Cannot find a valid assets folder, resolved to ", this->m_context.settings.general.assets);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: move this somewhere else?
|
// TODO: move this somewhere else?
|
||||||
auto virtualContainer = std::make_shared <CVirtualContainer> ();
|
auto virtualContainer = std::make_unique <CVirtualContainer> ();
|
||||||
|
|
||||||
//
|
//
|
||||||
// Had to get a little creative with the effects to achieve the same bloom effect without any custom code
|
// Had to get a little creative with the effects to achieve the same bloom effect without any custom code
|
||||||
@ -181,7 +184,7 @@ void CWallpaperApplication::setupContainer (const std::shared_ptr<CCombinedConta
|
|||||||
"}"
|
"}"
|
||||||
);
|
);
|
||||||
|
|
||||||
container->add (virtualContainer);
|
container->add (std::move(virtualContainer));
|
||||||
}
|
}
|
||||||
|
|
||||||
void CWallpaperApplication::loadBackgrounds () {
|
void CWallpaperApplication::loadBackgrounds () {
|
||||||
@ -206,6 +209,16 @@ std::shared_ptr<Core::CProject> CWallpaperApplication::loadBackground (const std
|
|||||||
|
|
||||||
this->setupContainer (container, bg);
|
this->setupContainer (container, bg);
|
||||||
|
|
||||||
|
// do the parsing with the new parser first
|
||||||
|
auto json = WallpaperEngine::Data::JSON::JSON::parse (container->readFileAsString ("project.json"));
|
||||||
|
const auto project = WallpaperEngine::Data::Parsers::ProjectParser::parse (json, container);
|
||||||
|
|
||||||
|
auto dumper = WallpaperEngine::Data::Dumpers::StringPrinter ();
|
||||||
|
|
||||||
|
dumper.printWallpaper (*project->wallpaper);
|
||||||
|
|
||||||
|
std::cout << dumper.str () << std::endl;
|
||||||
|
|
||||||
return Core::CProject::fromFile ("project.json", container);
|
return Core::CProject::fromFile ("project.json", container);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,14 +8,14 @@ using namespace WallpaperEngine::Assets;
|
|||||||
|
|
||||||
CCombinedContainer::CCombinedContainer () : CContainer () {}
|
CCombinedContainer::CCombinedContainer () : CContainer () {}
|
||||||
|
|
||||||
void CCombinedContainer::add (const std::shared_ptr<CContainer>& container) {
|
void CCombinedContainer::add (std::unique_ptr<CContainer> container) {
|
||||||
this->m_containers.emplace_back (container);
|
this->m_containers.emplace_back (std::move(container));
|
||||||
}
|
}
|
||||||
|
|
||||||
void CCombinedContainer::addPkg (const std::filesystem::path& path) {
|
void CCombinedContainer::addPkg (const std::filesystem::path& path) {
|
||||||
try {
|
try {
|
||||||
// add the package to the list
|
// add the package to the list
|
||||||
this->add (std::make_shared<CPackage> (path));
|
this->add (std::make_unique<CPackage> (path));
|
||||||
sLog.out ("Detected ", path.filename (), " file at ", path, ". Adding to list of searchable paths");
|
sLog.out ("Detected ", path.filename (), " file at ", path, ". Adding to list of searchable paths");
|
||||||
} catch (CPackageLoadException&) {
|
} catch (CPackageLoadException&) {
|
||||||
// ignore this error, the package file was not found
|
// ignore this error, the package file was not found
|
||||||
|
@ -19,7 +19,7 @@ class CCombinedContainer final : public CContainer {
|
|||||||
*
|
*
|
||||||
* @param container
|
* @param container
|
||||||
*/
|
*/
|
||||||
void add (const std::shared_ptr<CContainer>& container);
|
void add (std::unique_ptr<CContainer> container);
|
||||||
/**
|
/**
|
||||||
* Adds the given package to the list
|
* Adds the given package to the list
|
||||||
*
|
*
|
||||||
@ -32,6 +32,6 @@ class CCombinedContainer final : public CContainer {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
/** The list of containers to search files off from */
|
/** The list of containers to search files off from */
|
||||||
std::vector<std::shared_ptr<CContainer>> m_containers {};
|
std::vector<std::unique_ptr<CContainer>> m_containers {};
|
||||||
};
|
};
|
||||||
}; // namespace WallpaperEngine::Assets
|
}; // namespace WallpaperEngine::Assets
|
@ -6,6 +6,7 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
namespace WallpaperEngine::Assets {
|
namespace WallpaperEngine::Assets {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* File container, provides access to files for backgrounds
|
* File container, provides access to files for backgrounds
|
||||||
*/
|
*/
|
||||||
|
@ -509,7 +509,7 @@ template <typename T> const T* Core::jsonFindUserConfig (
|
|||||||
if (it == data->end () || it->type () == nlohmann::detail::value_t::null)
|
if (it == data->end () || it->type () == nlohmann::detail::value_t::null)
|
||||||
return T::fromScalar (defaultValue);
|
return T::fromScalar (defaultValue);
|
||||||
|
|
||||||
return T::fromJSON (*it, project);
|
return T::fromJSON (*it, project.getProperties ());
|
||||||
}
|
}
|
||||||
|
|
||||||
template const CUserSettingBoolean* Core::jsonFindUserConfig (
|
template const CUserSettingBoolean* Core::jsonFindUserConfig (
|
||||||
@ -530,7 +530,7 @@ template <typename T> const T* Core::jsonFindUserConfig (
|
|||||||
if (it == data.end () || it->type () == nlohmann::detail::value_t::null)
|
if (it == data.end () || it->type () == nlohmann::detail::value_t::null)
|
||||||
return T::fromScalar (defaultValue);
|
return T::fromScalar (defaultValue);
|
||||||
|
|
||||||
return T::fromJSON (*it, project);
|
return T::fromJSON (*it, project.getProperties ());
|
||||||
}
|
}
|
||||||
|
|
||||||
template const CUserSettingBoolean* Core::jsonFindUserConfig (
|
template const CUserSettingBoolean* Core::jsonFindUserConfig (
|
||||||
|
@ -5,8 +5,19 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
#include <glm/glm.hpp>
|
#include <glm/glm.hpp>
|
||||||
|
|
||||||
|
namespace WallpaperEngine::Data::Parsers {
|
||||||
|
class UserSettingParser;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace WallpaperEngine::Data::Builders {
|
||||||
|
class UserSettingBuilder;
|
||||||
|
}
|
||||||
|
|
||||||
namespace WallpaperEngine::Core::DynamicValues {
|
namespace WallpaperEngine::Core::DynamicValues {
|
||||||
class CDynamicValue {
|
class CDynamicValue {
|
||||||
|
//TODO: THIS SHOULD BE CHANGED ONCE THINGS ARE FINISHED
|
||||||
|
friend class WallpaperEngine::Data::Parsers::UserSettingParser;
|
||||||
|
friend class WallpaperEngine::Data::Builders::UserSettingBuilder;
|
||||||
public:
|
public:
|
||||||
virtual ~CDynamicValue ();
|
virtual ~CDynamicValue ();
|
||||||
|
|
||||||
|
@ -14,6 +14,10 @@ using namespace WallpaperEngine::Core::DynamicValues;
|
|||||||
*/
|
*/
|
||||||
class CProperty : public CDynamicValue {
|
class CProperty : public CDynamicValue {
|
||||||
public:
|
public:
|
||||||
|
using UniquePtr = std::unique_ptr<CProperty>;
|
||||||
|
using SharedPtr = std::shared_ptr<CProperty>;
|
||||||
|
using WeakPtr = std::weak_ptr<CProperty>;
|
||||||
|
|
||||||
typedef std::function<void(const CProperty*)> function_type;
|
typedef std::function<void(const CProperty*)> function_type;
|
||||||
virtual ~CProperty () = default;
|
virtual ~CProperty () = default;
|
||||||
static std::shared_ptr<CProperty> fromJSON (const json& data, const std::string& name);
|
static std::shared_ptr<CProperty> fromJSON (const json& data, const std::string& name);
|
||||||
|
@ -39,7 +39,7 @@ CUserSettingBoolean::CUserSettingBoolean (
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const CUserSettingBoolean* CUserSettingBoolean::fromJSON (const nlohmann::json& data, const CProject& project) {
|
const CUserSettingBoolean* CUserSettingBoolean::fromJSON (const nlohmann::json& data, const std::map <std::string, std::shared_ptr <Projects::CProperty>>& properties) {
|
||||||
bool hasCondition = false;
|
bool hasCondition = false;
|
||||||
std::shared_ptr <const Projects::CProperty> sourceProperty = nullptr;
|
std::shared_ptr <const Projects::CProperty> sourceProperty = nullptr;
|
||||||
bool defaultValue;
|
bool defaultValue;
|
||||||
@ -61,11 +61,10 @@ const CUserSettingBoolean* CUserSettingBoolean::fromJSON (const nlohmann::json&
|
|||||||
jsonFindRequired <std::string> (userIt, "condition", "Condition for conditional setting must be present");
|
jsonFindRequired <std::string> (userIt, "condition", "Condition for conditional setting must be present");
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const auto& [key, property] : project.getProperties ()) {
|
const auto propertyIt = properties.find (source);
|
||||||
if (key == source) {
|
|
||||||
sourceProperty = property;
|
if (propertyIt != properties.end ()) {
|
||||||
break;
|
sourceProperty = propertyIt->second;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sourceProperty == nullptr) {
|
if (sourceProperty == nullptr) {
|
||||||
|
@ -12,7 +12,7 @@ class CUserSettingBoolean : public CUserSettingValue {
|
|||||||
public:
|
public:
|
||||||
typedef bool data_type;
|
typedef bool data_type;
|
||||||
|
|
||||||
static const CUserSettingBoolean* fromJSON (const nlohmann::json& data, const CProject& project);
|
static const CUserSettingBoolean* fromJSON (const nlohmann::json& data, const std::map <std::string, std::shared_ptr <Projects::CProperty>>& properties);
|
||||||
static const CUserSettingBoolean* fromScalar (bool value);
|
static const CUserSettingBoolean* fromScalar (bool value);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -33,7 +33,7 @@ CUserSettingFloat::CUserSettingFloat (
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const CUserSettingFloat* CUserSettingFloat::fromJSON (const nlohmann::json& data, const CProject& project) {
|
const CUserSettingFloat* CUserSettingFloat::fromJSON (const nlohmann::json& data, const std::map <std::string, std::shared_ptr <Projects::CProperty>>& properties) {
|
||||||
float defaultValue;
|
float defaultValue;
|
||||||
std::string source;
|
std::string source;
|
||||||
std::string expectedValue;
|
std::string expectedValue;
|
||||||
@ -55,11 +55,10 @@ const CUserSettingFloat* CUserSettingFloat::fromJSON (const nlohmann::json& data
|
|||||||
jsonFindRequired <std::string> (userIt, "condition", "Condition for conditional setting must be present");
|
jsonFindRequired <std::string> (userIt, "condition", "Condition for conditional setting must be present");
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const auto& [key, property] : project.getProperties ()) {
|
const auto propertyIt = properties.find (source);
|
||||||
if (key == source) {
|
|
||||||
sourceProperty = property;
|
if (propertyIt != properties.end ()) {
|
||||||
break;
|
sourceProperty = propertyIt->second;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sourceProperty == nullptr) {
|
if (sourceProperty == nullptr) {
|
||||||
|
@ -12,7 +12,7 @@ class CUserSettingFloat : public CUserSettingValue {
|
|||||||
public:
|
public:
|
||||||
typedef float data_type;
|
typedef float data_type;
|
||||||
|
|
||||||
static const CUserSettingFloat* fromJSON (const nlohmann::json& data, const CProject& project);
|
static const CUserSettingFloat* fromJSON (const nlohmann::json& data, const std::map <std::string, std::shared_ptr <Projects::CProperty>>& properties);
|
||||||
static const CUserSettingFloat* fromScalar (float value);
|
static const CUserSettingFloat* fromScalar (float value);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -33,7 +33,7 @@ CUserSettingVector3::CUserSettingVector3 (
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const CUserSettingVector3* CUserSettingVector3::fromJSON (const nlohmann::json& data, const CProject& project) {
|
const CUserSettingVector3* CUserSettingVector3::fromJSON (const nlohmann::json& data, const std::map <std::string, std::shared_ptr <Projects::CProperty>>& properties) {
|
||||||
bool hasCondition = false;
|
bool hasCondition = false;
|
||||||
std::shared_ptr <const Projects::CProperty> sourceProperty = nullptr;
|
std::shared_ptr <const Projects::CProperty> sourceProperty = nullptr;
|
||||||
glm::vec3 defaultValue;
|
glm::vec3 defaultValue;
|
||||||
@ -55,11 +55,10 @@ const CUserSettingVector3* CUserSettingVector3::fromJSON (const nlohmann::json&
|
|||||||
jsonFindRequired <std::string> (userIt, "condition", "Condition for conditional setting must be present");
|
jsonFindRequired <std::string> (userIt, "condition", "Condition for conditional setting must be present");
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const auto& [key, property] : project.getProperties ()) {
|
const auto propertyIt = properties.find (source);
|
||||||
if (key == source) {
|
|
||||||
sourceProperty = property;
|
if (propertyIt != properties.end ()) {
|
||||||
break;
|
sourceProperty = propertyIt->second;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sourceProperty == nullptr) {
|
if (sourceProperty == nullptr) {
|
||||||
|
@ -14,7 +14,7 @@ class CUserSettingVector3 : public CUserSettingValue {
|
|||||||
public:
|
public:
|
||||||
typedef glm::vec3 data_type;
|
typedef glm::vec3 data_type;
|
||||||
|
|
||||||
static const CUserSettingVector3* fromJSON (const nlohmann::json& data, const CProject& project);
|
static const CUserSettingVector3* fromJSON (const nlohmann::json& data, const std::map <std::string, std::shared_ptr <Projects::CProperty>>& properties);
|
||||||
static const CUserSettingVector3* fromScalar (glm::vec3 value);
|
static const CUserSettingVector3* fromScalar (glm::vec3 value);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
23
src/WallpaperEngine/Data/Builders/UserSettingBuilder.h
Normal file
23
src/WallpaperEngine/Data/Builders/UserSettingBuilder.h
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "WallpaperEngine/Data/Model/Types.h"
|
||||||
|
#include "WallpaperEngine/Data/Model/UserSetting.h"
|
||||||
|
|
||||||
|
namespace WallpaperEngine::Data::Builders {
|
||||||
|
using namespace WallpaperEngine::Data::Model;
|
||||||
|
class UserSettingBuilder {
|
||||||
|
public:
|
||||||
|
template <typename T>
|
||||||
|
static UserSettingSharedPtr fromValue (T defaultValue) {
|
||||||
|
DynamicValueUniquePtr value = std::make_unique <DynamicValue> ();
|
||||||
|
|
||||||
|
value->update (defaultValue);
|
||||||
|
|
||||||
|
return std::make_shared <UserSetting> (UserSetting {
|
||||||
|
.value = std::move (value),
|
||||||
|
.property = PropertyWeakPtr (),
|
||||||
|
.condition = std::nullopt,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
} // namespace WallpaperEngine::Data::Builders
|
1
src/WallpaperEngine/Data/Builders/VectorBuilder.cpp
Normal file
1
src/WallpaperEngine/Data/Builders/VectorBuilder.cpp
Normal file
@ -0,0 +1 @@
|
|||||||
|
#include "VectorBuilder.h"
|
178
src/WallpaperEngine/Data/Builders/VectorBuilder.h
Normal file
178
src/WallpaperEngine/Data/Builders/VectorBuilder.h
Normal file
@ -0,0 +1,178 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <cstring>
|
||||||
|
#include <string>
|
||||||
|
#include <glm/glm.hpp>
|
||||||
|
|
||||||
|
#include "WallpaperEngine/Logging/CLog.h"
|
||||||
|
|
||||||
|
namespace WallpaperEngine::Data::Builders {
|
||||||
|
class VectorBuilder {
|
||||||
|
private:
|
||||||
|
/**
|
||||||
|
* Convert template that calls the proper std::strto* function
|
||||||
|
* based on the incoming type
|
||||||
|
*
|
||||||
|
* @tparam type
|
||||||
|
* @param str
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
template <typename type>
|
||||||
|
static type convert (const char* str);
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Takes the string and returns the vector size (2, 3 or 4)
|
||||||
|
*
|
||||||
|
* TODO: THIS SHOULD BE MOVED, RENAMED OR PLACED SOMEWHERE WHERE IT MAKES MORE SENSE
|
||||||
|
*
|
||||||
|
* @param str
|
||||||
|
* @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;
|
||||||
|
|
||||||
|
if (first == nullptr) {
|
||||||
|
sLog.exception ("Invalid vector format: " + str + " (too few values, expected: 2, 3 or 4)");
|
||||||
|
} else if (second == nullptr) {
|
||||||
|
return 2;
|
||||||
|
} else if (third == nullptr) {
|
||||||
|
return 3;
|
||||||
|
} else {
|
||||||
|
return 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Takes a string value and parses it into a glm::vec.
|
||||||
|
* This particular parsing uses spaces as separators and basic std::strto* functions
|
||||||
|
* for the actual parsing of the values.
|
||||||
|
*
|
||||||
|
* @tparam length Vector length
|
||||||
|
* @tparam type Vector storage type
|
||||||
|
* @tparam qualifier Precision qualifier
|
||||||
|
*
|
||||||
|
* @param str The string to parse the vector from
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
template <int length, typename type, glm::qualifier qualifier>
|
||||||
|
static glm::vec<length, type, qualifier> parse (const std::string& str) {
|
||||||
|
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, ")");
|
||||||
|
} else 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, ")");
|
||||||
|
} else 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, ")");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
sLog.exception ("Invalid vector length: ", 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 {
|
||||||
|
return {
|
||||||
|
convert <type> (p),
|
||||||
|
convert <type> (first + 1),
|
||||||
|
convert <type> (second + 1),
|
||||||
|
convert <type> (third + 1)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
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::strtol (str, nullptr, 10);
|
||||||
|
}
|
||||||
|
|
||||||
|
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 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) {
|
||||||
|
return std::strtoul (str, nullptr, 10);
|
||||||
|
}
|
||||||
|
|
||||||
|
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 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 bool VectorBuilder::convert<bool> (const char* str) {
|
||||||
|
return std::strtoul (str, nullptr, 10) > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace WallpaperEngine::Data::Parsers
|
394
src/WallpaperEngine/Data/Dumpers/StringPrinter.cpp
Normal file
394
src/WallpaperEngine/Data/Dumpers/StringPrinter.cpp
Normal file
@ -0,0 +1,394 @@
|
|||||||
|
#include <utility>
|
||||||
|
|
||||||
|
#include "StringPrinter.h"
|
||||||
|
|
||||||
|
#include "WallpaperEngine/Data/Model/Wallpaper.h"
|
||||||
|
|
||||||
|
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)) { }
|
||||||
|
|
||||||
|
void StringPrinter::printWallpaper (const Wallpaper& wallpaper) {
|
||||||
|
bool isScene = wallpaper.is <Scene> ();
|
||||||
|
bool isVideo = wallpaper.is <Video> ();
|
||||||
|
bool isWeb = wallpaper.is <Web> ();
|
||||||
|
|
||||||
|
if (isVideo) {
|
||||||
|
const auto video = wallpaper.as <Video> ();
|
||||||
|
|
||||||
|
this->m_out << "Video wallpaper: " << video->filename;
|
||||||
|
this->lineEnd ();
|
||||||
|
} else if (isWeb) {
|
||||||
|
const auto web = wallpaper.as <Web> ();
|
||||||
|
|
||||||
|
this->m_out << "Web wallpaper: " << web->filename;
|
||||||
|
this->lineEnd ();
|
||||||
|
} else if (isScene) {
|
||||||
|
const auto scene = wallpaper.as <Scene> ();
|
||||||
|
|
||||||
|
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 ();
|
||||||
|
|
||||||
|
for (const auto& object : scene->objects) {
|
||||||
|
this->lineEnd ();
|
||||||
|
this->printObject (*object.second);
|
||||||
|
this->lineEnd ();
|
||||||
|
}
|
||||||
|
|
||||||
|
this->decreaseIndentation ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void StringPrinter::printObject (const Object& object) {
|
||||||
|
this->m_out << "Object " << object.id << " " << object.name << ":";
|
||||||
|
this->increaseIndentation ();
|
||||||
|
|
||||||
|
this->lineEnd ();
|
||||||
|
this->m_out << "Dependencies (" << object.dependencies.size () << "): ";
|
||||||
|
|
||||||
|
for (const auto& dependency : object.dependencies) {
|
||||||
|
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> ());
|
||||||
|
}
|
||||||
|
|
||||||
|
this->decreaseIndentation ();
|
||||||
|
}
|
||||||
|
|
||||||
|
void StringPrinter::printImage (const Image& image) {
|
||||||
|
this->printModel (*image.model);
|
||||||
|
|
||||||
|
this->lineEnd ();
|
||||||
|
this->m_out << "Image effects count: " << image.effects.size ();
|
||||||
|
this->increaseIndentation ();
|
||||||
|
|
||||||
|
for (const auto& effect : image.effects) {
|
||||||
|
this->lineEnd ();
|
||||||
|
this->printImageEffect (*effect);
|
||||||
|
}
|
||||||
|
|
||||||
|
this->decreaseIndentation ();
|
||||||
|
}
|
||||||
|
|
||||||
|
void StringPrinter::printSound (const Sound& sound) {
|
||||||
|
this->m_out << "Sounds: " << sound.sounds.size ();
|
||||||
|
this->increaseIndentation ();
|
||||||
|
|
||||||
|
for (const auto& filename : sound.sounds) {
|
||||||
|
this->lineEnd ();
|
||||||
|
this->m_out << "Filename " << filename;
|
||||||
|
}
|
||||||
|
|
||||||
|
this->decreaseIndentation ();
|
||||||
|
}
|
||||||
|
|
||||||
|
void StringPrinter::printModel (const ModelStruct& model) {
|
||||||
|
this->m_out << "Model " << model.filename << ":";
|
||||||
|
this->increaseIndentation ();
|
||||||
|
this->lineEnd ();
|
||||||
|
|
||||||
|
this->m_out << "Autosize: " << model.autosize;
|
||||||
|
this->lineEnd ();
|
||||||
|
this->m_out << "Passthrough: " << model.passthrough;
|
||||||
|
this->lineEnd ();
|
||||||
|
this->m_out << "Fullscreen: " << model.fullscreen;
|
||||||
|
this->lineEnd ();
|
||||||
|
this->m_out << "No padding: " << model.nopadding;
|
||||||
|
this->lineEnd ();
|
||||||
|
this->m_out << "Solid layer: " << model.solidlayer;
|
||||||
|
this->lineEnd ();
|
||||||
|
|
||||||
|
if (model.width.has_value ()) {
|
||||||
|
this->m_out << "Width: " << model.width.value ();
|
||||||
|
this->lineEnd ();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (model.height.has_value ()) {
|
||||||
|
this->m_out << "Height: " << model.height.value ();
|
||||||
|
this->lineEnd ();
|
||||||
|
}
|
||||||
|
|
||||||
|
this->printMaterial (*model.material);
|
||||||
|
|
||||||
|
this->decreaseIndentation ();
|
||||||
|
}
|
||||||
|
|
||||||
|
void StringPrinter::printImageEffect (const ImageEffect& effect) {
|
||||||
|
this->m_out << "Image effect " << effect.id << ":";
|
||||||
|
|
||||||
|
this->increaseIndentation ();
|
||||||
|
|
||||||
|
this->lineEnd ();
|
||||||
|
this->m_out << "Default visibility status: " << effect.visible->value->getBool ();
|
||||||
|
|
||||||
|
this->printEffect (*effect.effect);
|
||||||
|
|
||||||
|
this->lineEnd ();
|
||||||
|
this->m_out << "Effect overrides count: " << effect.passOverrides.size ();
|
||||||
|
|
||||||
|
this->increaseIndentation ();
|
||||||
|
|
||||||
|
for (const auto& override : effect.passOverrides) {
|
||||||
|
this->printImageEffectPassOverride (*override);
|
||||||
|
}
|
||||||
|
|
||||||
|
this->decreaseIndentation ();
|
||||||
|
this->decreaseIndentation ();
|
||||||
|
}
|
||||||
|
|
||||||
|
void StringPrinter::printImageEffectPassOverride (const ImageEffectPassOverride& imageEffectPass) {
|
||||||
|
this->lineEnd ();
|
||||||
|
this->m_out << "Pass override " << imageEffectPass.id << ":";
|
||||||
|
this->increaseIndentation ();
|
||||||
|
|
||||||
|
this->lineEnd ();
|
||||||
|
this->m_out << "Textures count: " << imageEffectPass.textures.size ();
|
||||||
|
|
||||||
|
if (!imageEffectPass.textures.empty ()) {
|
||||||
|
this->increaseIndentation ();
|
||||||
|
|
||||||
|
for (const auto& texture : imageEffectPass.textures) {
|
||||||
|
this->lineEnd ();
|
||||||
|
this->m_out << "Texture " << texture.first << ": " << texture.second;
|
||||||
|
}
|
||||||
|
|
||||||
|
this->decreaseIndentation ();
|
||||||
|
}
|
||||||
|
|
||||||
|
this->lineEnd ();
|
||||||
|
this->m_out << "Combos count: " << imageEffectPass.combos.size ();
|
||||||
|
|
||||||
|
if (!imageEffectPass.combos.empty ()) {
|
||||||
|
this->increaseIndentation ();
|
||||||
|
|
||||||
|
for (const auto& combo : imageEffectPass.combos) {
|
||||||
|
this->lineEnd ();
|
||||||
|
this->m_out << "Combo " << combo.first << "=" << combo.second;
|
||||||
|
}
|
||||||
|
|
||||||
|
this->decreaseIndentation ();
|
||||||
|
}
|
||||||
|
|
||||||
|
this->lineEnd ();
|
||||||
|
this->m_out << "Constants count: " << imageEffectPass.constants.size ();
|
||||||
|
|
||||||
|
if (!imageEffectPass.constants.empty ()) {
|
||||||
|
this->increaseIndentation ();
|
||||||
|
|
||||||
|
for (const auto& constant : imageEffectPass.constants) {
|
||||||
|
this->lineEnd ();
|
||||||
|
this->m_out << "Constant " << constant.first << "=" << constant.second->toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
this->decreaseIndentation ();
|
||||||
|
}
|
||||||
|
|
||||||
|
this->decreaseIndentation ();
|
||||||
|
}
|
||||||
|
|
||||||
|
void StringPrinter::printEffect (const Effect& effect) {
|
||||||
|
this->lineEnd ();
|
||||||
|
this->m_out << "Effect " << effect.name << ":";
|
||||||
|
this->increaseIndentation ();
|
||||||
|
|
||||||
|
if (!effect.description.empty ()) {
|
||||||
|
this->lineEnd ();
|
||||||
|
this->m_out << "Description: " << effect.description;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!effect.dependencies.empty ()) {
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
this->decreaseIndentation ();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!effect.group.empty ()) {
|
||||||
|
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 << "Passes count: " << effect.passes.size ();
|
||||||
|
this->increaseIndentation ();
|
||||||
|
|
||||||
|
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->decreaseIndentation ();
|
||||||
|
|
||||||
|
this->lineEnd ();
|
||||||
|
this->m_out << "FBOs count: " << effect.fbos.size ();
|
||||||
|
this->increaseIndentation ();
|
||||||
|
|
||||||
|
for (const auto& fbo : effect.fbos) {
|
||||||
|
this->lineEnd ();
|
||||||
|
this->printFBO (*fbo);
|
||||||
|
}
|
||||||
|
|
||||||
|
this->decreaseIndentation ();
|
||||||
|
this->decreaseIndentation ();
|
||||||
|
}
|
||||||
|
|
||||||
|
void StringPrinter::printEffectPass (const EffectPass& effectPass) {
|
||||||
|
if (effectPass.command.has_value ()) {
|
||||||
|
const auto& command = effectPass.command.value ();
|
||||||
|
|
||||||
|
this->m_out << "Command: " << (command.command == Command_Copy ? "copy" : "swap");
|
||||||
|
this->lineEnd ();
|
||||||
|
this->m_out << "Source: " << command.source;
|
||||||
|
this->lineEnd ();
|
||||||
|
this->m_out << "Target: " << command.target;
|
||||||
|
} else {
|
||||||
|
if (effectPass.target.has_value ()) {
|
||||||
|
this->m_out << "Target: " << effectPass.target.value ();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!effectPass.binds.empty ()) {
|
||||||
|
if (effectPass.target.has_value ()) {
|
||||||
|
this->lineEnd ();
|
||||||
|
}
|
||||||
|
|
||||||
|
this->m_out << "Binds count: " << effectPass.binds.size ();
|
||||||
|
this->increaseIndentation ();
|
||||||
|
|
||||||
|
for (const auto& bind : effectPass.binds) {
|
||||||
|
this->lineEnd ();
|
||||||
|
this->m_out << "Bind " << bind.first << ": " << bind.second;
|
||||||
|
}
|
||||||
|
|
||||||
|
this->decreaseIndentation ();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (effectPass.target.has_value () || !effectPass.binds.empty ()) {
|
||||||
|
this->lineEnd ();
|
||||||
|
}
|
||||||
|
|
||||||
|
this->printMaterial (*effectPass.material);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void StringPrinter::printFBO (const FBO& fbo) {
|
||||||
|
this->m_out << "FBO " << fbo.name << ":";
|
||||||
|
this->increaseIndentation ();
|
||||||
|
|
||||||
|
this->lineEnd ();
|
||||||
|
this->m_out << "Format: " << fbo.format;
|
||||||
|
|
||||||
|
this->lineEnd ();
|
||||||
|
this->m_out << "Scale: " << fbo.scale;
|
||||||
|
this->decreaseIndentation ();
|
||||||
|
}
|
||||||
|
|
||||||
|
void StringPrinter::printMaterial (const Material& material) {
|
||||||
|
this->m_out << "Material " << material.filename << ":";
|
||||||
|
this->increaseIndentation ();
|
||||||
|
this->lineEnd ();
|
||||||
|
this->m_out << "Passes count: " << material.passes.size ();
|
||||||
|
this->increaseIndentation ();
|
||||||
|
|
||||||
|
for (const auto& pass : material.passes) {
|
||||||
|
this->lineEnd ();
|
||||||
|
this->printMaterialPass (*pass);
|
||||||
|
}
|
||||||
|
|
||||||
|
this->decreaseIndentation ();
|
||||||
|
this->decreaseIndentation ();
|
||||||
|
}
|
||||||
|
|
||||||
|
void StringPrinter::printMaterialPass (const MaterialPass& materialPass) {
|
||||||
|
this->m_out << "Pass " << materialPass.shader << ":";
|
||||||
|
this->increaseIndentation ();
|
||||||
|
|
||||||
|
this->lineEnd ();
|
||||||
|
this->m_out << "Depth test: " << materialPass.depthtest;
|
||||||
|
this->lineEnd ();
|
||||||
|
this->m_out << "Depth write: " << materialPass.depthwrite;
|
||||||
|
this->lineEnd ();
|
||||||
|
this->m_out << "Blend mode: " << materialPass.blending;
|
||||||
|
this->lineEnd ();
|
||||||
|
this->m_out << "Culling mode: " << materialPass.cullmode;
|
||||||
|
|
||||||
|
if (!materialPass.textures.empty ()) {
|
||||||
|
this->lineEnd ();
|
||||||
|
this->m_out << "Textures count: " << materialPass.textures.size ();
|
||||||
|
this->increaseIndentation ();
|
||||||
|
|
||||||
|
for (const auto& texture : materialPass.textures) {
|
||||||
|
this->lineEnd ();
|
||||||
|
this->m_out << "Texture " << texture.first << ": " << texture.second;
|
||||||
|
}
|
||||||
|
|
||||||
|
this->decreaseIndentation ();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!materialPass.combos.empty ()) {
|
||||||
|
this->lineEnd ();
|
||||||
|
this->m_out << "Combos count: " << materialPass.combos.size ();
|
||||||
|
this->increaseIndentation ();
|
||||||
|
|
||||||
|
for (const auto& combo : materialPass.combos) {
|
||||||
|
this->lineEnd ();
|
||||||
|
this->m_out << "Combo " << combo.first << ": " << combo.second;
|
||||||
|
}
|
||||||
|
|
||||||
|
this->decreaseIndentation ();
|
||||||
|
}
|
||||||
|
|
||||||
|
this->decreaseIndentation ();
|
||||||
|
}
|
||||||
|
|
||||||
|
void StringPrinter::indentation () {
|
||||||
|
for (int i = 0; i < this->m_level; i++)
|
||||||
|
this->m_out << this->m_indentationCharacter;
|
||||||
|
}
|
||||||
|
|
||||||
|
void StringPrinter::lineEnd () {
|
||||||
|
this->m_out << "\n";
|
||||||
|
this->indentation ();
|
||||||
|
}
|
||||||
|
|
||||||
|
void StringPrinter::increaseIndentation () {
|
||||||
|
this->m_level ++;
|
||||||
|
}
|
||||||
|
|
||||||
|
void StringPrinter::decreaseIndentation () {
|
||||||
|
this->m_level --;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string StringPrinter::str () {
|
||||||
|
return this->m_buffer.str ();
|
||||||
|
}
|
130
src/WallpaperEngine/Data/Dumpers/StringPrinter.h
Normal file
130
src/WallpaperEngine/Data/Dumpers/StringPrinter.h
Normal file
@ -0,0 +1,130 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
#include "WallpaperEngine/Data/Model/Types.h"
|
||||||
|
|
||||||
|
namespace WallpaperEngine::Data::Dumpers {
|
||||||
|
using namespace WallpaperEngine::Data::Model;
|
||||||
|
|
||||||
|
class StringPrinter {
|
||||||
|
public:
|
||||||
|
explicit StringPrinter (std::string indentationCharacter = "\t");
|
||||||
|
~StringPrinter () = default;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The contents of the pretty printer buffer
|
||||||
|
*/
|
||||||
|
std::string str ();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prints the information of the given wallpaper
|
||||||
|
*
|
||||||
|
* @param wallpaper
|
||||||
|
*/
|
||||||
|
void printWallpaper (const Wallpaper& wallpaper);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prints the information of the given object
|
||||||
|
*
|
||||||
|
* @param object
|
||||||
|
*/
|
||||||
|
void printObject (const Object& object);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prints the information of the given image
|
||||||
|
*
|
||||||
|
* @param image
|
||||||
|
*/
|
||||||
|
void printImage (const Image& image);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prints the information of the given sound
|
||||||
|
*
|
||||||
|
* @param sound
|
||||||
|
*/
|
||||||
|
void printSound (const Sound& sound);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prints the information of the given model
|
||||||
|
*
|
||||||
|
* @param model
|
||||||
|
*/
|
||||||
|
void printModel (const ModelStruct& model);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prints the information of the given image effect
|
||||||
|
*
|
||||||
|
* @param imageEffect
|
||||||
|
*/
|
||||||
|
void printImageEffect (const ImageEffect& imageEffect);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prints the information of the given image effect pass
|
||||||
|
*
|
||||||
|
* @param imageEffectPass
|
||||||
|
*/
|
||||||
|
void printImageEffectPassOverride (const ImageEffectPassOverride& imageEffectPass);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prints the information of the given FBO
|
||||||
|
*
|
||||||
|
* @param fbo
|
||||||
|
*/
|
||||||
|
void printFBO (const FBO& fbo);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prints the information of the given material
|
||||||
|
*
|
||||||
|
* @param material
|
||||||
|
*/
|
||||||
|
void printMaterial (const Material& material);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prints the information of the given material pass
|
||||||
|
*
|
||||||
|
* @param materialPass
|
||||||
|
*/
|
||||||
|
void printMaterialPass (const MaterialPass& materialPass);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prints the information of the given effect
|
||||||
|
*
|
||||||
|
* @param effect
|
||||||
|
*/
|
||||||
|
void printEffect (const Effect& effect);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prints the information of the given effect
|
||||||
|
*
|
||||||
|
* @param effectPass
|
||||||
|
*/
|
||||||
|
void printEffectPass (const EffectPass& effectPass);
|
||||||
|
|
||||||
|
private:
|
||||||
|
/**
|
||||||
|
* Printss the current identation level
|
||||||
|
*/
|
||||||
|
void indentation ();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prints an end of line and indentates the next line to the aproppiate level
|
||||||
|
*/
|
||||||
|
void lineEnd ();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Increases the indentation level and prints a new line up to the specified level
|
||||||
|
*/
|
||||||
|
void increaseIndentation ();
|
||||||
|
/**
|
||||||
|
* Decreases the indentation level and prints a new line up to the specified level
|
||||||
|
*/
|
||||||
|
void decreaseIndentation ();
|
||||||
|
|
||||||
|
int m_level = 0;
|
||||||
|
std::stringbuf m_buffer = {};
|
||||||
|
std::ostream m_out;
|
||||||
|
std::string m_indentationCharacter;
|
||||||
|
};
|
||||||
|
} // namespace WallpaperEngine::Data::Dumpers
|
12
src/WallpaperEngine/Data/JSON.cpp
Normal file
12
src/WallpaperEngine/Data/JSON.cpp
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
#include "JSON.h"
|
||||||
|
|
||||||
|
#include "WallpaperEngine/Data/Parsers/UserSettingParser.h"
|
||||||
|
|
||||||
|
using namespace WallpaperEngine::Data::JSON;
|
||||||
|
using namespace WallpaperEngine::Data::Model;
|
||||||
|
|
||||||
|
UserSettingSharedPtr JsonExtensions::user (const std::string& key, const Properties& properties) const {
|
||||||
|
const auto value = this->require (key, "User setting without default value must be present");
|
||||||
|
|
||||||
|
return UserSettingParser::parse (value, properties);
|
||||||
|
}
|
168
src/WallpaperEngine/Data/JSON.h
Normal file
168
src/WallpaperEngine/Data/JSON.h
Normal file
@ -0,0 +1,168 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <glm/detail/qualifier.hpp>
|
||||||
|
#include <glm/detail/type_vec1.hpp>
|
||||||
|
#include <nlohmann/json.hpp>
|
||||||
|
#include <optional>
|
||||||
|
#include <string>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
#include "WallpaperEngine/Data/Builders/UserSettingBuilder.h"
|
||||||
|
#include "WallpaperEngine/Data/Builders/VectorBuilder.h"
|
||||||
|
#include "WallpaperEngine/Data/Model/Types.h"
|
||||||
|
#include "WallpaperEngine/Logging/CLog.h"
|
||||||
|
|
||||||
|
namespace WallpaperEngine::Data::Parsers {
|
||||||
|
class UserSettingParser;
|
||||||
|
}
|
||||||
|
namespace WallpaperEngine::Data::JSON {
|
||||||
|
using namespace WallpaperEngine::Data::Builders;
|
||||||
|
using namespace WallpaperEngine::Data::Parsers;
|
||||||
|
using namespace WallpaperEngine::Data::Model;
|
||||||
|
|
||||||
|
// sfinae to detect the type for template specialization
|
||||||
|
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 {};
|
||||||
|
|
||||||
|
// traits used to guess the type of the vector and it's length
|
||||||
|
template <typename T>
|
||||||
|
struct GlmVecTraits;
|
||||||
|
|
||||||
|
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;
|
||||||
|
};
|
||||||
|
|
||||||
|
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
|
||||||
|
>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Small extensions class that is used as base class of nlohmann's implementation.
|
||||||
|
*
|
||||||
|
* Provides shorthand methods to reduce the amount of handling required for specific situations
|
||||||
|
* (mainly throwing readable exceptions when a value is missing, optional/default values, user settings...)
|
||||||
|
*/
|
||||||
|
class JsonExtensions {
|
||||||
|
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;
|
||||||
|
|
||||||
|
// 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]] base_type require (const std::string& key, const std::string& message) const {
|
||||||
|
auto base = this->base ();
|
||||||
|
auto it = base.find (key);
|
||||||
|
|
||||||
|
if (it == base.end ()) {
|
||||||
|
sLog.exception (message);
|
||||||
|
}
|
||||||
|
|
||||||
|
return *it;
|
||||||
|
}
|
||||||
|
template <typename T>
|
||||||
|
[[nodiscard]] T require (const std::string& key, const std::string& message) const {
|
||||||
|
auto base = this->base ();
|
||||||
|
auto it = base.find (key);
|
||||||
|
|
||||||
|
if (it == base.end ()) {
|
||||||
|
sLog.exception (message);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (*it);
|
||||||
|
}
|
||||||
|
[[nodiscard]] std::optional <base_type> optional (const std::string& key) const noexcept {
|
||||||
|
auto base = this->base ();
|
||||||
|
auto it = base.find (key);
|
||||||
|
auto result = std::optional<base_type> {};
|
||||||
|
|
||||||
|
if (it != base.end ()) {
|
||||||
|
result.emplace (*it);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
template <typename T>
|
||||||
|
[[nodiscard]] std::optional <T> optional (const std::string& key) const noexcept {
|
||||||
|
auto base = this->base ();
|
||||||
|
auto it = base.find (key);
|
||||||
|
|
||||||
|
if (it == base.end ()) {
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
|
||||||
|
return *it;
|
||||||
|
}
|
||||||
|
template <typename T>
|
||||||
|
[[nodiscard]] T optional (const std::string& key, T defaultValue) const noexcept {
|
||||||
|
auto base = this->base ();
|
||||||
|
auto it = base.find (key);
|
||||||
|
|
||||||
|
if (it == base.end ()) {
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (*it);
|
||||||
|
}
|
||||||
|
[[nodiscard]] UserSettingSharedPtr user (const std::string& key, const Properties& properties) const;
|
||||||
|
template <typename T>
|
||||||
|
[[nodiscard]] UserSettingSharedPtr 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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 <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> ();
|
||||||
|
}
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace WallpaperEngine::Data::JSON
|
54
src/WallpaperEngine/Data/Model/Effect.h
Normal file
54
src/WallpaperEngine/Data/Model/Effect.h
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "Types.h"
|
||||||
|
|
||||||
|
namespace WallpaperEngine::Data::Model {
|
||||||
|
enum PassCommandType {
|
||||||
|
Command_Copy = 0,
|
||||||
|
Command_Swap = 1
|
||||||
|
};
|
||||||
|
|
||||||
|
struct FBO {
|
||||||
|
std::string name;
|
||||||
|
std::string format;
|
||||||
|
float scale;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct PassCommand {
|
||||||
|
/** The type of command to execute */
|
||||||
|
PassCommandType command;
|
||||||
|
/** The target of the command (where to draw to) */
|
||||||
|
std::string target;
|
||||||
|
/** The source of the command (where to draw from) */
|
||||||
|
std::string source;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct EffectPass {
|
||||||
|
/** The material to use for this effect's pass */
|
||||||
|
MaterialUniquePtr material;
|
||||||
|
/** Texture bindings for this effect's pass */
|
||||||
|
std::map <int, std::string> binds;
|
||||||
|
/** The command this material executes (if specified) */
|
||||||
|
std::optional <PassCommand> command;
|
||||||
|
/** The target this material renders to (if specified) */
|
||||||
|
std::optional <std::string> target;
|
||||||
|
};
|
||||||
|
struct Effect {
|
||||||
|
/** Effect's name for the UI */
|
||||||
|
std::string name;
|
||||||
|
/** Effect's description for the UI */
|
||||||
|
std::string description;
|
||||||
|
/** Effect's group for the UI */
|
||||||
|
std::string group;
|
||||||
|
/** Effect's preview project */
|
||||||
|
std::string preview;
|
||||||
|
/** Effect's dependencies */
|
||||||
|
std::vector <std::string> dependencies;
|
||||||
|
/** The different passes for this effect */
|
||||||
|
std::vector <EffectPassUniquePtr> passes;
|
||||||
|
/** The fbos declared by this effect */
|
||||||
|
std::vector <FBOUniquePtr> fbos;
|
||||||
|
};
|
||||||
|
} // namespace WallpaperEngine::Data::Model
|
36
src/WallpaperEngine/Data/Model/Material.h
Normal file
36
src/WallpaperEngine/Data/Model/Material.h
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
#include <vector>
|
||||||
|
#include <string>
|
||||||
|
#include <optional>
|
||||||
|
|
||||||
|
#include "Types.h"
|
||||||
|
|
||||||
|
namespace WallpaperEngine::Data::Model {
|
||||||
|
struct MaterialPass {
|
||||||
|
// TODO: WRITE ENUMS FOR THESE
|
||||||
|
/** Blending mode */
|
||||||
|
std::string blending;
|
||||||
|
/** Culling mode */
|
||||||
|
std::string cullmode;
|
||||||
|
/** Depth test mode */
|
||||||
|
std::string depthtest;
|
||||||
|
/** Depth write mode */
|
||||||
|
std::string depthwrite;
|
||||||
|
/** Shader file to use for this pass */
|
||||||
|
std::string shader;
|
||||||
|
/** List of textures defined for this pass */
|
||||||
|
std::map <int, std::string> textures;
|
||||||
|
/** The combos and their values to pass onto the shader */
|
||||||
|
std::map <std::string, int> combos;
|
||||||
|
};
|
||||||
|
|
||||||
|
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;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace WallpaperEngine::Data::Model
|
27
src/WallpaperEngine/Data/Model/Model.h
Normal file
27
src/WallpaperEngine/Data/Model/Model.h
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "Types.h"
|
||||||
|
|
||||||
|
namespace WallpaperEngine::Data::Model {
|
||||||
|
// TODO: FIND A BETTER NAMING SO THIS DOESN'T COLLIDE WITH THE NAMESPACE ITSELF
|
||||||
|
struct ModelStruct {
|
||||||
|
/** The filename of the model */
|
||||||
|
std::string filename;
|
||||||
|
/** The material used for this model */
|
||||||
|
MaterialUniquePtr material;
|
||||||
|
/** Whether this model is a solid layer */
|
||||||
|
bool solidlayer;
|
||||||
|
/** Whether this model is a fullscreen layer */
|
||||||
|
bool fullscreen;
|
||||||
|
/** Whether this model is a passthrough layer */
|
||||||
|
bool passthrough;
|
||||||
|
/** Whether this models's size should be determined automatically or not */
|
||||||
|
bool autosize;
|
||||||
|
/** Whether this models's padding should be disabled or not */
|
||||||
|
bool nopadding;
|
||||||
|
/** Not sure what's used for */
|
||||||
|
std::optional<int> width;
|
||||||
|
/** Not sure what's used for */
|
||||||
|
std::optional<int> height;
|
||||||
|
};
|
||||||
|
} // namespace WallpaperEngine::Data::Model
|
122
src/WallpaperEngine/Data/Model/Object.h
Normal file
122
src/WallpaperEngine/Data/Model/Object.h
Normal file
@ -0,0 +1,122 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <utility>
|
||||||
|
#include <vector>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include <glm/glm.hpp>
|
||||||
|
|
||||||
|
#include "Types.h"
|
||||||
|
#include "Effect.h"
|
||||||
|
#include "Material.h"
|
||||||
|
#include "Model.h"
|
||||||
|
#include "WallpaperEngine/Data/Utils/TypeCaster.h"
|
||||||
|
|
||||||
|
namespace WallpaperEngine::Data::Model {
|
||||||
|
using TypeCaster = WallpaperEngine::Data::Utils::TypeCaster;
|
||||||
|
|
||||||
|
struct ObjectData {
|
||||||
|
int id;
|
||||||
|
std::string name;
|
||||||
|
std::vector <int> dependencies;
|
||||||
|
};
|
||||||
|
|
||||||
|
//TODO: CHECK IF THE SEMANTICS FOR MEMORY ARE RIGHT HERE
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base class for all objects, represents a single object in the scene
|
||||||
|
*
|
||||||
|
* @see Image
|
||||||
|
* @see Sound
|
||||||
|
* @see Particle
|
||||||
|
* @see Text
|
||||||
|
* @see Light
|
||||||
|
*/
|
||||||
|
class Object : public TypeCaster, public ObjectData {
|
||||||
|
public:
|
||||||
|
explicit Object (ObjectData data) noexcept : ObjectData (std::move (data)), TypeCaster () {};
|
||||||
|
~Object () override = default;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Overrides effect's passes configuration
|
||||||
|
*
|
||||||
|
* @see ImageEffect
|
||||||
|
* @see EffectPass
|
||||||
|
*/
|
||||||
|
struct ImageEffectPassOverride {
|
||||||
|
int id;
|
||||||
|
ComboMap combos;
|
||||||
|
ShaderConstantMap constants;
|
||||||
|
std::map <int, std::string> textures;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Override information for an specific effect
|
||||||
|
*
|
||||||
|
* @see ImageEffect
|
||||||
|
* @see Effect
|
||||||
|
* @see EffectPass
|
||||||
|
* @see ImageEffectPass
|
||||||
|
*/
|
||||||
|
struct ImageEffect {
|
||||||
|
/** Not sure what it's used for */
|
||||||
|
int id;
|
||||||
|
/** Effect's name for the editor */
|
||||||
|
std::string name;
|
||||||
|
/** If this effect is visible or not */
|
||||||
|
UserSettingSharedPtr visible;
|
||||||
|
/** Pass overrides to apply to the effect's passes */
|
||||||
|
std::vector <ImageEffectPassOverrideUniquePtr> passOverrides;
|
||||||
|
/** The effect definition */
|
||||||
|
EffectUniquePtr effect;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ImageData {
|
||||||
|
/** The point of origin of the image */
|
||||||
|
UserSettingSharedPtr origin;
|
||||||
|
/** The scale of the image */
|
||||||
|
UserSettingSharedPtr scale;
|
||||||
|
/** The rotation of the image */
|
||||||
|
UserSettingSharedPtr angles;
|
||||||
|
/** If the image is visible or not */
|
||||||
|
UserSettingSharedPtr visible;
|
||||||
|
/** The alpha of the image */
|
||||||
|
UserSettingSharedPtr alpha;
|
||||||
|
/** The color of the image */
|
||||||
|
UserSettingSharedPtr color;
|
||||||
|
// TODO: WRITE A COUPLE OF ENUMS FOR THIS
|
||||||
|
/** The alignment of the image */
|
||||||
|
std::string alignment;
|
||||||
|
/** The size of the image in pixels */
|
||||||
|
glm::vec2 size;
|
||||||
|
/** Parallax depth used for parallax scrolling */
|
||||||
|
glm::vec2 parallaxDepth;
|
||||||
|
/** The color blending mode for this image */
|
||||||
|
int colorBlendMode;
|
||||||
|
/** The brightness of the image */
|
||||||
|
float brightness;
|
||||||
|
/** The material in use for this image */
|
||||||
|
ModelUniquePtr model;
|
||||||
|
/** The effects applied to this image after the material is rendered */
|
||||||
|
std::vector <ImageEffectUniquePtr> effects;
|
||||||
|
};
|
||||||
|
|
||||||
|
class Image : public Object, public 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, */
|
||||||
|
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)) {};
|
||||||
|
~Sound () override = default;
|
||||||
|
};
|
||||||
|
} // namespace WallpaperEngine::Data::Model
|
38
src/WallpaperEngine/Data/Model/Project.h
Normal file
38
src/WallpaperEngine/Data/Model/Project.h
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
#include "Types.h"
|
||||||
|
|
||||||
|
namespace WallpaperEngine::Data::Model {
|
||||||
|
using json = WallpaperEngine::Data::JSON::JSON;
|
||||||
|
/**
|
||||||
|
* Represents a wallpaper engine project
|
||||||
|
*/
|
||||||
|
struct Project {
|
||||||
|
public:
|
||||||
|
enum Type {
|
||||||
|
Type_Scene = 0,
|
||||||
|
Type_Web = 1,
|
||||||
|
Type_Video = 2,
|
||||||
|
Type_Unknown = 3
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Wallpapers title */
|
||||||
|
std::string title;
|
||||||
|
/** Wallpaper's type */
|
||||||
|
Type type;
|
||||||
|
/** Workshop ID of the background or a negative id if not present */
|
||||||
|
std::string workshopId;
|
||||||
|
/** Indicates if the background uses audio processing or not */
|
||||||
|
bool supportsAudioProcessing;
|
||||||
|
/** All the available properties that the project defines for the user to change */
|
||||||
|
Properties properties;
|
||||||
|
|
||||||
|
/** The wallpaper this project defines */
|
||||||
|
WallpaperSharedPtr wallpaper;
|
||||||
|
/** VFS to access the project's files */
|
||||||
|
ContainerWeakPtr container;
|
||||||
|
};
|
||||||
|
};
|
86
src/WallpaperEngine/Data/Model/Types.h
Normal file
86
src/WallpaperEngine/Data/Model/Types.h
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
#include "WallpaperEngine/Assets/CContainer.h"
|
||||||
|
#include "WallpaperEngine/Core/DynamicValues/CDynamicValue.h"
|
||||||
|
#include "WallpaperEngine/Core/Objects/Effects/Constants/CShaderConstant.h"
|
||||||
|
#include "WallpaperEngine/Core/Objects/Effects/Constants/CShaderConstantProperty.h"
|
||||||
|
#include "WallpaperEngine/Core/Objects/Effects/Constants/CShaderConstantFloat.h"
|
||||||
|
#include "WallpaperEngine/Core/Objects/Effects/Constants/CShaderConstantInteger.h"
|
||||||
|
#include "WallpaperEngine/Core/Objects/Effects/Constants/CShaderConstantVector2.h"
|
||||||
|
#include "WallpaperEngine/Core/Objects/Effects/Constants/CShaderConstantVector3.h"
|
||||||
|
#include "WallpaperEngine/Core/Objects/Effects/Constants/CShaderConstantVector4.h"
|
||||||
|
#include "WallpaperEngine/Core/Projects/CProperty.h"
|
||||||
|
|
||||||
|
namespace WallpaperEngine::Data::Model {
|
||||||
|
struct Project;
|
||||||
|
class Wallpaper;
|
||||||
|
class Scene;
|
||||||
|
class Web;
|
||||||
|
class Video;
|
||||||
|
class UserSetting;
|
||||||
|
class Object;
|
||||||
|
class Sound;
|
||||||
|
class Image;
|
||||||
|
struct ImageEffect;
|
||||||
|
struct ImageEffectPassOverride;
|
||||||
|
class Particle;
|
||||||
|
struct Material;
|
||||||
|
struct MaterialPass;
|
||||||
|
struct FBO;
|
||||||
|
struct Effect;
|
||||||
|
struct EffectPass;
|
||||||
|
struct ModelStruct;
|
||||||
|
|
||||||
|
// TODO: REMOVE ONCE THESE ARE RENAMED AND MOVED
|
||||||
|
using Container = WallpaperEngine::Assets::CContainer;
|
||||||
|
using ShaderConstant = WallpaperEngine::Core::Objects::Effects::Constants::CShaderConstant;
|
||||||
|
using ShaderConstantProperty = WallpaperEngine::Core::Objects::Effects::Constants::CShaderConstantProperty;
|
||||||
|
using ShaderConstantFloat = WallpaperEngine::Core::Objects::Effects::Constants::CShaderConstantFloat;
|
||||||
|
using ShaderConstantInteger = WallpaperEngine::Core::Objects::Effects::Constants::CShaderConstantInteger;
|
||||||
|
using ShaderConstantVector2 = WallpaperEngine::Core::Objects::Effects::Constants::CShaderConstantVector2;
|
||||||
|
using ShaderConstantVector3 = WallpaperEngine::Core::Objects::Effects::Constants::CShaderConstantVector3;
|
||||||
|
using ShaderConstantVector4 = WallpaperEngine::Core::Objects::Effects::Constants::CShaderConstantVector4;
|
||||||
|
|
||||||
|
using Property = WallpaperEngine::Core::Projects::CProperty;
|
||||||
|
using PropertySharedPtr = std::shared_ptr <Property>;
|
||||||
|
using PropertyWeakPtr = std::weak_ptr <Property>;
|
||||||
|
using Properties = std::map <std::string, PropertySharedPtr>;
|
||||||
|
using DynamicValue = WallpaperEngine::Core::DynamicValues::CDynamicValue;
|
||||||
|
using DynamicValueUniquePtr = std::unique_ptr <DynamicValue>;
|
||||||
|
using DynamicValueSharedPtr = std::shared_ptr <DynamicValue>;
|
||||||
|
using DynamicValueWeakPtr = std::weak_ptr <DynamicValue>;
|
||||||
|
using UserSettingSharedPtr = std::shared_ptr <UserSetting>;
|
||||||
|
using UserSettingWeakPtr = std::weak_ptr <UserSetting>;
|
||||||
|
using ShaderConstantUniquePtr = std::unique_ptr <ShaderConstant>;
|
||||||
|
// TODO: UP TO THIS POINT
|
||||||
|
|
||||||
|
using ShaderConstantMap = std::map <std::string, ShaderConstantUniquePtr>;
|
||||||
|
|
||||||
|
using ProjectSharedPtr = std::shared_ptr <Project>;
|
||||||
|
using WallpaperSharedPtr = std::shared_ptr <Wallpaper>;
|
||||||
|
using WallpaperWeakPtr = std::weak_ptr <Wallpaper>;
|
||||||
|
using ProjectWeakPtr = std::weak_ptr <Project>;
|
||||||
|
using ContainerSharedPtr = std::shared_ptr <Container>;
|
||||||
|
using ContainerWeakPtr = std::weak_ptr <Container>;
|
||||||
|
using SceneSharedPtr = std::shared_ptr <Scene>;
|
||||||
|
using WebSharedPtr = std::shared_ptr <Web>;
|
||||||
|
using VideoSharedPtr = std::shared_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 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 ObjectMap = std::map<int, ObjectUniquePtr>;
|
||||||
|
using ComboMap = std::map<std::string, int>;
|
||||||
|
using TextureMap = std::map<int, std::string>;
|
||||||
|
}
|
31
src/WallpaperEngine/Data/Model/UserSetting.h
Normal file
31
src/WallpaperEngine/Data/Model/UserSetting.h
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
#include <optional>
|
||||||
|
|
||||||
|
#include "Types.h"
|
||||||
|
|
||||||
|
#include "WallpaperEngine/Core/DynamicValues/CDynamicValue.h"
|
||||||
|
#include "WallpaperEngine/Core/Projects/CProperty.h"
|
||||||
|
|
||||||
|
namespace WallpaperEngine::Data::Model {
|
||||||
|
struct ConditionInfo {
|
||||||
|
public:
|
||||||
|
std::string name;
|
||||||
|
std::string condition;
|
||||||
|
};
|
||||||
|
struct UserSetting {
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* The value of this setting, can be a few different things:
|
||||||
|
* - a value connected to the property
|
||||||
|
* - a default value
|
||||||
|
* - a static value
|
||||||
|
*/
|
||||||
|
DynamicValueUniquePtr value;
|
||||||
|
/** The property this setting takes the value from (if specified) */
|
||||||
|
PropertyWeakPtr property;
|
||||||
|
/** Condition required for this setting, this should be possible to run in JS' V8 */
|
||||||
|
std::optional <ConditionInfo> condition;
|
||||||
|
};
|
||||||
|
} // namespace WallpaperEngine::Data::Model
|
119
src/WallpaperEngine/Data/Model/Wallpaper.h
Normal file
119
src/WallpaperEngine/Data/Model/Wallpaper.h
Normal file
@ -0,0 +1,119 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
#include <glm/glm.hpp>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
#include "Types.h"
|
||||||
|
#include "Object.h"
|
||||||
|
#include "WallpaperEngine/Data/Utils/TypeCaster.h"
|
||||||
|
#include "WallpaperEngine/Data/JSON.h"
|
||||||
|
|
||||||
|
namespace WallpaperEngine::Data::Model {
|
||||||
|
using json = WallpaperEngine::Data::JSON::JSON;
|
||||||
|
using TypeCaster = WallpaperEngine::Data::Utils::TypeCaster;
|
||||||
|
|
||||||
|
struct WallpaperData {
|
||||||
|
std::string filename;
|
||||||
|
ProjectWeakPtr project;
|
||||||
|
};
|
||||||
|
|
||||||
|
class Wallpaper : public TypeCaster, public WallpaperData {
|
||||||
|
public:
|
||||||
|
explicit Wallpaper (WallpaperData data) noexcept : WallpaperData (std::move(data)), TypeCaster () {};
|
||||||
|
~Wallpaper () override = default;
|
||||||
|
};
|
||||||
|
|
||||||
|
class Video : public Wallpaper {
|
||||||
|
public:
|
||||||
|
explicit Video (WallpaperData data) noexcept : Wallpaper (std::move(data)) {}
|
||||||
|
|
||||||
|
~Video () override = default;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class Web : public Wallpaper {
|
||||||
|
public:
|
||||||
|
explicit Web (WallpaperData data) noexcept : Wallpaper (std::move(data)) {}
|
||||||
|
|
||||||
|
~Web () override = default;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SceneData {
|
||||||
|
struct {
|
||||||
|
glm::vec3 ambient;
|
||||||
|
glm::vec3 skylight;
|
||||||
|
UserSettingSharedPtr clear;
|
||||||
|
} colors;
|
||||||
|
/**
|
||||||
|
* Camera configuration
|
||||||
|
*/
|
||||||
|
struct {
|
||||||
|
/** 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 */
|
||||||
|
UserSettingSharedPtr enabled;
|
||||||
|
/** Bloom's strength to pass onto the shader */
|
||||||
|
UserSettingSharedPtr strength;
|
||||||
|
/** Bloom's threshold to pass onto the shader */
|
||||||
|
UserSettingSharedPtr threshold;
|
||||||
|
} bloom;
|
||||||
|
/**
|
||||||
|
* Parallax effect configuration
|
||||||
|
*/
|
||||||
|
struct {
|
||||||
|
bool enabled;
|
||||||
|
float amount;
|
||||||
|
float delay;
|
||||||
|
float mouseInfluence;
|
||||||
|
} parallax;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shake effect configuration
|
||||||
|
*/
|
||||||
|
struct {
|
||||||
|
bool enabled;
|
||||||
|
float amplitude;
|
||||||
|
float roughness;
|
||||||
|
float speed;
|
||||||
|
} shake;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Position configuration
|
||||||
|
*/
|
||||||
|
struct {
|
||||||
|
glm::vec3 center;
|
||||||
|
glm::vec3 eye;
|
||||||
|
glm::vec3 up;
|
||||||
|
} configuration;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Projection information
|
||||||
|
*/
|
||||||
|
struct {
|
||||||
|
int width;
|
||||||
|
int height;
|
||||||
|
bool isAuto;
|
||||||
|
} projection;
|
||||||
|
} camera;
|
||||||
|
ObjectMap objects;
|
||||||
|
ProjectWeakPtr project;
|
||||||
|
};
|
||||||
|
|
||||||
|
class Scene : public Wallpaper, public SceneData {
|
||||||
|
public:
|
||||||
|
explicit Scene (WallpaperData data, SceneData sceneData) noexcept : SceneData (std::move(sceneData)), Wallpaper (data) {}
|
||||||
|
|
||||||
|
~Scene () override = default;
|
||||||
|
|
||||||
|
// TODO: ADD OBJECTS HERE
|
||||||
|
};
|
||||||
|
} // namespace WallpaperEngine::Data::Model
|
95
src/WallpaperEngine/Data/Parsers/EffectParser.cpp
Normal file
95
src/WallpaperEngine/Data/Parsers/EffectParser.cpp
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
#include "EffectParser.h"
|
||||||
|
#include "MaterialParser.h"
|
||||||
|
|
||||||
|
#include "WallpaperEngine/Data/Model/Material.h"
|
||||||
|
#include "WallpaperEngine/Data/Model/Effect.h"
|
||||||
|
#include "WallpaperEngine/Data/Model/Project.h"
|
||||||
|
|
||||||
|
using namespace WallpaperEngine::Data::Parsers;
|
||||||
|
using namespace WallpaperEngine::Data::Model;
|
||||||
|
|
||||||
|
EffectUniquePtr EffectParser::load (const ProjectWeakPtr& project, const std::string& filename) {
|
||||||
|
const auto effectJson = JSON::parse (project.lock ()->container.lock ()->readFileAsString (filename));
|
||||||
|
|
||||||
|
return parse (effectJson, project);
|
||||||
|
}
|
||||||
|
|
||||||
|
EffectUniquePtr EffectParser::parse (const JSON& it, const ProjectWeakPtr& project) {
|
||||||
|
const auto dependencies = it.optional ("dependencies");
|
||||||
|
|
||||||
|
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),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector <std::string> EffectParser::parseDependencies (const JSON& it) {
|
||||||
|
std::vector <std::string> result = {};
|
||||||
|
|
||||||
|
if (!it.is_array ()) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const auto& cur : it) {
|
||||||
|
result.push_back (cur);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector <EffectPassUniquePtr> EffectParser::parseEffectPasses (const JSON& it, const ProjectWeakPtr& project) {
|
||||||
|
std::vector <EffectPassUniquePtr> result = {};
|
||||||
|
|
||||||
|
if (!it.is_array ()) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const auto& cur : it) {
|
||||||
|
const auto binds = cur.optional ("binds");
|
||||||
|
std::optional <PassCommand> command = std::nullopt;
|
||||||
|
|
||||||
|
if (cur.contains ("command")) {
|
||||||
|
command = {
|
||||||
|
.command = cur.require <std::string> ("command", "Material command must have a command") == "copy"
|
||||||
|
? Command_Copy
|
||||||
|
: Command_Swap,
|
||||||
|
.target = cur.require <std::string> ("target", "Material command must have a target"),
|
||||||
|
.source = cur.require <std::string> ("source", "Material command must have a source"),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
result.push_back (std::make_unique <EffectPass> (EffectPass {
|
||||||
|
.material = MaterialParser::load (project, cur.require <std::string> ("material", "Effect pass must have a material")),
|
||||||
|
.binds = binds.has_value () ? parseBinds (binds.value ()) : std::map<int, std::string> {},
|
||||||
|
.command = command,
|
||||||
|
// target is a bit special: if the material is a command this will be nullopt
|
||||||
|
// and the actual target will be set in the command itself, otherwise it will
|
||||||
|
// be set to whatever is in the json, which is not required to be present for
|
||||||
|
// normal materials
|
||||||
|
.target = command.has_value () ? std::nullopt : cur.optional <std::string> ("target"),
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::map <int, std::string> EffectParser::parseBinds (const JSON& it) {
|
||||||
|
std::map <int, std::string> result = {};
|
||||||
|
|
||||||
|
if (!it.is_array ()) {
|
||||||
|
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")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
20
src/WallpaperEngine/Data/Parsers/EffectParser.h
Normal file
20
src/WallpaperEngine/Data/Parsers/EffectParser.h
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "WallpaperEngine/Data/JSON.h"
|
||||||
|
#include "WallpaperEngine/Data/Model/Types.h"
|
||||||
|
|
||||||
|
namespace WallpaperEngine::Data::Parsers {
|
||||||
|
using JSON = WallpaperEngine::Data::JSON::JSON;
|
||||||
|
using namespace WallpaperEngine::Data::Model;
|
||||||
|
|
||||||
|
class EffectParser {
|
||||||
|
public:
|
||||||
|
static EffectUniquePtr load (const ProjectWeakPtr& project, const std::string& filename);
|
||||||
|
|
||||||
|
private:
|
||||||
|
static EffectUniquePtr parse (const JSON& it, const ProjectWeakPtr& project);
|
||||||
|
static std::vector <std::string> parseDependencies (const JSON& it);
|
||||||
|
static std::vector <EffectPassUniquePtr> parseEffectPasses (const JSON& it, const ProjectWeakPtr& project);
|
||||||
|
static std::map <int, std::string> parseBinds (const JSON& it);
|
||||||
|
};
|
||||||
|
} // namespace WallpaperEngine::Data::Parsers
|
86
src/WallpaperEngine/Data/Parsers/MaterialParser.cpp
Normal file
86
src/WallpaperEngine/Data/Parsers/MaterialParser.cpp
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
#include "MaterialParser.h"
|
||||||
|
|
||||||
|
#include "WallpaperEngine/Data/Model/Material.h"
|
||||||
|
#include "WallpaperEngine/Data/Model/Project.h"
|
||||||
|
|
||||||
|
using namespace WallpaperEngine::Data::Parsers;
|
||||||
|
using namespace WallpaperEngine::Data::Model;
|
||||||
|
|
||||||
|
MaterialUniquePtr MaterialParser::load (const ProjectWeakPtr& project, const std::string& filename) {
|
||||||
|
const auto materialJson = JSON::parse (project.lock ()->container.lock ()->readFileAsString (filename));
|
||||||
|
|
||||||
|
return parse (materialJson, project, filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
MaterialUniquePtr MaterialParser::parse (const JSON& it, const ProjectWeakPtr& project, const std::string& filename) {
|
||||||
|
return std::make_unique <Material> (Material {
|
||||||
|
.filename = filename,
|
||||||
|
//TODO: PARSE PASSES
|
||||||
|
.passes = parsePasses (it.require ("passes", "Material must have passes to render"), project),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector <MaterialPassUniquePtr> MaterialParser::parsePasses (const JSON& it, const ProjectWeakPtr& project) {
|
||||||
|
std::vector <MaterialPassUniquePtr> result = {};
|
||||||
|
|
||||||
|
if (!it.is_array ()) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const auto& cur : it) {
|
||||||
|
result.push_back (parsePass (cur, project));
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
MaterialPassUniquePtr MaterialParser::parsePass (const JSON& it, const ProjectWeakPtr& project) {
|
||||||
|
const auto textures = it.optional ("textures");
|
||||||
|
const auto combos = it.optional ("combos");
|
||||||
|
const auto constants = it.optional ("constants");
|
||||||
|
|
||||||
|
return std::make_unique <MaterialPass>(MaterialPass {
|
||||||
|
//TODO: REMOVE THIS UGLY STD::STRING CREATION
|
||||||
|
.blending = it.optional ("blending", std::string ("normal")),
|
||||||
|
.cullmode = it.optional ("cullmode", std::string ("disabled")),
|
||||||
|
.depthtest = it.optional ("depthtest", std::string ("disabled")),
|
||||||
|
.depthwrite = it.optional ("depthwrite", std::string ("disabled")),
|
||||||
|
.shader = it.require <std::string> ("shader", "Material pass must have a shader"),
|
||||||
|
.textures = textures.has_value () ? parseTextures (*textures) : std::map <int, std::string> {},
|
||||||
|
.combos = combos.has_value () ? parseCombos (*combos) : std::map <std::string, int> {},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
std::map <int, std::string> MaterialParser::parseTextures (const JSON& it) {
|
||||||
|
std::map <int, std::string> result = {};
|
||||||
|
|
||||||
|
if (!it.is_array ()) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
int index = 0;
|
||||||
|
|
||||||
|
for (const auto& cur : it) {
|
||||||
|
if (!it.is_null ()) {
|
||||||
|
result.emplace (index, cur);
|
||||||
|
}
|
||||||
|
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::map <std::string, int> MaterialParser::parseCombos (const JSON& it) {
|
||||||
|
std::map <std::string, int> result = {};
|
||||||
|
|
||||||
|
if (!it.is_object ()) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const auto& cur : it.items ()) {
|
||||||
|
result.emplace (cur.key (), cur.value ());
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
19
src/WallpaperEngine/Data/Parsers/MaterialParser.h
Normal file
19
src/WallpaperEngine/Data/Parsers/MaterialParser.h
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "WallpaperEngine/Data/JSON.h"
|
||||||
|
#include "WallpaperEngine/Data/Model/Types.h"
|
||||||
|
|
||||||
|
namespace WallpaperEngine::Data::Parsers {
|
||||||
|
using JSON = WallpaperEngine::Data::JSON::JSON;
|
||||||
|
using namespace WallpaperEngine::Data::Model;
|
||||||
|
|
||||||
|
class MaterialParser {
|
||||||
|
public:
|
||||||
|
static MaterialUniquePtr load (const ProjectWeakPtr& project, const std::string& filename);
|
||||||
|
static MaterialUniquePtr parse (const JSON& it, const ProjectWeakPtr& project, const std::string& filename);
|
||||||
|
static std::vector <MaterialPassUniquePtr> parsePasses (const JSON& it, const ProjectWeakPtr& project);
|
||||||
|
static MaterialPassUniquePtr parsePass (const JSON& it, const ProjectWeakPtr& project);
|
||||||
|
static std::map <int, std::string> parseTextures (const JSON& it);
|
||||||
|
static std::map <std::string, int> parseCombos (const JSON& it);
|
||||||
|
};
|
||||||
|
} // namespace WallpaperEngine::Data::Parsers
|
31
src/WallpaperEngine/Data/Parsers/ModelParser.cpp
Normal file
31
src/WallpaperEngine/Data/Parsers/ModelParser.cpp
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
#include "ModelParser.h"
|
||||||
|
#include "MaterialParser.h"
|
||||||
|
|
||||||
|
#include "WallpaperEngine/Data/Model/Model.h"
|
||||||
|
#include "WallpaperEngine/Data/Model/Project.h"
|
||||||
|
#include "WallpaperEngine/Data/Model/Material.h"
|
||||||
|
|
||||||
|
using namespace WallpaperEngine::Data::Parsers;
|
||||||
|
using namespace WallpaperEngine::Data::Model;
|
||||||
|
|
||||||
|
ModelUniquePtr ModelParser::load (const ProjectWeakPtr& project, const std::string& filename) {
|
||||||
|
const auto model = JSON::parse (project.lock ()->container.lock ()->readFileAsString (filename));
|
||||||
|
|
||||||
|
return parse (model, project, filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
ModelUniquePtr ModelParser::parse (const JSON& file, const ProjectWeakPtr& project, const std::string& filename) {
|
||||||
|
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"),
|
||||||
|
});
|
||||||
|
}
|
15
src/WallpaperEngine/Data/Parsers/ModelParser.h
Normal file
15
src/WallpaperEngine/Data/Parsers/ModelParser.h
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "WallpaperEngine/Data/JSON.h"
|
||||||
|
#include "WallpaperEngine/Data/Model/Types.h"
|
||||||
|
|
||||||
|
namespace WallpaperEngine::Data::Parsers {
|
||||||
|
using JSON = WallpaperEngine::Data::JSON::JSON;
|
||||||
|
using namespace WallpaperEngine::Data::Model;
|
||||||
|
|
||||||
|
class ModelParser {
|
||||||
|
public:
|
||||||
|
static ModelUniquePtr load (const ProjectWeakPtr& project, const std::string& filename);
|
||||||
|
static ModelUniquePtr parse (const JSON& file, const ProjectWeakPtr& project, const std::string& filename);
|
||||||
|
};
|
||||||
|
} // namespace WallpaperEngine::Data::Parsers
|
187
src/WallpaperEngine/Data/Parsers/ObjectParser.cpp
Normal file
187
src/WallpaperEngine/Data/Parsers/ObjectParser.cpp
Normal file
@ -0,0 +1,187 @@
|
|||||||
|
#include "ObjectParser.h"
|
||||||
|
#include "ModelParser.h"
|
||||||
|
#include "EffectParser.h"
|
||||||
|
|
||||||
|
#include "ShaderConstantParser.h"
|
||||||
|
#include "WallpaperEngine/Data/Model/Object.h"
|
||||||
|
#include "WallpaperEngine/Data/Model/Project.h"
|
||||||
|
#include "WallpaperEngine/Logging/CLog.h"
|
||||||
|
|
||||||
|
using namespace WallpaperEngine::Data::Parsers;
|
||||||
|
using namespace WallpaperEngine::Data::Model;
|
||||||
|
|
||||||
|
ObjectUniquePtr ObjectParser::parse (const JSON& it, const ProjectWeakPtr& project) {
|
||||||
|
const auto imageIt = it.find ("image");
|
||||||
|
const auto soundIt = it.find ("sound");
|
||||||
|
const auto particleIt = it.find ("particle");
|
||||||
|
const auto textIt = it.find ("text");
|
||||||
|
const auto lightIt = it.find ("light");
|
||||||
|
const auto basedata = ObjectData {
|
||||||
|
.id = it.require <int> ("id", "Object must have an id"),
|
||||||
|
.name = it.require <std::string> ("name", "Object must have a name"),
|
||||||
|
.dependencies = parseDependencies (it),
|
||||||
|
};
|
||||||
|
|
||||||
|
if (imageIt != it.end () && imageIt->is_string ()) {
|
||||||
|
return parseImage (it, project, basedata, *imageIt);
|
||||||
|
} else if (soundIt != it.end () && soundIt->is_array ()) {
|
||||||
|
return parseSound (it, project, basedata);
|
||||||
|
} else if (particleIt != it.end ()) {
|
||||||
|
sLog.error ("Particle objects are not supported yet");
|
||||||
|
} else if (textIt != it.end ()) {
|
||||||
|
sLog.error ("Text objects are not supported yet");
|
||||||
|
} else if (lightIt != it.end ()) {
|
||||||
|
sLog.error ("Light objects are not supported yet");
|
||||||
|
} else {
|
||||||
|
// dump the object for now, might want to change later
|
||||||
|
sLog.exception ("Unknown object type found: ", it.dump ());
|
||||||
|
}
|
||||||
|
|
||||||
|
return std::make_unique <Object> (basedata);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<int> ObjectParser::parseDependencies (const JSON& it) {
|
||||||
|
const auto dependenciesIt = it.find ("dependencies");
|
||||||
|
|
||||||
|
if (dependenciesIt == it.end () || !dependenciesIt->is_array ()) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<int> result = {};
|
||||||
|
|
||||||
|
for (const auto& cur : *dependenciesIt) {
|
||||||
|
result.push_back (cur);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
SoundUniquePtr ObjectParser::parseSound (const JSON& it, const ProjectWeakPtr& project, ObjectData base) {
|
||||||
|
const auto soundIt = it.require ("sound", "Object must have a sound");
|
||||||
|
std::vector<std::string> sounds = {};
|
||||||
|
|
||||||
|
for (const auto& cur : soundIt) {
|
||||||
|
sounds.push_back (cur);
|
||||||
|
}
|
||||||
|
|
||||||
|
return std::make_unique <Sound> (
|
||||||
|
std::move (base),
|
||||||
|
SoundData {
|
||||||
|
.playbackmode = it.optional <std::string> ("playbackmode"),
|
||||||
|
.sounds = sounds,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
ImageUniquePtr ObjectParser::parseImage (
|
||||||
|
const JSON& it, const ProjectWeakPtr& project, ObjectData base, const std::string& image) {
|
||||||
|
const auto& properties = project.lock ()->properties;
|
||||||
|
const auto& effects = it.optional ("effects");
|
||||||
|
|
||||||
|
return std::make_unique <Image> (
|
||||||
|
std::move (base),
|
||||||
|
ImageData {
|
||||||
|
.origin = it.user ("origin", properties, glm::vec3 (0.0f)),
|
||||||
|
.scale = it.user ("scale", properties, glm::vec3 (1.0f)),
|
||||||
|
.angles = it.user ("angles", properties, glm::vec3 (0.0)),
|
||||||
|
.visible = it.user ("visible", properties, true),
|
||||||
|
.alpha = it.user ("alpha", properties, 1.0f),
|
||||||
|
.color = it.user ("color", properties, glm::vec3 (1.0f)),
|
||||||
|
.alignment = it.optional ("alignment", std::string ("center")),
|
||||||
|
.size = it.optional ("size", glm::vec2 (0.0f)),
|
||||||
|
.parallaxDepth = it.optional ("parallaxDepth", glm::vec2 (0.0f)),
|
||||||
|
.colorBlendMode = it.optional ("colorBlendMode", 0),
|
||||||
|
.brightness = it.optional ("brightness", 1.0f),
|
||||||
|
.model = ModelParser::load (project, image),
|
||||||
|
.effects = effects.has_value () ? parseEffects (*effects, project) : std::vector <ImageEffectUniquePtr> {},
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector <ImageEffectUniquePtr> ObjectParser::parseEffects (const JSON& it, const ProjectWeakPtr& project) {
|
||||||
|
if (!it.is_array ()) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector <ImageEffectUniquePtr> result = {};
|
||||||
|
|
||||||
|
for (const auto& cur : it) {
|
||||||
|
result.push_back (parseEffect (cur, project));
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
ImageEffectUniquePtr ObjectParser::parseEffect (const JSON& it, const ProjectWeakPtr& project) {
|
||||||
|
const auto& passsOverrides = it.optional ("passes");
|
||||||
|
return std::make_unique <ImageEffect> (ImageEffect {
|
||||||
|
.id = it.require <int> ("id", "Image effect must have an id"),
|
||||||
|
.name = it.require <std::string> ("name", "Image effect must have a name"),
|
||||||
|
.visible = it.user ("visible", project.lock ()->properties, true),
|
||||||
|
.passOverrides = passsOverrides.has_value () ? parseEffectPassOverrides (passsOverrides.value (), project) : std::vector <ImageEffectPassOverrideUniquePtr> {},
|
||||||
|
.effect = EffectParser::load (project, it.require ("file", "Image effect must have an effect"))
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector <ImageEffectPassOverrideUniquePtr> ObjectParser::parseEffectPassOverrides (const JSON& it, const ProjectWeakPtr& project) {
|
||||||
|
if (!it.is_array ()) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector <ImageEffectPassOverrideUniquePtr> result = {};
|
||||||
|
|
||||||
|
for (const auto& cur : it) {
|
||||||
|
result.push_back (parseEffectPass (cur, project));
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
ImageEffectPassOverrideUniquePtr ObjectParser::parseEffectPass (const JSON& it, const ProjectWeakPtr& project) {
|
||||||
|
const auto& combos = it.optional ("combos");
|
||||||
|
const auto& textures = it.optional ("textures");
|
||||||
|
const auto& constants = it.optional ("constantshadervalues");
|
||||||
|
|
||||||
|
// TODO: PARSE CONSTANT SHADER VALUES AND FIND REFS?
|
||||||
|
return std::make_unique <ImageEffectPassOverride> (ImageEffectPassOverride {
|
||||||
|
.id = it.require <int> ("id", "Image effect pass must have an id"),
|
||||||
|
.combos = combos.has_value () ? parseComboMap (combos.value ()) : ComboMap {},
|
||||||
|
.constants = constants.has_value () ? ShaderConstantParser::parse (constants.value (), project) : ShaderConstantMap {},
|
||||||
|
.textures = textures.has_value () ? parseTextureMap (textures.value ()) : TextureMap {},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
TextureMap ObjectParser::parseTextureMap (const JSON& it) {
|
||||||
|
if (!it.is_array ()) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
TextureMap result = {};
|
||||||
|
int textureIndex = -1;
|
||||||
|
|
||||||
|
for (const auto& cur : it) {
|
||||||
|
textureIndex ++;
|
||||||
|
|
||||||
|
if (cur.is_null ()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
result.emplace (textureIndex, cur);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
ComboMap ObjectParser::parseComboMap (const JSON& it) {
|
||||||
|
if (!it.is_object ()) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
ComboMap result = {};
|
||||||
|
|
||||||
|
for (const auto& cur : it.items ()) {
|
||||||
|
result.emplace (cur.key (), cur.value ());
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
32
src/WallpaperEngine/Data/Parsers/ObjectParser.h
Normal file
32
src/WallpaperEngine/Data/Parsers/ObjectParser.h
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "WallpaperEngine/Data/JSON.h"
|
||||||
|
#include "WallpaperEngine/Data/Model/Object.h"
|
||||||
|
|
||||||
|
namespace WallpaperEngine::Data::Model {
|
||||||
|
struct ObjectData;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace WallpaperEngine::Data::Parsers {
|
||||||
|
using JSON = WallpaperEngine::Data::JSON::JSON;
|
||||||
|
using namespace WallpaperEngine::Data::Model;
|
||||||
|
|
||||||
|
class ObjectParser {
|
||||||
|
public:
|
||||||
|
static ObjectUniquePtr parse (const JSON& it, const ProjectWeakPtr& project);
|
||||||
|
|
||||||
|
private:
|
||||||
|
static std::vector<int> parseDependencies (const JSON& it);
|
||||||
|
static SoundUniquePtr parseSound (const JSON& it, const ProjectWeakPtr& project, ObjectData base);
|
||||||
|
static ImageUniquePtr parseImage (
|
||||||
|
const JSON& it, const ProjectWeakPtr& project, ObjectData base, const std::string& image);
|
||||||
|
static std::vector <ImageEffectUniquePtr> parseEffects (const JSON& it, const ProjectWeakPtr& project);
|
||||||
|
static ImageEffectUniquePtr parseEffect (const JSON& it, const ProjectWeakPtr& project);
|
||||||
|
static std::vector <ImageEffectPassOverrideUniquePtr> parseEffectPassOverrides (const JSON& it, const ProjectWeakPtr& project);
|
||||||
|
static ImageEffectPassOverrideUniquePtr parseEffectPass (const JSON& it, const ProjectWeakPtr& project);
|
||||||
|
static TextureMap parseTextureMap (const JSON& it);
|
||||||
|
static ComboMap parseComboMap (const JSON& it);
|
||||||
|
};
|
||||||
|
} // namespace WallpaperEngine::Data::Parsers
|
68
src/WallpaperEngine/Data/Parsers/ProjectParser.cpp
Normal file
68
src/WallpaperEngine/Data/Parsers/ProjectParser.cpp
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
#include "ProjectParser.h"
|
||||||
|
#include "WallpaperEngine/Logging/CLog.h"
|
||||||
|
|
||||||
|
#include "WallpaperParser.h"
|
||||||
|
|
||||||
|
using namespace WallpaperEngine::Data::Parsers;
|
||||||
|
|
||||||
|
static int backgroundId = 0;
|
||||||
|
|
||||||
|
ProjectSharedPtr ProjectParser::parse (const JSON& data, const ContainerWeakPtr& container) {
|
||||||
|
const auto general = data.optional ("general");
|
||||||
|
auto type = data.require <std::string> ("type", "Project type missing");
|
||||||
|
|
||||||
|
// lowercase for consistency
|
||||||
|
std::transform (type.begin (), type.end (), type.begin (), tolower);
|
||||||
|
|
||||||
|
auto result = std::make_shared <Project> (Project {
|
||||||
|
.title = data.require <std::string> ("title", "Project title missing"),
|
||||||
|
.type = parseType (type),
|
||||||
|
.workshopId = data.optional ("workshopid", std::to_string (--backgroundId)),
|
||||||
|
.supportsAudioProcessing = general.has_value () && general.value ().optional ("supportsAudioProcessing", false),
|
||||||
|
.properties = parseProperties (general),
|
||||||
|
.container = container,
|
||||||
|
});
|
||||||
|
|
||||||
|
result->wallpaper = WallpaperParser::parse (data.require ("file", "Project's main file missing"), result);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
Project::Type ProjectParser::parseType (const std::string& type) {
|
||||||
|
if (type == "scene") {
|
||||||
|
return Project::Type_Scene;
|
||||||
|
} else if (type == "video") {
|
||||||
|
return Project::Type_Video;
|
||||||
|
} else if (type == "web") {
|
||||||
|
return Project::Type_Web;
|
||||||
|
}
|
||||||
|
|
||||||
|
sLog.exception ("Unsupported project type ", type);
|
||||||
|
}
|
||||||
|
|
||||||
|
Properties ProjectParser::parseProperties (const std::optional <JSON>& data) {
|
||||||
|
if (!data.has_value ()) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto properties = data.value ().optional ("properties");
|
||||||
|
|
||||||
|
if (!properties.has_value ()) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
Properties result = {};
|
||||||
|
|
||||||
|
// TODO: CHANGE THIS ONCE THE PROPERTIES PARSING IS HANDLED IN THE NEW TYPES
|
||||||
|
// THESE ARE COMPLEX TYPES THAT INCLUDE SOME RUNTIME INFO THAT ISN'T EXPLICITLY DATA
|
||||||
|
// SO THIS WILL NEED A RETHINK IN THE FUTURE
|
||||||
|
for (const auto& cur : properties.value ().items ()) {
|
||||||
|
const auto& property = Property::fromJSON (cur.value (), cur.key ());
|
||||||
|
|
||||||
|
result.emplace (property->getName (), property);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
24
src/WallpaperEngine/Data/Parsers/ProjectParser.h
Normal file
24
src/WallpaperEngine/Data/Parsers/ProjectParser.h
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <nlohmann/json.hpp>
|
||||||
|
|
||||||
|
#include "WallpaperEngine/Data/JSON.h"
|
||||||
|
#include "WallpaperEngine/Data/Model/Project.h"
|
||||||
|
|
||||||
|
namespace WallpaperEngine::Data::Parsers {
|
||||||
|
using JSON = WallpaperEngine::Data::JSON::JSON;
|
||||||
|
|
||||||
|
using namespace WallpaperEngine::Data::Model;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parses a project file and returns an object representing it
|
||||||
|
*/
|
||||||
|
class ProjectParser {
|
||||||
|
public:
|
||||||
|
static ProjectSharedPtr parse (const JSON& data, const ContainerWeakPtr& container);
|
||||||
|
|
||||||
|
private:
|
||||||
|
static Project::Type parseType (const std::string& type);
|
||||||
|
static Properties parseProperties (const std::optional <JSON>& data);
|
||||||
|
};
|
||||||
|
} // namespace WallpaperEngine::Data::Parsers
|
77
src/WallpaperEngine/Data/Parsers/ShaderConstantParser.cpp
Normal file
77
src/WallpaperEngine/Data/Parsers/ShaderConstantParser.cpp
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
#include "ShaderConstantParser.h"
|
||||||
|
|
||||||
|
#include "WallpaperEngine/Data/Model/Project.h"
|
||||||
|
|
||||||
|
using namespace WallpaperEngine::Data::Parsers;
|
||||||
|
using namespace WallpaperEngine::Data::Model;
|
||||||
|
|
||||||
|
ShaderConstantMap ShaderConstantParser::parse (const JSON& it, const ProjectWeakPtr& project) {
|
||||||
|
if (!it.is_object ()) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
std::map <std::string, ShaderConstantUniquePtr> result = {};
|
||||||
|
|
||||||
|
for (const auto& cur : it.items ()) {
|
||||||
|
result.emplace (cur.key(), parseConstant (cur.value(), project));
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderConstantUniquePtr ShaderConstantParser::parseConstant (const JSON& it, const ProjectWeakPtr& project) {
|
||||||
|
ShaderConstant* constant = nullptr;
|
||||||
|
auto valueIt = it;
|
||||||
|
|
||||||
|
if (it.is_object ()) {
|
||||||
|
auto user = it.find ("user");
|
||||||
|
auto value = it.find ("value");
|
||||||
|
|
||||||
|
if (user == it.end () && value == it.end ()) {
|
||||||
|
sLog.error (R"(Found object for shader constant without "value" and "user" setting)");
|
||||||
|
return ShaderConstantUniquePtr (constant);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (user != it.end () && user->is_string ()) {
|
||||||
|
const auto& properties = project.lock ()->properties;
|
||||||
|
const auto& propertyIt = properties.find (*user);
|
||||||
|
|
||||||
|
if (propertyIt != properties.end ()) {
|
||||||
|
constant = new ShaderConstantProperty (propertyIt->second);
|
||||||
|
} else {
|
||||||
|
sLog.error ("Shader constant pointing to non-existant project property: ", user->get <std::string> ());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
valueIt = *value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: REFACTOR THIS, SAME OLD THING WE HAD BEFORE, THESE SHADERCONSTANT CLASSES HAVE TO GO AND WE SHOULD HAVE JUST ONE
|
||||||
|
if (constant == nullptr) {
|
||||||
|
if (valueIt.is_number_float ()) {
|
||||||
|
constant = new ShaderConstantFloat (valueIt);
|
||||||
|
} else if (valueIt.is_number_integer ()) {
|
||||||
|
constant = new ShaderConstantInteger (valueIt);
|
||||||
|
} else if (valueIt.is_string ()) {
|
||||||
|
// TODO: USE VECTOR PARSER HERE? MAKE USE OF CDYNAMICVALUE FOR SHADERCONSTANTS TOO
|
||||||
|
|
||||||
|
// count the number of spaces to determine which type of vector we have
|
||||||
|
std::string value = valueIt;
|
||||||
|
|
||||||
|
size_t spaces =
|
||||||
|
std::count_if (value.begin (), value.end (), [&] (const auto& item) { return item == ' '; });
|
||||||
|
|
||||||
|
if (spaces == 1) {
|
||||||
|
constant = new ShaderConstantVector2 (valueIt);
|
||||||
|
} else if (spaces == 2) {
|
||||||
|
constant = new ShaderConstantVector3 (valueIt);
|
||||||
|
} else if (spaces == 3) {
|
||||||
|
constant = new ShaderConstantVector4 (valueIt);
|
||||||
|
} else {
|
||||||
|
sLog.exception ("unknown shader constant type ", value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ShaderConstantUniquePtr (constant);
|
||||||
|
}
|
15
src/WallpaperEngine/Data/Parsers/ShaderConstantParser.h
Normal file
15
src/WallpaperEngine/Data/Parsers/ShaderConstantParser.h
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "WallpaperEngine/Data/JSON.h"
|
||||||
|
#include "WallpaperEngine/Data/Model/Types.h"
|
||||||
|
|
||||||
|
namespace WallpaperEngine::Data::Parsers {
|
||||||
|
using JSON = WallpaperEngine::Data::JSON::JSON;
|
||||||
|
using namespace WallpaperEngine::Data::Model;
|
||||||
|
|
||||||
|
class ShaderConstantParser {
|
||||||
|
public:
|
||||||
|
static ShaderConstantMap parse (const JSON& it, const ProjectWeakPtr& project);
|
||||||
|
static ShaderConstantUniquePtr parseConstant (const JSON& it, const ProjectWeakPtr& project);
|
||||||
|
};
|
||||||
|
} // namespace WallpaperEngine::Data::Parsers
|
69
src/WallpaperEngine/Data/Parsers/UserSettingParser.cpp
Normal file
69
src/WallpaperEngine/Data/Parsers/UserSettingParser.cpp
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
#include "UserSettingParser.h"
|
||||||
|
|
||||||
|
#include "WallpaperEngine/Data/Model/UserSetting.h"
|
||||||
|
|
||||||
|
using namespace WallpaperEngine::Data::Parsers;
|
||||||
|
using namespace WallpaperEngine::Data::Builders;
|
||||||
|
|
||||||
|
UserSettingSharedPtr UserSettingParser::parse (const json& data, const Properties& properties) {
|
||||||
|
DynamicValueUniquePtr value = std::make_unique <DynamicValue> ();
|
||||||
|
PropertyWeakPtr property;
|
||||||
|
std::optional<ConditionInfo> condition;
|
||||||
|
auto valueIt = data;
|
||||||
|
|
||||||
|
if (data.is_object ()) {
|
||||||
|
const auto user = data.optional ("user");
|
||||||
|
valueIt = data.require ("value", "User setting must have a value");
|
||||||
|
|
||||||
|
if (user.has_value ()) {
|
||||||
|
std::string source;
|
||||||
|
const auto& it = user.value ();
|
||||||
|
|
||||||
|
if (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;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto propertyIt = properties.find (source);
|
||||||
|
|
||||||
|
if (propertyIt != properties.end ()) {
|
||||||
|
property = propertyIt->second;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// actual value parsing
|
||||||
|
if (valueIt.is_string ()) {
|
||||||
|
std::string str = valueIt;
|
||||||
|
int size = VectorBuilder::preparseSize (str);
|
||||||
|
|
||||||
|
//TODO: VALIDATE THIS IS RIGHT?
|
||||||
|
if (size == 2) {
|
||||||
|
value->update ((glm::vec2) valueIt);
|
||||||
|
} else if (size == 3) {
|
||||||
|
value->update ((glm::vec3) valueIt);
|
||||||
|
} else {
|
||||||
|
value->update ((glm::vec4) valueIt);
|
||||||
|
}
|
||||||
|
} else if (valueIt.is_number_integer ()) {
|
||||||
|
value->update (valueIt.get <int> ());
|
||||||
|
} else if (valueIt.is_number_float ()) {
|
||||||
|
value->update (valueIt.get <float> ());
|
||||||
|
} else if (valueIt.is_boolean ()) {
|
||||||
|
value->update (valueIt.get <bool> ());
|
||||||
|
} else {
|
||||||
|
sLog.exception ("Unsupported user setting type ", valueIt.type_name ());
|
||||||
|
}
|
||||||
|
|
||||||
|
return std::make_shared <UserSetting> (UserSetting {
|
||||||
|
.value = std::move (value),
|
||||||
|
.property = property,
|
||||||
|
.condition = condition,
|
||||||
|
});
|
||||||
|
}
|
16
src/WallpaperEngine/Data/Parsers/UserSettingParser.h
Normal file
16
src/WallpaperEngine/Data/Parsers/UserSettingParser.h
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "WallpaperEngine/Data/JSON.h"
|
||||||
|
#include "WallpaperEngine/Data/Model/Types.h"
|
||||||
|
#include "WallpaperEngine/Data/Model/UserSetting.h"
|
||||||
|
#include "WallpaperEngine/Logging/CLog.h"
|
||||||
|
|
||||||
|
namespace WallpaperEngine::Data::Parsers {
|
||||||
|
using json = WallpaperEngine::Data::JSON::JSON;
|
||||||
|
using namespace WallpaperEngine::Data::Model;
|
||||||
|
|
||||||
|
class UserSettingParser {
|
||||||
|
public:
|
||||||
|
static UserSettingSharedPtr parse (const json& data, const Properties& properties);
|
||||||
|
};
|
||||||
|
} // namespace WallpaperEngine::Data::Parsers
|
106
src/WallpaperEngine/Data/Parsers/WallpaperParser.cpp
Normal file
106
src/WallpaperEngine/Data/Parsers/WallpaperParser.cpp
Normal file
@ -0,0 +1,106 @@
|
|||||||
|
#include "WallpaperParser.h"
|
||||||
|
|
||||||
|
#include "ObjectParser.h"
|
||||||
|
#include "WallpaperEngine/Data/Model/Project.h"
|
||||||
|
#include "WallpaperEngine/Data/Model/Wallpaper.h"
|
||||||
|
#include "WallpaperEngine/Logging/CLog.h"
|
||||||
|
|
||||||
|
using namespace WallpaperEngine::Data::Parsers;
|
||||||
|
|
||||||
|
WallpaperSharedPtr WallpaperParser::parse (const JSON& file, const ProjectWeakPtr& project) {
|
||||||
|
switch (project.lock ()->type) {
|
||||||
|
case Project::Type_Scene:
|
||||||
|
return std::dynamic_pointer_cast <Wallpaper> (parseScene (file, project));
|
||||||
|
case Project::Type_Video:
|
||||||
|
return std::dynamic_pointer_cast <Wallpaper> (parseVideo (file, project));
|
||||||
|
case Project::Type_Web:
|
||||||
|
return std::dynamic_pointer_cast <Wallpaper> (parseWeb (file, project));
|
||||||
|
default:
|
||||||
|
sLog.exception ("Unexpected project type value found... This is likely a bug");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SceneSharedPtr WallpaperParser::parseScene (const JSON& file, const ProjectWeakPtr& project) {
|
||||||
|
const auto scene = JSON::parse (project.lock ()->container.lock ()->readFileAsString (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 objects = scene.require ("objects", "Scenes must have an objects section");
|
||||||
|
const auto& properties = project.lock ()->properties;
|
||||||
|
|
||||||
|
// TODO: FIND IF THESE DEFAULTS ARE SENSIBLE OR NOT AND PERFORM PROPER VALIDATION WHEN CAMERA PREVIEW AND CAMERA
|
||||||
|
// PARALLAX ARE PRESENT
|
||||||
|
|
||||||
|
return std::make_shared <Scene> (
|
||||||
|
WallpaperData {
|
||||||
|
.filename = "",
|
||||||
|
.project = project
|
||||||
|
}, SceneData {
|
||||||
|
.colors = {
|
||||||
|
.ambient = general.optional ("ambientcolor", glm::vec3 (0.0f)),
|
||||||
|
.skylight = general.optional ("skylightcolor", glm::vec3 (0.0f)),
|
||||||
|
.clear = general.user ("clearcolor", properties, glm::vec3 (1.0f)),
|
||||||
|
},
|
||||||
|
.camera = {
|
||||||
|
.fade = general.optional ("camerafade", false),
|
||||||
|
.preview = general.optional ("camerapreview", false),
|
||||||
|
.bloom = {
|
||||||
|
.enabled = general.user ("bloom", properties, false),
|
||||||
|
.strength = general.user ("bloomstrength", properties, 0.0f),
|
||||||
|
.threshold = general.user ("bloomthreshold", properties, 0.0f),
|
||||||
|
},
|
||||||
|
.parallax = {
|
||||||
|
.enabled = general.optional ("cameraparallax", false),
|
||||||
|
.amount = general.optional ("cameraparallaxamount", 1.0f),
|
||||||
|
.delay = general.optional ("cameraparallaxdelay", 0.0f),
|
||||||
|
.mouseInfluence = general.optional ("cameraparallaxmouseinfluence", 1.0f),
|
||||||
|
},
|
||||||
|
.shake = {
|
||||||
|
.enabled = general.optional ("camerashake", false),
|
||||||
|
.amplitude = general.optional ("camerashakeamplitude", 0.0f),
|
||||||
|
.roughness = general.optional ("camerashakeroughness", 0.0f),
|
||||||
|
.speed = general.optional ("camerashakespeed", 0.0f),
|
||||||
|
},
|
||||||
|
.configuration = {
|
||||||
|
.center = camera.require <glm::vec3> ("center", "Camera must have a center position"),
|
||||||
|
.eye = camera.require <glm::vec3> ("eye", "Camera must have an eye position"),
|
||||||
|
.up = camera.require <glm::vec3> ("up", "Camera must have an up position"),
|
||||||
|
},
|
||||||
|
.projection = {
|
||||||
|
.width = projection.require <int> ("width", "Projection must have a width"),
|
||||||
|
.height = projection.require <int> ("height", "Projection must have a height"),
|
||||||
|
.isAuto = projection.optional ("auto", false)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
.objects = parseObjects (objects, project)
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
VideoSharedPtr WallpaperParser::parseVideo (const JSON& file, const ProjectWeakPtr& project) {
|
||||||
|
return std::make_unique <Video> (WallpaperData {
|
||||||
|
.filename = file,
|
||||||
|
.project = project
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
WebSharedPtr WallpaperParser::parseWeb (const JSON& file, const ProjectWeakPtr& project) {
|
||||||
|
return std::make_unique <Web> (WallpaperData {
|
||||||
|
.filename = file,
|
||||||
|
.project = project,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
ObjectMap WallpaperParser::parseObjects (const JSON& objects, const ProjectWeakPtr& project) {
|
||||||
|
ObjectMap result = {};
|
||||||
|
|
||||||
|
for (const auto& cur : objects) {
|
||||||
|
auto object = ObjectParser::parse (cur, project);
|
||||||
|
|
||||||
|
//TODO: DO WE REALLY WANT TO DIRECTLY CONSTRUCT UNIQUE AND SHARED PTRS EVERYWHERE?
|
||||||
|
// SHOULDN'T THAT BE HANDLED BY CALLING CODE (LIKE THIS) INSTEAD?
|
||||||
|
result.emplace (object->id, std::move (object));
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
20
src/WallpaperEngine/Data/Parsers/WallpaperParser.h
Normal file
20
src/WallpaperEngine/Data/Parsers/WallpaperParser.h
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "WallpaperEngine/Data/JSON.h"
|
||||||
|
#include "WallpaperEngine/Data/Model/Types.h"
|
||||||
|
|
||||||
|
namespace WallpaperEngine::Data::Parsers {
|
||||||
|
using JSON = WallpaperEngine::Data::JSON::JSON;
|
||||||
|
using namespace WallpaperEngine::Data::Model;
|
||||||
|
|
||||||
|
class WallpaperParser {
|
||||||
|
public:
|
||||||
|
static WallpaperSharedPtr parse (const JSON& file, const ProjectWeakPtr& project);
|
||||||
|
|
||||||
|
private:
|
||||||
|
static SceneSharedPtr parseScene (const JSON& file, const ProjectWeakPtr& project);
|
||||||
|
static VideoSharedPtr parseVideo (const JSON& file, const ProjectWeakPtr& project);
|
||||||
|
static WebSharedPtr parseWeb (const JSON& file, const ProjectWeakPtr& project);
|
||||||
|
static ObjectMap parseObjects (const JSON& objects, const ProjectWeakPtr& project);
|
||||||
|
};
|
||||||
|
} // namespace WallpaperEngine::Data::Parsers
|
1
src/WallpaperEngine/Data/Utils/TypeCaster.cpp
Normal file
1
src/WallpaperEngine/Data/Utils/TypeCaster.cpp
Normal file
@ -0,0 +1 @@
|
|||||||
|
#include "TypeCaster.h"
|
36
src/WallpaperEngine/Data/Utils/TypeCaster.h
Normal file
36
src/WallpaperEngine/Data/Utils/TypeCaster.h
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdexcept>
|
||||||
|
|
||||||
|
namespace WallpaperEngine::Data::Utils {
|
||||||
|
/**
|
||||||
|
* A simple implementation of type and sub-types casting to be as explicit
|
||||||
|
* as possible while being performant
|
||||||
|
*
|
||||||
|
* Uses typeid from C++17, so base types must have a virtual, default destructor
|
||||||
|
*/
|
||||||
|
class TypeCaster {
|
||||||
|
public:
|
||||||
|
virtual ~TypeCaster() = default;
|
||||||
|
|
||||||
|
template <class T> [[nodiscard]] const T* as () const {
|
||||||
|
if (is<T> ()) {
|
||||||
|
return static_cast <const T*> (this);
|
||||||
|
}
|
||||||
|
|
||||||
|
throw std::bad_cast ();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T> [[nodiscard]] T* as () {
|
||||||
|
if (is<T> ()) {
|
||||||
|
return static_cast <T*> (this);
|
||||||
|
}
|
||||||
|
|
||||||
|
throw std::bad_cast ();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T> [[nodiscard]] bool is () const {
|
||||||
|
return typeid(*this) == typeid(T);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
} // namespace WallpaperEngine::Data::Utils
|
@ -20,6 +20,7 @@ void initLogging () {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int main (int argc, char* argv[]) {
|
int main (int argc, char* argv[]) {
|
||||||
|
try {
|
||||||
// if type parameter is specified, this is a subprocess, so no logging should be enabled from our side
|
// if type parameter is specified, this is a subprocess, so no logging should be enabled from our side
|
||||||
bool enableLogging = true;
|
bool enableLogging = true;
|
||||||
std::string typeZygote = "--type=zygote";
|
std::string typeZygote = "--type=zygote";
|
||||||
@ -63,4 +64,8 @@ int main (int argc, char* argv[]) {
|
|||||||
delete app;
|
delete app;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
} catch (const std::exception& e) {
|
||||||
|
std::cerr << e.what () << std::endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user