refactor: simplified working with properties, constants and shader variables

This commit is contained in:
Almamu 2025-04-19 09:49:21 +02:00
parent 971e50e8bf
commit f312bcdca4
60 changed files with 734 additions and 724 deletions

View File

@ -393,6 +393,9 @@ add_executable(
src/WallpaperEngine/WebBrowser/CWebBrowserContext.cpp
src/WallpaperEngine/WebBrowser/CWebBrowserContext.h
src/WallpaperEngine/Core/DynamicValues/CDynamicValue.cpp
src/WallpaperEngine/Core/DynamicValues/CDynamicValue.h
src/WallpaperEngine/Core/UserSettings/CUserSettingValue.cpp
src/WallpaperEngine/Core/UserSettings/CUserSettingValue.h
src/WallpaperEngine/Core/UserSettings/CUserSettingBoolean.cpp

View File

@ -191,14 +191,14 @@ Core::CProject* CWallpaperApplication::loadBackground (const std::string& bg) {
void CWallpaperApplication::setupPropertiesForProject (const Core::CProject* project) {
// show properties if required
for (const auto [key, cur] : project->getProperties ()) {
for (const auto& [key, cur] : project->getProperties ()) {
// update the value of the property
auto override = this->m_context.settings.general.properties.find (key);
if (override != this->m_context.settings.general.properties.end ()) {
sLog.out ("Applying override value for ", key);
cur->update (override->second);
cur->set (override->second);
}
if (this->m_context.settings.general.onlyListProperties)

View File

@ -34,9 +34,9 @@ const CObject* CObject::fromJSON (
const json& data, const Wallpapers::CScene* scene, const CContainer* container
) {
const auto id = jsonFindRequired <int> (data, "id", "Objects must have id");
const auto visible = jsonFindUserConfig<CUserSettingBoolean> (data, "visible", true);
const auto origin = jsonFindUserConfig<CUserSettingVector3> (data, "origin", {0, 0, 0});
const auto scale = jsonFindUserConfig<CUserSettingVector3> (data, "scale", {1, 1, 1});
const auto visible = jsonFindUserConfig<CUserSettingBoolean> (data, scene->getProject(), "visible", true);
const auto origin = jsonFindUserConfig<CUserSettingVector3> (data, scene->getProject(), "origin", {0, 0, 0});
const auto scale = jsonFindUserConfig<CUserSettingVector3> (data, scene->getProject(), "scale", {1, 1, 1});
const auto angles_val = jsonFindDefault<glm::vec3> (data, "angles", glm::vec3 (0, 0, 0));
const auto name = jsonFindRequired <std::string> (data, "name", "Objects must have name");
const auto effects_it = data.find ("effects");
@ -84,11 +84,11 @@ const CObject* CObject::fromJSON (
}
const glm::vec3& CObject::getOrigin () const {
return this->m_origin->processValue (this->getScene ()->getProject ().getProperties ());
return this->m_origin->getVec3 ();
}
const glm::vec3& CObject::getScale () const {
return this->m_scale->processValue (this->getScene ()->getProject ().getProperties ());
return this->m_scale->getVec3 ();
}
const glm::vec3& CObject::getAngles () const {
@ -104,8 +104,7 @@ const std::vector<int>& CObject::getDependencies () const {
}
bool CObject::isVisible () const {
// TODO: cache this
return this->m_visible->processValue (this->getScene ()->getProject ().getProperties ());
return this->m_visible->getBool ();
}
const Wallpapers::CScene* CObject::getScene () const {

View File

@ -16,7 +16,7 @@ static int backgroundId = -1;
CProject::CProject (
std::string title, std::string type, std::string workshopid, const CContainer* container,
const std::map<std::string, const Projects::CProperty*> properties
const std::map<std::string, Projects::CProperty*> properties
) :
m_workshopid(std::move(workshopid)),
m_title (std::move(title)),
@ -40,7 +40,7 @@ CProject* CProject::fromFile (const std::string& filename, const CContainer* con
const auto file = jsonFindRequired <std::string> (content, "file", "Project's main file missing");
auto general = content.find ("general");
const CWallpaper* wallpaper;
std::map<std::string, const Projects::CProperty*> properties;
std::map<std::string, Projects::CProperty*> properties;
std::transform (type.begin (), type.end (), type.begin (), tolower);
@ -49,7 +49,7 @@ CProject* CProject::fromFile (const std::string& filename, const CContainer* con
if (properties_it != general->end ()) {
for (const auto& cur : properties_it->items ()) {
const auto property = Projects::CProperty::fromJSON (cur.value (), cur.key ());
auto property = Projects::CProperty::fromJSON (cur.value (), cur.key ());
if (property == nullptr) {
continue;
@ -98,7 +98,7 @@ const std::string& CProject::getType () const {
return this->m_type;
}
const std::map<std::string, const Projects::CProperty*>& CProject::getProperties () const {
const std::map<std::string, Projects::CProperty*>& CProject::getProperties () const {
return this->m_properties;
}

View File

@ -1,11 +1,18 @@
#pragma once
#include <map>
#include <nlohmann/json.hpp>
#include "CWallpaper.h"
#include "WallpaperEngine/Core/Core.h"
#include "WallpaperEngine/Core/Projects/CProperty.h"
#include "WallpaperEngine/Assets/CContainer.h"
namespace WallpaperEngine::Core::Projects {
class CProperty;
}
namespace WallpaperEngine::Core {
using json = nlohmann::json;
using namespace WallpaperEngine::Assets;
@ -20,7 +27,7 @@ class CProject {
[[nodiscard]] const std::string& getTitle () const;
[[nodiscard]] const std::string& getType () const;
[[nodiscard]] const std::map<std::string, const Projects::CProperty*>& getProperties () const;
[[nodiscard]] const std::map<std::string, Projects::CProperty*>& getProperties () const;
[[nodiscard]] const std::string& getWorkshopId () const;
const CContainer* getContainer () const;
@ -28,12 +35,12 @@ class CProject {
protected:
CProject (
std::string title, std::string type, std::string workshopid, const CContainer* container,
std::map<std::string, const Projects::CProperty*> properties);
std::map<std::string, Projects::CProperty*> properties);
void setWallpaper (const CWallpaper* wallpaper);
private:
std::map<std::string, const Projects::CProperty*> m_properties;
std::map<std::string, Projects::CProperty*> m_properties;
const std::string m_workshopid;
const std::string m_title;

View File

@ -468,37 +468,40 @@ template const glm::ivec3 Core::jsonFindDefault (const nlohmann::json& data, con
template const glm::ivec4 Core::jsonFindDefault (const nlohmann::json& data, const char* key, const glm::ivec4 defaultValue);
template <typename T> const T* Core::jsonFindUserConfig (
const nlohmann::json::const_iterator& data, const char* key, typename T::data_type defaultValue
const nlohmann::json::const_iterator& data, const CProject& project, const char* key, typename T::data_type defaultValue
) {
const auto it = data->find (key);
if (it == data->end () || it->type () == nlohmann::detail::value_t::null)
return T::fromScalar (defaultValue);
return T::fromJSON (*it);
return T::fromJSON (*it, project);
}
template const CUserSettingBoolean* Core::jsonFindUserConfig (const nlohmann::json::const_iterator& data, const char* key,
CUserSettingBoolean::data_type defaultValue);
template const CUserSettingVector3* Core::jsonFindUserConfig (const nlohmann::json::const_iterator& data, const char* key,
CUserSettingVector3::data_type defaultValue);
template const CUserSettingFloat* Core::jsonFindUserConfig (const nlohmann::json::const_iterator& data, const char* key,
CUserSettingFloat::data_type defaultValue);
template const CUserSettingBoolean* Core::jsonFindUserConfig (
const nlohmann::json::const_iterator& data, const CProject& project, const char* key,
CUserSettingBoolean::data_type defaultValue);
template const CUserSettingVector3* Core::jsonFindUserConfig (
const nlohmann::json::const_iterator& data, const CProject& project, const char* key,
CUserSettingVector3::data_type defaultValue);
template const CUserSettingFloat* Core::jsonFindUserConfig (
const nlohmann::json::const_iterator& data, const CProject& project, const char* key,
CUserSettingFloat::data_type defaultValue);
template <typename T> const T* Core::jsonFindUserConfig (
const nlohmann::json& data, const char* key, typename T::data_type defaultValue
const nlohmann::json& data, const CProject& project, const char* key, typename T::data_type defaultValue
) {
const auto it = data.find (key);
if (it == data.end () || it->type () == nlohmann::detail::value_t::null)
return T::fromScalar (defaultValue);
return T::fromJSON (*it);
return T::fromJSON (*it, project);
}
template const CUserSettingBoolean* Core::jsonFindUserConfig (const nlohmann::json& data, const char* key,
CUserSettingBoolean::data_type defaultValue);
template const CUserSettingVector3* Core::jsonFindUserConfig (const nlohmann::json& data, const char* key,
CUserSettingVector3::data_type defaultValue);
template const CUserSettingFloat* Core::jsonFindUserConfig (const nlohmann::json& data, const char* key,
CUserSettingFloat::data_type defaultValue);
template const CUserSettingBoolean* Core::jsonFindUserConfig (
const nlohmann::json& data, const CProject& project, const char* key, CUserSettingBoolean::data_type defaultValue);
template const CUserSettingVector3* Core::jsonFindUserConfig (
const nlohmann::json& data, const CProject& project, const char* key, CUserSettingVector3::data_type defaultValue);
template const CUserSettingFloat* Core::jsonFindUserConfig (
const nlohmann::json& data, const CProject& project, const char* key, CUserSettingFloat::data_type defaultValue);

View File

@ -1,5 +1,6 @@
#pragma once
#include "CProject.h"
#include <glm/mat4x4.hpp>
#include <glm/vec2.hpp>
#include <glm/vec3.hpp>
@ -7,6 +8,8 @@
#include <string>
namespace WallpaperEngine::Core {
class CProject;
glm::vec4 aToVector4 (const char* str);
glm::vec3 aToVector3 (const char* str);
glm::vec2 aToVector2 (const char* str);
@ -42,7 +45,7 @@ template <typename T> const T jsonFindDefault (
template <typename T> const T jsonFindDefault (
const nlohmann::json& data, const char* key, const T defaultValue);
template <typename T> const T* jsonFindUserConfig (
const nlohmann::json::const_iterator& data, const char* key, typename T::data_type defaultValue);
const nlohmann::json::const_iterator& data, const CProject& project, const char* key, typename T::data_type defaultValue);
template <typename T> const T* jsonFindUserConfig (
const nlohmann::json& data, const char* key, typename T::data_type defaultValue);
const nlohmann::json& data, const CProject& project, const char* key, typename T::data_type defaultValue);
} // namespace WallpaperEngine::Core

View File

@ -0,0 +1,229 @@
#include <algorithm>
#include <stdexcept>
#include "CDynamicValue.h"
using namespace WallpaperEngine::Core::DynamicValues;
CDynamicValue::CDynamicValue() :
m_ivec4(new glm::ivec4()),
m_ivec3(new glm::ivec3()),
m_ivec2(new glm::ivec2()),
m_vec4 (new glm::vec4()),
m_vec3 (new glm::vec3()),
m_vec2 (new glm::vec2()),
m_float (new float()),
m_int (new int()),
m_bool (new bool()),
m_outgoingConnections (),
m_incomingConnections () {}
CDynamicValue::~CDynamicValue() {
for (auto* connection : this->m_incomingConnections) {
connection->destroyOutgoingConnection (this);
}
delete this->m_ivec4;
delete this->m_ivec3;
delete this->m_ivec2;
delete this->m_vec4;
delete this->m_vec3;
delete this->m_vec2;
delete this->m_float;
delete this->m_int;
delete this->m_bool;
}
void CDynamicValue::update(float newValue) {
*this->m_ivec4 = glm::ivec4(static_cast<int> (newValue));
*this->m_ivec3 = glm::ivec3(static_cast<int> (newValue));
*this->m_ivec2 = glm::ivec2(static_cast<int> (newValue));
*this->m_vec4 = glm::vec4(newValue);
*this->m_vec3 = glm::vec3(newValue);
*this->m_vec2 = glm::vec2(newValue);
*this->m_float = newValue;
*this->m_int = static_cast<int> (newValue);
*this->m_bool = static_cast<int> (newValue);
this->propagate ();
}
void CDynamicValue::update(int newValue) {
*this->m_ivec4 = glm::ivec4(newValue);
*this->m_ivec3 = glm::ivec3(newValue);
*this->m_ivec2 = glm::ivec2(newValue);
*this->m_vec4 = glm::vec4(static_cast<float> (newValue));
*this->m_vec3 = glm::vec3(static_cast<float> (newValue));
*this->m_vec2 = glm::vec2(static_cast<float> (newValue));
*this->m_float = static_cast<float> (newValue);
*this->m_int = newValue;
*this->m_bool = newValue;
this->propagate ();
}
void CDynamicValue::update(bool newValue) {
*this->m_ivec4 = glm::ivec4(newValue);
*this->m_ivec3 = glm::ivec3(newValue);
*this->m_ivec2 = glm::ivec2(newValue);
*this->m_vec4 = glm::vec4(newValue);
*this->m_vec3 = glm::vec3(newValue);
*this->m_vec2 = glm::vec2(newValue);
*this->m_float = newValue;
*this->m_int = newValue;
*this->m_bool = newValue;
this->propagate ();
}
void CDynamicValue::update(const glm::vec2& newValue) {
*this->m_ivec4 = glm::ivec4(newValue, 0, 0);
*this->m_ivec3 = glm::ivec3(newValue, 0);
*this->m_ivec2 = glm::ivec2(newValue);
*this->m_vec2 = newValue;
*this->m_vec3 = glm::vec3(newValue, 0.0f);
*this->m_vec4 = glm::vec4(newValue, 0.0f, 0.0f);
*this->m_float = newValue.x;
*this->m_int = static_cast<int> (newValue.x);
*this->m_bool = newValue.x != 0.0f;
this->propagate ();
}
void CDynamicValue::update(const glm::vec3& newValue) {
*this->m_ivec4 = glm::ivec4(newValue, 0);
*this->m_ivec3 = glm::ivec3(newValue);
*this->m_ivec2 = glm::ivec2(newValue);
*this->m_vec2 = glm::vec2(newValue);
*this->m_vec3 = newValue;
*this->m_vec4 = glm::vec4(newValue, 0.0f);
*this->m_float = newValue.x;
*this->m_int = static_cast<int> (newValue.x);
*this->m_bool = newValue.x != 0.0f;
this->propagate ();
}
void CDynamicValue::update(const glm::vec4& newValue) {
*this->m_ivec4 = glm::ivec4(newValue);
*this->m_ivec3 = glm::ivec3(newValue);
*this->m_ivec2 = glm::ivec2(newValue);
*this->m_vec2 = glm::vec2(newValue);
*this->m_vec3 = glm::vec3(newValue);
*this->m_vec4 = newValue;
*this->m_float = newValue.x;
*this->m_int = static_cast<int> (newValue.x);
*this->m_bool = newValue.x != 0.0f;
this->propagate ();
}
void CDynamicValue::update(const glm::ivec2& newValue) {
*this->m_ivec4 = glm::ivec4(newValue, 0, 0);
*this->m_ivec3 = glm::ivec3(newValue, 0);
*this->m_ivec2 = glm::ivec2(newValue);
*this->m_vec2 = newValue;
*this->m_vec3 = glm::vec3(newValue, 0.0f);
*this->m_vec4 = glm::vec4(newValue, 0.0f, 0.0f);
*this->m_float = static_cast<float> (newValue.x);
*this->m_int = static_cast<int> (newValue.x);
*this->m_bool = newValue.x;
this->propagate ();
}
void CDynamicValue::update(const glm::ivec3& newValue) {
*this->m_ivec4 = glm::ivec4(newValue, 0);
*this->m_ivec3 = glm::ivec3(newValue);
*this->m_ivec2 = glm::ivec2(newValue);
*this->m_vec2 = glm::vec2(newValue);
*this->m_vec3 = newValue;
*this->m_vec4 = glm::vec4(newValue, 0.0f);
*this->m_float = static_cast<float> (newValue.x);
*this->m_int = static_cast<int> (newValue.x);
*this->m_bool = newValue.x;
this->propagate ();
}
void CDynamicValue::update(const glm::ivec4& newValue) {
*this->m_ivec4 = glm::ivec4(newValue);
*this->m_ivec3 = glm::ivec3(newValue);
*this->m_ivec2 = glm::ivec2(newValue);
*this->m_vec2 = glm::vec2(newValue);
*this->m_vec3 = glm::vec3(newValue);
*this->m_vec4 = newValue;
*this->m_float = static_cast<float> (newValue.x);
*this->m_int = static_cast<int> (newValue.x);
*this->m_bool = newValue.x;
this->propagate ();
}
void CDynamicValue::connectOutgoing (CDynamicValue* value) const {
this->m_outgoingConnections.push_back (value);
// ensure that new connection has the right value
this->propagate ();
// ensure the other value keeps track of our connection too
value->connectIncoming (this);
}
void CDynamicValue::connectIncoming (const CDynamicValue* value) const {
this->m_incomingConnections.push_back (value);
}
void CDynamicValue::destroyOutgoingConnection (CDynamicValue* value) const {
this->m_outgoingConnections.erase (
std::remove (this->m_outgoingConnections.begin (), this->m_outgoingConnections.end (), value), this->m_outgoingConnections.end ()
);
}
void CDynamicValue::propagate () const {
for (auto* cur : this->m_outgoingConnections) {
*cur->m_bool = *this->m_bool;
*cur->m_int = *this->m_int;
*cur->m_float = *this->m_float;
*cur->m_ivec2 = *this->m_ivec2;
*cur->m_ivec3 = *this->m_ivec3;
*cur->m_ivec4 = *this->m_ivec4;
*cur->m_vec2 = *this->m_vec2;
*cur->m_vec3 = *this->m_vec3;
*cur->m_vec4 = *this->m_vec4;
}
}
const glm::ivec4& CDynamicValue::getIVec4 () const {
return *this->m_ivec4;
}
const glm::ivec3& CDynamicValue::getIVec3 () const {
return *this->m_ivec3;
}
const glm::ivec2& CDynamicValue::getIVec2 () const {
return *this->m_ivec2;
}
const glm::vec4& CDynamicValue::getVec4 () const {
return *this->m_vec4;
}
const glm::vec3& CDynamicValue::getVec3 () const {
return *this->m_vec3;
}
const glm::vec2& CDynamicValue::getVec2 () const {
return *this->m_vec2;
}
const float& CDynamicValue::getFloat () const {
return *this->m_float;
}
const int& CDynamicValue::getInt () const {
return *this->m_int;
}
const bool& CDynamicValue::getBool () const {
return *this->m_bool;
}

View File

@ -0,0 +1,69 @@
#pragma once
#include <functional>
#include <string>
#include <vector>
#include <glm/glm.hpp>
namespace WallpaperEngine::Core::DynamicValues {
class CDynamicValue {
public:
CDynamicValue ();
~CDynamicValue ();
[[nodiscard]] const glm::ivec4& getIVec4 () const;
[[nodiscard]] const glm::ivec3& getIVec3 () const;
[[nodiscard]] const glm::ivec2& getIVec2 () const;
[[nodiscard]] const glm::vec4& getVec4 () const;
[[nodiscard]] const glm::vec3& getVec3 () const;
[[nodiscard]] const glm::vec2& getVec2 () const;
[[nodiscard]] const float& getFloat () const;
[[nodiscard]] const int& getInt () const;
[[nodiscard]] const bool& getBool () const;
/**
* Connects the current instance to the given instance, updating it's values
* based on current instance's changes
*
* @param value
*/
void connectOutgoing (CDynamicValue* value) const;
protected:
void update (float newValue);
void update (int newValue);
void update (bool newValue);
void update (const glm::vec2& newValue);
void update (const glm::vec3& newValue);
void update (const glm::vec4& newValue);
void update (const glm::ivec2& newValue);
void update (const glm::ivec3& newValue);
void update (const glm::ivec4& newValue);
/**
* Registers an incoming connection (another CDynamicValue affecting the current instance's value)
* Useful mainly for destroying the connection on delete
*
* @param value
*/
void connectIncoming (const CDynamicValue* value) const;
void destroyOutgoingConnection (CDynamicValue* value) const;
/**
* Propagates the current value to all it's connections
*/
virtual void propagate () const;
private:
mutable std::vector<CDynamicValue*> m_outgoingConnections;
mutable std::vector<const CDynamicValue*> m_incomingConnections;
// different values that we will be casted to automagically
glm::ivec4* m_ivec4;
glm::ivec3* m_ivec3;
glm::ivec2* m_ivec2;
glm::vec4* m_vec4;
glm::vec3* m_vec3;
glm::vec2* m_vec2;
float* m_float;
int* m_int;
bool* m_bool;
};
};

View File

@ -292,7 +292,7 @@ const Core::CProject& CEffect::getProject () const {
}
bool CEffect::isVisible () const {
return this->m_visible->processValue (this->getProject ().getProperties ());
return this->m_visible->getBool ();
}
const Effects::CFBO* CEffect::findFBO (const std::string& name) {

View File

@ -49,9 +49,14 @@ const WallpaperEngine::Core::CObject* CImage::fromJSON (
if (effects_it != data.end () && effects_it->is_array ()) {
for (auto& cur : *effects_it) {
const auto effectVisible = jsonFindUserConfig<CUserSettingBoolean> (cur, "visible", true);
const auto effectVisible = jsonFindUserConfig<CUserSettingBoolean> (cur, scene->getProject(), "visible", true);
if (!effectVisible->processValue (scene->getProject ().getProperties ()))
// TODO: USER CANNOT MODIFY VALUES ON THE FLY, BUT IT MIGHT BE INTERESTING TO SUPPORT THAT AT SOME POINT?
// TODO: AT LEAST THE ORIGINAL SOFTWARE ALLOWS YOU TO DO THAT IN THE PREVIEW WINDOW
// TODO: THAT MIGHT INCREASE COMPLEXITY THO...
// TODO: ESPECIALLY IF THAT CHANGES RENDERING OF PASSES/IMAGES
// TODO: DECISIONS, DECISIONS, DECISIONS...
if (!effectVisible->getBool ())
continue;
effects.push_back (
@ -73,8 +78,8 @@ const WallpaperEngine::Core::CObject* CImage::fromJSON (
angles,
jsonFindDefault<glm::vec2> (data, "size", glm::vec2 (0.0, 0.0)),
jsonFindDefault<std::string> (data, "alignment", "center"),
jsonFindUserConfig<CUserSettingVector3> (data, "color", {1, 1, 1}),
jsonFindUserConfig<CUserSettingFloat> (data, "alpha", 1.0),
jsonFindUserConfig<CUserSettingVector3> (data, scene->getProject(), "color", {1, 1, 1}),
jsonFindUserConfig<CUserSettingFloat> (data, scene->getProject(), "alpha", 1.0),
jsonFindDefault<float> (data, "brightness", 1.0),
jsonFindDefault<uint32_t> (data, "colorBlendMode", 0),
jsonFindDefault<glm::vec2> (data, "parallaxDepth", glm::vec2 (0.0, 0.0)),
@ -99,11 +104,11 @@ const std::string& CImage::getAlignment () const {
}
float CImage::getAlpha () const {
return this->m_alpha->processValue (this->getScene ()->getProject ().getProperties ());
return this->m_alpha->getFloat ();
}
const glm::vec3& CImage::getColor () const {
return this->m_color->processValue (this->getScene ()->getProject ().getProperties ());
return this->m_color->getVec3 ();
}
float CImage::getBrightness () const {

View File

@ -1,13 +1,14 @@
#pragma once
#include <string>
#include <cassert>
#include <string>
#include "WallpaperEngine/Core/DynamicValues/CDynamicValue.h"
namespace WallpaperEngine::Core::Objects::Effects::Constants {
/**
* Shader constants base class
*/
class CShaderConstant {
class CShaderConstant : public DynamicValues::CDynamicValue {
public:
explicit CShaderConstant (std::string type);

View File

@ -3,15 +3,12 @@
using namespace WallpaperEngine::Core::Objects::Effects::Constants;
CShaderConstantFloat::CShaderConstantFloat (float value) :
CShaderConstant (Type),
m_value (value) {}
const float* CShaderConstantFloat::getValue () const {
return &this->m_value;
CShaderConstant (Type) {
this->update (value);
}
std::string CShaderConstantFloat::toString () const {
return std::to_string (this->m_value);
return std::to_string (this->getFloat ());
}
const std::string CShaderConstantFloat::Type = "float";

View File

@ -12,19 +12,11 @@ class CShaderConstantFloat : public CShaderConstant {
public:
explicit CShaderConstantFloat (float value);
/**
* @return A pointer to the actual value of the constant
*/
[[nodiscard]] const float* getValue () const;
/**
* Type string indicator
*/
static const std::string Type;
[[nodiscard]] std::string toString () const override;
protected:
/** The constant's value */
const float m_value;
};
} // namespace WallpaperEngine::Core::Objects::Effects::Constants

View File

@ -3,15 +3,12 @@
using namespace WallpaperEngine::Core::Objects::Effects::Constants;
CShaderConstantInteger::CShaderConstantInteger (int32_t value) :
CShaderConstant (Type),
m_value (value) {}
const int32_t* CShaderConstantInteger::getValue () const {
return &this->m_value;
CShaderConstant (Type) {
this->update (value);
}
std::string CShaderConstantInteger::toString () const {
return std::to_string (this->m_value);
return std::to_string (this->getInt ());
}
const std::string CShaderConstantInteger::Type = "int";

View File

@ -12,19 +12,11 @@ class CShaderConstantInteger : public CShaderConstant {
public:
explicit CShaderConstantInteger (int32_t value);
/**
* @return A pointer to the actual value of the constant
*/
[[nodiscard]] const int32_t* getValue () const;
/**
* Type string indicator
*/
static const std::string Type;
[[nodiscard]] std::string toString () const override;
protected:
/** The constant's value */
const int32_t m_value;
};
} // namespace WallpaperEngine::Core::Objects::Effects::Constants

View File

@ -1,13 +1,11 @@
#include "WallpaperEngine/Core/DynamicValues/CDynamicValue.h"
#include "CShaderConstantProperty.h"
using namespace WallpaperEngine::Core::Objects::Effects::Constants;
CShaderConstantProperty::CShaderConstantProperty (const CProperty* property) :
CShaderConstant (Type),
m_property (property) {}
const CProperty* CShaderConstantProperty::getProperty () const {
return this->m_property;
CShaderConstant (Type) {
property->connectOutgoing (this);
}
std::string CShaderConstantProperty::toString () const {

View File

@ -13,25 +13,13 @@ using namespace WallpaperEngine::Core::Projects;
*/
class CShaderConstantProperty : public CShaderConstant {
public:
// TODO: SUPPORT DEFAULT VALUE?
explicit CShaderConstantProperty (const CProperty* property);
/**
* @return The property this points to
*/
[[nodiscard]] const CProperty* getProperty () const;
/**
* Type string indicator
*/
static const std::string Type;
[[nodiscard]] std::string toString () const override;
protected:
/**
* The backing property
*/
const CProperty* m_property;
};
} // namespace WallpaperEngine::Core::Objects::Effects::Constants

View File

@ -3,19 +3,16 @@
using namespace WallpaperEngine::Core::Objects::Effects::Constants;
CShaderConstantVector2::CShaderConstantVector2 (glm::vec2 value) :
CShaderConstant (Type),
m_value (value) {}
const glm::vec2* CShaderConstantVector2::getValue () const {
return &this->m_value;
CShaderConstant (Type) {
this->update (value);
}
std::string CShaderConstantVector2::toString () const {
std::string result = "(";
result.append (std::to_string (this->m_value.x));
result.append (std::to_string (this->getVec2 ().x));
result.append (",");
result.append (std::to_string (this->m_value.y));
result.append (std::to_string (this->getVec2 ().y));
result.append (")");
return result;

View File

@ -14,19 +14,11 @@ class CShaderConstantVector2 : public CShaderConstant {
public:
explicit CShaderConstantVector2 (glm::vec2 value);
/**
* @return A pointer to the actual value of the constant
*/
[[nodiscard]] const glm::vec2* getValue () const;
/**
* Type string indicator
*/
static const std::string Type;
[[nodiscard]] std::string toString () const override;
protected:
/** The constant's value */
const glm::vec2 m_value;
};
} // namespace WallpaperEngine::Core::Objects::Effects::Constants

View File

@ -3,21 +3,18 @@
using namespace WallpaperEngine::Core::Objects::Effects::Constants;
CShaderConstantVector3::CShaderConstantVector3 (glm::vec3 value) :
CShaderConstant (Type),
m_value (value) {}
const glm::vec3* CShaderConstantVector3::getValue () const {
return &this->m_value;
CShaderConstant (Type) {
this->update (value);
}
std::string CShaderConstantVector3::toString () const {
std::string result = "(";
result.append (std::to_string (this->m_value.x));
result.append (std::to_string (this->getVec3 ().x));
result.append (",");
result.append (std::to_string (this->m_value.y));
result.append (std::to_string (this->getVec3 ().y));
result.append (",");
result.append (std::to_string (this->m_value.z));
result.append (std::to_string (this->getVec3 ().z));
result.append (")");
return result;

View File

@ -13,19 +13,11 @@ class CShaderConstantVector3 : public CShaderConstant {
public:
explicit CShaderConstantVector3 (glm::vec3 value);
/**
* @return A pointer to the actual value of the constant
*/
[[nodiscard]] const glm::vec3* getValue () const;
/**
* Type string indicator
*/
static const std::string Type;
[[nodiscard]] std::string toString () const override;
protected:
/** The constant's value */
const glm::vec3 m_value;
};
} // namespace WallpaperEngine::Core::Objects::Effects::Constants

View File

@ -3,23 +3,20 @@
using namespace WallpaperEngine::Core::Objects::Effects::Constants;
CShaderConstantVector4::CShaderConstantVector4 (glm::vec4 value) :
CShaderConstant (Type),
m_value (value) {}
const glm::vec4* CShaderConstantVector4::getValue () const {
return &this->m_value;
CShaderConstant (Type) {
this->update (value);
}
std::string CShaderConstantVector4::toString () const {
std::string result = "(";
result.append (std::to_string (this->m_value.x));
result.append (std::to_string (this->getVec4 ().x));
result.append (",");
result.append (std::to_string (this->m_value.y));
result.append (std::to_string (this->getVec4 ().y));
result.append (",");
result.append (std::to_string (this->m_value.z));
result.append (std::to_string (this->getVec4 ().z));
result.append (",");
result.append (std::to_string (this->m_value.w));
result.append (std::to_string (this->getVec4 ().w));
result.append (")");
return result;

View File

@ -13,19 +13,11 @@ class CShaderConstantVector4 : public CShaderConstant {
public:
explicit CShaderConstantVector4 (glm::vec4 value);
/**
* @return A pointer to the actual value of the constant
*/
[[nodiscard]] const glm::vec4* getValue () const;
/**
* Type string indicator
*/
static const std::string Type;
[[nodiscard]] std::string toString () const override;
protected:
/** The constant's value */
const glm::vec4 m_value;
};
} // namespace WallpaperEngine::Core::Objects::Effects::Constants

View File

@ -10,7 +10,7 @@
using namespace WallpaperEngine::Core::Projects;
const CProperty* CProperty::fromJSON (const json& data, const std::string& name) {
CProperty* CProperty::fromJSON (const json& data, const std::string& name) {
const auto type = jsonFindRequired (data, "type", "Project properties must have the type field");
if (*type == CPropertyColor::Type)
@ -36,6 +36,18 @@ CProperty::CProperty (std::string name, std::string type, std::string text) :
m_name (std::move(name)),
m_text (std::move(text)) {}
void CProperty::subscribe (const function_type& callback) const {
this->m_subscriptions.push_back (callback);
}
void CProperty::propagate () const {
CDynamicValue::propagate ();
for (const auto& callback : this->m_subscriptions) {
callback(this);
}
}
const std::string& CProperty::getName () const {
return this->m_name;
}

View File

@ -1,34 +1,34 @@
#pragma once
#include "WallpaperEngine/Core/DynamicValues/CDynamicValue.h"
#include "WallpaperEngine/Core/Core.h"
namespace WallpaperEngine::Core::Projects {
using json = nlohmann::json;
using namespace WallpaperEngine::Core::DynamicValues;
/**
* Represents a property in a background
*
* Properties are settings that alter how the background looks or works
* and are configurable by the user so they can customize it to their likings
*/
class CPropertyColor;
class CProperty {
class CProperty : public CDynamicValue {
public:
typedef std::function<void(const CProperty*)> function_type;
virtual ~CProperty () = default;
static const CProperty* fromJSON (const json& data, const std::string& name);
static CProperty* fromJSON (const json& data, const std::string& name);
template <class T> const T* as () const {
template <class T> [[nodiscard]] const T* as () const {
assert (is<T> ());
return reinterpret_cast<const T*> (this);
}
template <class T> T* as () {
template <class T> [[nodiscard]] T* as () {
assert (is<T> ());
return reinterpret_cast<T*> (this);
}
template <class T> bool is () const {
template <class T> [[nodiscard]] bool is () const {
return this->m_type == T::Type;
}
@ -41,8 +41,7 @@ class CProperty {
*
* @param value New value for the property
*/
virtual void update (const std::string& value) const = 0;
virtual void set (const std::string& value) = 0;
/**
* @return Name of the property
*/
@ -55,10 +54,20 @@ class CProperty {
* @return Text of the property
*/
[[nodiscard]] const std::string& getText () const;
/**
* Registers a function to be called when this instance's value changes
*
* @param callback
*/
void subscribe (const function_type& callback) const;
protected:
void propagate () const override;
CProperty (std::string name, std::string type, std::string text);
/** Functions to call when this property's value changes */
mutable std::vector<function_type> m_subscriptions;
/** Type of property */
const std::string m_type;
/** Name of the property */

View File

@ -6,7 +6,7 @@
using namespace WallpaperEngine::Core::Projects;
const CPropertyBoolean* CPropertyBoolean::fromJSON (const json& data, std::string name) {
CPropertyBoolean* CPropertyBoolean::fromJSON (const json& data, std::string name) {
return new CPropertyBoolean (
jsonFindRequired <bool> (data, "value", "Boolean property must have a value"),
std::move(name),
@ -14,12 +14,9 @@ const CPropertyBoolean* CPropertyBoolean::fromJSON (const json& data, std::strin
);
}
bool CPropertyBoolean::getValue () const {
return this->m_value;
}
void CPropertyBoolean::update (const std::string& value) const {
this->m_value = value == "1" || value == "true";
void CPropertyBoolean::set (const std::string& value) {
this->update (value == "1" || value == "true" || value == "on");
}
std::string CPropertyBoolean::dump () const {
@ -29,13 +26,12 @@ std::string CPropertyBoolean::dump () const {
<< "\t"
<< "Description: " << this->m_text << std::endl
<< "\t"
<< "Value: " << this->m_value;
<< "Value: " << &this->getBool ();
return ss.str ();
}
CPropertyBoolean::CPropertyBoolean (bool value, std::string name, std::string text) :
CProperty (std::move(name), Type, std::move(text)),
m_value (value) {}
CProperty (std::move(name), Type, std::move(text)) {}
const std::string CPropertyBoolean::Type = "bool";

View File

@ -10,23 +10,16 @@ using json = nlohmann::json;
*/
class CPropertyBoolean final : public CProperty {
public:
static const CPropertyBoolean* fromJSON (const json& data, std::string name);
static CPropertyBoolean* fromJSON (const json& data, std::string name);
/**
* @return The value of the property
*/
[[nodiscard]] bool getValue () const;
/** @inheritdoc */
[[nodiscard]] std::string dump () const override;
/** @inheritdoc */
void update (const std::string& value) const override;
void set (const std::string& value) override;
static const std::string Type;
private:
CPropertyBoolean (bool value, std::string name, std::string text);
/** Property's value */
mutable bool m_value;
};
} // namespace WallpaperEngine::Core::Projects

View File

@ -6,6 +6,7 @@
using namespace WallpaperEngine::Core::Projects;
glm::vec3 ParseColor (std::string value) {
// TODO: ENSURE THIS PARSING IS ACTUALLY ACCURATE
if (value.find (',') != std::string::npos) {
// replace commas with dots so it can be parsed
std::replace (value.begin (), value.end (), ',', ' ');
@ -20,35 +21,33 @@ glm::vec3 ParseColor (std::string value) {
return WallpaperEngine::Core::aToColorf (value);
}
const CPropertyColor* CPropertyColor::fromJSON (const json& data, std::string name) {
const std::string value = *jsonFindRequired (data, "value", "Color property must have a value");
CPropertyColor* CPropertyColor::fromJSON (const json& data, std::string name) {
const auto value = jsonFindRequired <std::string> (data, "value", "Color property must have a value");
const auto text = jsonFindDefault<std::string> (data, "text", "");
return new CPropertyColor (ParseColor (value), std::move(name), text);
return new CPropertyColor (value, std::move(name), text);
}
const glm::vec3& CPropertyColor::getValue () const {
return this->m_color;
}
void CPropertyColor::update (const std::string& value) const {
this->m_color = ParseColor (std::string (value));
void CPropertyColor::set (const std::string& value) {
this->update (ParseColor (std::string (value)));
}
std::string CPropertyColor::dump () const {
const auto color = this->getVec3 ();
std::stringstream ss;
ss << this->m_name << " - color" << std::endl
<< "\t"
<< "Description: " << this->m_text << std::endl
<< "\t"
<< "R: " << this->m_color.r << " G: " << this->m_color.g << " B: " << this->m_color.b;
<< "R: " << color.r << " G: " << color.g << " B: " << color.b;
return ss.str ();
}
CPropertyColor::CPropertyColor (glm::vec3 color, std::string name, std::string text) :
CProperty (std::move(name), Type, std::move(text)),
m_color (color) {}
CPropertyColor::CPropertyColor (const std::string& color, std::string name, std::string text) :
CProperty (std::move(name), Type, std::move(text)) {
this->set (color);
}
const std::string CPropertyColor::Type = "color";

View File

@ -12,20 +12,14 @@ using json = nlohmann::json;
*/
class CPropertyColor final : public CProperty {
public:
static const CPropertyColor* fromJSON (const json& data, std::string name);
static CPropertyColor* fromJSON (const json& data, std::string name);
/**
* @return The RGB color value in the 0-1 range
*/
[[nodiscard]] const glm::vec3& getValue () const;
[[nodiscard]] std::string dump () const override;
void update (const std::string& value) const override;
void set (const std::string& value) override;
static const std::string Type;
private:
CPropertyColor (glm::vec3 color, std::string name, std::string text);
mutable glm::vec3 m_color;
CPropertyColor (const std::string& color, std::string name, std::string text);
};
} // namespace WallpaperEngine::Core::Projects

View File

@ -8,7 +8,7 @@
using namespace WallpaperEngine::Core::Projects;
const CPropertyCombo* CPropertyCombo::fromJSON (const json& data, std::string name) {
CPropertyCombo* CPropertyCombo::fromJSON (const json& data, std::string name) {
std::vector<const CPropertyComboValue*> values;
const auto options = jsonFindRequired (data, "options", "Options for a property combo is required");
@ -32,27 +32,24 @@ const CPropertyCombo* CPropertyCombo::fromJSON (const json& data, std::string na
return new CPropertyCombo (
std::move(name),
jsonFindDefault<std::string> (data, "text", ""),
jsonFindRequired (data, "value", "Value is required for a property combo")->dump (),
jsonFindRequired<std::string> (data, "value", "Value is required for a property combo"),
values
);
}
CPropertyCombo::CPropertyCombo (
std::string name, std::string text, std::string defaultValue, std::vector<const CPropertyComboValue*> values
std::string name, std::string text, const std::string& defaultValue, std::vector<const CPropertyComboValue*> values
) :
CProperty (std::move(name), Type, std::move(text)),
m_defaultValue (std::move(defaultValue)),
m_values (std::move(values)) {}
m_values (std::move(values)) {
this->set (defaultValue);
}
CPropertyCombo::~CPropertyCombo () {
for (const auto* value : this->m_values)
delete value;
}
const std::string& CPropertyCombo::getValue () const {
return this->m_defaultValue;
}
std::string CPropertyCombo::dump () const {
std::stringstream ss;
@ -60,7 +57,7 @@ std::string CPropertyCombo::dump () const {
<< "\t"
<< "Description: " << this->m_text << std::endl
<< "\t"
<< "Value: " << this->m_defaultValue << std::endl
<< "Value: " << &this->getInt () << std::endl
<< "\t\t"
<< "Posible values:" << std::endl;
@ -70,21 +67,45 @@ std::string CPropertyCombo::dump () const {
return ss.str ();
}
void CPropertyCombo::update (const std::string& value) const {
void CPropertyCombo::set (const std::string& value) {
bool found = false;
int index = 0;
// ensure the value is present somewhere in the value list
for (const auto cur : this->m_values) {
if (cur->value != value)
continue;
if (cur->value == value) {
found = true;
break;
}
found = true;
index ++;
}
if (!found)
sLog.exception ("Assigning invalid value to property ", this->m_name);
this->m_defaultValue = value;
this->update (index);
}
int CPropertyCombo::translateValueToIndex (const std::string& value) const {
bool found = false;
int index = 0;
// ensure the value is present somewhere in the value list
for (const auto cur : this->m_values) {
if (cur->value == value) {
found = true;
break;
}
index ++;
}
if (!found) {
return -1;
}
return index;
}
const std::string CPropertyCombo::Type = "combo";

View File

@ -23,26 +23,21 @@ class CPropertyComboValue {
*/
class CPropertyCombo final : public CProperty {
public:
static const CPropertyCombo* fromJSON (const json& data, std::string name);
static CPropertyCombo* fromJSON (const json& data, std::string name);
~CPropertyCombo () override;
/**
* @return The selected value
*/
[[nodiscard]] const std::string& getValue () const;
[[nodiscard]] std::string dump () const override;
void update (const std::string& value) const override;
void set (const std::string& value) override;
int translateValueToIndex (const std::string& value) const;
static const std::string Type;
private:
CPropertyCombo (
std::string name, std::string text, std::string defaultValue, std::vector<const CPropertyComboValue*> values);
std::string name, std::string text, const std::string& defaultValue, std::vector<const CPropertyComboValue*> values);
/** List of values available to select */
const std::vector<const CPropertyComboValue*> m_values;
/** The default value */
mutable std::string m_defaultValue;
};
} // namespace WallpaperEngine::Core::Projects

View File

@ -4,29 +4,25 @@
using namespace WallpaperEngine::Core::Projects;
const CPropertySlider* CPropertySlider::fromJSON (const json& data, const std::string& name) {
CPropertySlider* CPropertySlider::fromJSON (const json& data, const std::string& name) {
const auto value = data.find ("value");
const auto text = jsonFindDefault<std::string> (data, "text", "");
const auto min = jsonFindDefault (data, "min", 0.0);
const auto max = jsonFindDefault (data, "max", 0.0);
const auto step = jsonFindDefault (data, "step", 0.0);
const auto min = jsonFindDefault (data, "min", 0.0f);
const auto max = jsonFindDefault (data, "max", 0.0f);
const auto step = jsonFindDefault (data, "step", 0.0f);
return new CPropertySlider (*value, name, text, min, max, step);
}
const double& CPropertySlider::getValue () const {
return this->m_value;
}
const double& CPropertySlider::getMinValue () const {
const float& CPropertySlider::getMinValue () const {
return this->m_min;
}
const double& CPropertySlider::getMaxValue () const {
const float& CPropertySlider::getMaxValue () const {
return this->m_max;
}
const double& CPropertySlider::getStep () const {
const float& CPropertySlider::getStep () const {
return this->m_step;
}
@ -37,7 +33,7 @@ std::string CPropertySlider::dump () const {
<< "\t"
<< "Description: " << this->m_text << std::endl
<< "\t"
<< "Value: " << this->m_value << std::endl
<< "Value: " << &this->getFloat () << std::endl
<< "\t"
<< "Minimum value: " << this->m_min << std::endl
<< "\t"
@ -48,21 +44,22 @@ std::string CPropertySlider::dump () const {
return ss.str ();
}
void CPropertySlider::update (const std::string& value) const {
const auto newValue = strtod (value.c_str (), nullptr);
void CPropertySlider::set (const std::string& value) {
const auto newValue = strtof (value.c_str (), nullptr);
if (newValue < this->m_min || newValue > this->m_max)
sLog.exception ("Slider value (", newValue, ") is out of range (", this->m_min, ",", this->m_max, ")");
this->m_value = newValue;
this->update (newValue);
}
CPropertySlider::CPropertySlider (double value, const std::string& name, const std::string& text, double min,
double max, double step) :
CPropertySlider::CPropertySlider (float value, const std::string& name, const std::string& text, float min,
float max, float step) :
CProperty (name, Type, text),
m_value (value),
m_min (min),
m_max (max),
m_step (step) {}
m_step (step) {
this->update (value);
}
const std::string CPropertySlider::Type = "slider";

View File

@ -12,39 +12,33 @@ using json = nlohmann::json;
*/
class CPropertySlider final : public CProperty {
public:
static const CPropertySlider* fromJSON (const json& data, const std::string& name);
static CPropertySlider* fromJSON (const json& data, const std::string& name);
/**
* @return The slider's value
*/
[[nodiscard]] const double& getValue () const;
/**
* @return The slider's minimum value
*/
[[nodiscard]] const double& getMinValue () const;
[[nodiscard]] const float& getMinValue () const;
/**
* @return The slider's maximum value
*/
[[nodiscard]] const double& getMaxValue () const;
[[nodiscard]] const float& getMaxValue () const;
/**
* @return The slider's value increment steps, only really used in the UI
*/
[[nodiscard]] const double& getStep () const;
[[nodiscard]] const float& getStep () const;
[[nodiscard]] std::string dump () const override;
void update (const std::string& value) const override;
void set (const std::string& value) override;
static const std::string Type;
private:
CPropertySlider (double value, const std::string& name, const std::string& text, double min, double max, double step);
CPropertySlider (float value, const std::string& name, const std::string& text, float min, float max, float step);
/** Actual slider value */
mutable double m_value;
/** Minimum value */
const double m_min;
const float m_min;
/** Maximum value */
const double m_max;
const float m_max;
/** Increment steps for the slider in the UI */
const double m_step;
const float m_step;
};
} // namespace WallpaperEngine::Core::Projects

View File

@ -5,7 +5,8 @@
using namespace WallpaperEngine::Core::Projects;
const CPropertyText* CPropertyText::fromJSON (const json& data, std::string name) {
CPropertyText* CPropertyText::fromJSON (const json& data, std::string name) {
//TODO: VALIDATE THIS IS RIGHT
const auto text = data.find ("type");
return new CPropertyText (std::move(name), *text);
@ -21,10 +22,11 @@ std::string CPropertyText::dump () const {
return ss.str ();
}
void CPropertyText::update (const std::string& value) const {
void CPropertyText::set (const std::string& value) {
this->m_text = value;
}
CPropertyText::CPropertyText (std::string name, std::string text) : CProperty (std::move(name), Type, std::move(text)) {}
CPropertyText::CPropertyText (std::string name, std::string text) :
CProperty (std::move(name), Type, std::move(text)) {}
const std::string CPropertyText::Type = "text";

View File

@ -10,9 +10,9 @@ using json = nlohmann::json;
*/
class CPropertyText final : public CProperty {
public:
static const CPropertyText* fromJSON (const json& data, std::string name);
static CPropertyText* fromJSON (const json& data, std::string name);
[[nodiscard]] std::string dump () const override;
void update (const std::string& value) const override;
void set (const std::string& value) override;
static const std::string Type;

View File

@ -3,6 +3,7 @@
#include <utility>
#include "WallpaperEngine/Core/Core.h"
#include "WallpaperEngine/Core/CProject.h"
#include "WallpaperEngine/Core/Projects/CProperty.h"
#include "WallpaperEngine/Core/Projects/CPropertyBoolean.h"
#include "WallpaperEngine/Core/Projects/CPropertyCombo.h"
@ -15,24 +16,37 @@ using namespace WallpaperEngine::Core::Projects;
using namespace WallpaperEngine::Core::UserSettings;
CUserSettingBoolean::CUserSettingBoolean (
bool hasCondition,bool hasSource, bool defaultValue, std::string source, std::string expectedValue
bool hasCondition, bool defaultValue, const Projects::CProperty* source, std::string expectedValue
) :
CUserSettingValue (Type),
m_default (defaultValue),
m_hasCondition (hasCondition),
m_hasSource (hasSource),
m_source (std::move(source)),
m_expectedValue (std::move(expectedValue)) {}
m_source (source),
m_expectedValue (std::move(expectedValue)) {
this->update (defaultValue);
const CUserSettingBoolean* CUserSettingBoolean::fromJSON (const nlohmann::json& data) {
if (this->m_source != nullptr) {
this->m_source->subscribe ([this](const Projects::CProperty* property) -> void {
if (!this->m_hasCondition) {
this->update (property->getBool ());
} else if (property->is <CPropertyCombo> ()) {
this->update (
property->as <CPropertyCombo> ()->translateValueToIndex (this->m_expectedValue) == property->getInt ()
);
} else {
sLog.error ("Cannot update boolean user setting for an unknown property type ", property->getType ());
}
});
}
}
const CUserSettingBoolean* CUserSettingBoolean::fromJSON (const nlohmann::json& data, const CProject& project) {
bool hasCondition = false;
bool hasSource = false;
const Projects::CProperty* sourceProperty = nullptr;
bool defaultValue;
std::string source;
std::string expectedValue;
if (data.is_object ()) {
hasSource = true;
auto userIt = data.find ("user");
defaultValue = jsonFindDefault (data, "value", true); // is this default value right?
@ -45,6 +59,17 @@ const CUserSettingBoolean* CUserSettingBoolean::fromJSON (const nlohmann::json&
expectedValue =
jsonFindRequired <std::string> (userIt, "condition", "Condition for conditional setting must be present");
}
for (const auto& [key, property] : project.getProperties ()) {
if (key == source) {
sourceProperty = property;
break;
}
}
if (sourceProperty == nullptr) {
sLog.error ("Cannot find property ", source, " to get value from for user setting value, using default value: ", defaultValue);
}
} else {
sLog.error ("Boolean property doesn't have user member, this could mean an scripted value");
}
@ -55,37 +80,11 @@ const CUserSettingBoolean* CUserSettingBoolean::fromJSON (const nlohmann::json&
defaultValue = data.get<bool> ();
}
return new CUserSettingBoolean (hasCondition, hasSource, defaultValue, source, expectedValue);
return new CUserSettingBoolean (hasCondition, defaultValue, sourceProperty, expectedValue);
}
const CUserSettingBoolean* CUserSettingBoolean::fromScalar (const bool value) {
return new CUserSettingBoolean (false, false, value, "", "");
}
bool CUserSettingBoolean::getDefaultValue () const {
return this->m_default;
}
bool CUserSettingBoolean::processValue (const std::map<std::string, const Projects::CProperty*>& properties) const {
if (!this->m_hasSource && !this->m_hasCondition)
return this->getDefaultValue ();
const auto property = properties.find (this->m_source);
if (property != properties.end ()) {
if (!this->m_hasCondition) {
if (property->second->is<CPropertyBoolean> ())
return property->second->as<CPropertyBoolean> ()->getValue ();
}
// TODO: properly validate this as the combos might be more than just strings?
if (property->second->is<CPropertyCombo> ())
return property->second->as<CPropertyCombo> ()->getValue () == this->m_expectedValue;
sLog.exception ("Boolean property with condition doesn't match against combo value");
}
return this->m_default;
return new CUserSettingBoolean (false, value, nullptr, "");
}
std::string CUserSettingBoolean::Type = "boolean";

View File

@ -1,6 +1,7 @@
#pragma once
#include "CUserSettingValue.h"
#include "WallpaperEngine/Core/CProject.h"
namespace WallpaperEngine::Core::Projects {
class CProperty;
@ -11,21 +12,16 @@ class CUserSettingBoolean : public CUserSettingValue {
public:
typedef bool data_type;
static const CUserSettingBoolean* fromJSON (const nlohmann::json& data);
static const CUserSettingBoolean* fromJSON (const nlohmann::json& data, const CProject& project);
static const CUserSettingBoolean* fromScalar (const bool value);
static std::string Type;
[[nodiscard]] bool processValue (const std::map<std::string, const Projects::CProperty*>& properties) const;
[[nodiscard]] bool getDefaultValue () const;
private:
CUserSettingBoolean (
bool hasCondition, bool hasSource, bool defaultValue, std::string source, std::string expectedValue);
bool hasCondition, bool defaultValue, const Projects::CProperty* source, std::string expectedValue);
const bool m_default;
const bool m_hasCondition;
const bool m_hasSource;
const std::string m_source;
const std::string m_expectedValue;
const Projects::CProperty* m_source;
};
} // namespace WallpaperEngine::Core::UserSettings

View File

@ -3,6 +3,7 @@
#include <utility>
#include "WallpaperEngine/Core/Core.h"
#include "WallpaperEngine/Core/CProject.h"
#include "WallpaperEngine/Core/Projects/CProperty.h"
#include "WallpaperEngine/Core/Projects/CPropertySlider.h"
#include "WallpaperEngine/Logging/CLog.h"
@ -12,26 +13,36 @@ using namespace WallpaperEngine::Core::Projects;
using namespace WallpaperEngine::Core::UserSettings;
CUserSettingFloat::CUserSettingFloat (
bool hasCondition, bool hasSource, double defaultValue, std::string source, std::string expectedValue
bool hasCondition, float defaultValue, const Projects::CProperty* source, std::string expectedValue
) :
CUserSettingValue (Type),
m_default (defaultValue),
m_hasCondition (hasCondition),
m_hasSource (hasSource),
m_source (std::move(source)),
m_expectedValue (std::move(expectedValue)) {}
m_source (source),
m_expectedValue (std::move(expectedValue)) {
this->update (defaultValue);
const CUserSettingFloat* CUserSettingFloat::fromJSON (const nlohmann::json& data) {
double defaultValue;
if (this->m_source != nullptr) {
this->m_source->subscribe ([this](const Projects::CProperty* property) -> void {
if (!this->m_hasCondition) {
this->update (property->getFloat ());
} else {
sLog.error ("Don't know how to check for condition on a float property... Expected value: ", this->m_expectedValue);
}
});
}
}
const CUserSettingFloat* CUserSettingFloat::fromJSON (const nlohmann::json& data, const CProject& project) {
float defaultValue;
std::string source;
std::string expectedValue;
bool hasCondition = false;
bool hasSource = false;
const Projects::CProperty* sourceProperty = nullptr;
if (data.is_object ()) {
hasSource = true;
auto userIt = data.find ("user");
defaultValue = jsonFindDefault (data, "value", 1.0); // is this default value right?
defaultValue = jsonFindDefault (data, "value", 1.0f); // is this default value right?
if (userIt != data.end ()) {
if (userIt->is_string ()) {
@ -42,6 +53,17 @@ const CUserSettingFloat* CUserSettingFloat::fromJSON (const nlohmann::json& data
expectedValue =
jsonFindRequired <std::string> (userIt, "condition", "Condition for conditional setting must be present");
}
for (const auto& [key, property] : project.getProperties ()) {
if (key == source) {
sourceProperty = property;
break;
}
}
if (sourceProperty == nullptr) {
sLog.error ("Cannot find property ", source, " to get value from for user setting value, using default value: ", defaultValue);
}
} else {
sLog.error ("Float property doesn't have user member, this could mean an scripted value");
}
@ -49,38 +71,14 @@ const CUserSettingFloat* CUserSettingFloat::fromJSON (const nlohmann::json& data
if (!data.is_number ())
sLog.exception ("Expected numeric value on user settings");
defaultValue = data.get<double> ();
defaultValue = data.get<float> ();
}
return new CUserSettingFloat (hasCondition, hasSource, defaultValue, source, expectedValue);
return new CUserSettingFloat (hasCondition, defaultValue, sourceProperty, expectedValue);
}
const CUserSettingFloat* CUserSettingFloat::fromScalar (const double value) {
return new CUserSettingFloat (false, false, value, "", "");
}
double CUserSettingFloat::getDefaultValue () const {
return this->m_default;
}
double CUserSettingFloat::processValue (const std::map<std::string, const Projects::CProperty*>& properties) const {
if (!this->m_hasSource && !this->m_hasCondition)
return this->getDefaultValue ();
const auto property = properties.find (this->m_source);
if (property != properties.end ()) {
if (!this->m_hasCondition) {
if (property->second->is<CPropertySlider> ())
return property->second->as<CPropertySlider> ()->getValue ();
sLog.exception ("Property without condition must match type (slider)");
}
sLog.exception ("Float property with condition doesn't match against combo value");
}
return this->m_default;
const CUserSettingFloat* CUserSettingFloat::fromScalar (const float value) {
return new CUserSettingFloat (false, value, nullptr, "");
}
std::string CUserSettingFloat::Type = "float";

View File

@ -1,6 +1,7 @@
#pragma once
#include "CUserSettingValue.h"
#include "WallpaperEngine/Core/CProject.h"
namespace WallpaperEngine::Core::Projects {
class CProperty;
@ -9,23 +10,19 @@ class CProperty;
namespace WallpaperEngine::Core::UserSettings {
class CUserSettingFloat : public CUserSettingValue {
public:
typedef double data_type;
typedef float data_type;
static const CUserSettingFloat* fromJSON (const nlohmann::json& data);
static const CUserSettingFloat* fromScalar (const double value);
static const CUserSettingFloat* fromJSON (const nlohmann::json& data, const CProject& project);
static const CUserSettingFloat* fromScalar (const float value);
static std::string Type;
[[nodiscard]] double processValue (const std::map<std::string, const Projects::CProperty*>& properties) const;
[[nodiscard]] double getDefaultValue () const;
private:
CUserSettingFloat (
bool hasCondition, bool hasSource, double defaultValue, std::string source, std::string expectedValue);
bool hasCondition, float defaultValue, const Projects::CProperty* source, std::string expectedValue);
const double m_default;
const bool m_hasCondition;
const bool m_hasSource;
const std::string m_source;
const Projects::CProperty* m_source;
const std::string m_expectedValue;
};
} // namespace WallpaperEngine::Core::UserSettings

View File

@ -2,20 +2,24 @@
#include <nlohmann/json.hpp>
#include "WallpaperEngine/Core/DynamicValues/CDynamicValue.h"
namespace WallpaperEngine::Core::UserSettings {
class CUserSettingValue {
using namespace WallpaperEngine::Core::DynamicValues;
class CUserSettingValue : public CDynamicValue {
public:
template <class T> const T* as () const {
template <class T> [[nodiscard]] const T* as () const {
assert (is<T> ());
return reinterpret_cast<const T*> (this);
}
template <class T> T* as () {
template <class T> [[nodiscard]] T* as () {
assert (is<T> ());
return reinterpret_cast<T*> (this);
}
template <class T> bool is () const {
template <class T> [[nodiscard]] bool is () const {
return this->m_type == T::Type;
}

View File

@ -13,24 +13,34 @@ using namespace WallpaperEngine::Core::Projects;
using namespace WallpaperEngine::Core::UserSettings;
CUserSettingVector3::CUserSettingVector3 (
bool hasCondition, bool hasSource, glm::vec3 defaultValue, std::string source, std::string expectedValue
bool hasCondition, glm::vec3 defaultValue, const Projects::CProperty* source, std::string expectedValue
) :
CUserSettingValue (Type),
m_default (defaultValue),
m_hasCondition (hasCondition),
m_hasSource (hasSource),
m_source (std::move(source)),
m_expectedValue (std::move(expectedValue)) {}
m_source (source),
m_expectedValue (std::move(expectedValue)) {
this->update (defaultValue);
const CUserSettingVector3* CUserSettingVector3::fromJSON (const nlohmann::json& data) {
if (this->m_source != nullptr) {
this->m_source->subscribe ([this](const Projects::CProperty* property) -> void {
if (this->m_hasCondition) {
sLog.error ("Don't know how to check for condition on a float property... Expected value: ", this->m_expectedValue);
return;
}
this->update (property->getVec3 ());
});
}
}
const CUserSettingVector3* CUserSettingVector3::fromJSON (const nlohmann::json& data, const CProject& project) {
bool hasCondition = false;
bool hasSource = false;
const Projects::CProperty* sourceProperty = nullptr;
glm::vec3 defaultValue;
std::string source;
std::string expectedValue;
if (data.is_object ()) {
hasSource = true;
auto userIt = data.find ("user");
defaultValue = jsonFindDefault (data, "value", glm::vec3()); // is this default value right?
@ -43,6 +53,17 @@ const CUserSettingVector3* CUserSettingVector3::fromJSON (const nlohmann::json&
expectedValue =
jsonFindRequired <std::string> (userIt, "condition", "Condition for conditional setting must be present");
}
for (const auto& [key, property] : project.getProperties ()) {
if (key == source) {
sourceProperty = property;
break;
}
}
if (sourceProperty == nullptr) {
sLog.error ("Cannot find property ", source, " to get value from for user setting value, using default value: (", defaultValue.x, ",", defaultValue.y, ",", defaultValue.z, ")");
}
} else {
sLog.error ("Vector property doesn't have user member, this could mean an scripted value");
}
@ -53,38 +74,11 @@ const CUserSettingVector3* CUserSettingVector3::fromJSON (const nlohmann::json&
defaultValue = WallpaperEngine::Core::aToColorf (data.get<std::string> ().c_str ());
}
return new CUserSettingVector3 (hasCondition, hasSource, defaultValue, source, expectedValue);
return new CUserSettingVector3 (hasCondition, defaultValue, sourceProperty, expectedValue);
}
const CUserSettingVector3* CUserSettingVector3::fromScalar (const glm::vec3 value) {
return new CUserSettingVector3 (false, false, value, "", "");
}
const glm::vec3& CUserSettingVector3::getDefaultValue () const {
return this->m_default;
}
const glm::vec3& CUserSettingVector3::processValue (const std::map<std::string, const Projects::CProperty*>& properties) const {
if (!this->m_hasSource && !this->m_hasCondition)
return this->getDefaultValue ();
const auto property = properties.find (this->m_source);
if (property != properties.end ()) {
if (!this->m_hasCondition) {
if (property->second->is<CPropertyColor> ())
return property->second->as<CPropertyColor> ()->getValue ();
if (property->second->is<CPropertySlider> ())
return {property->second->as<CPropertySlider> ()->getValue (), property->second->as<CPropertySlider> ()->getValue (),
property->second->as<CPropertySlider> ()->getValue ()};
sLog.exception ("Property without condition must match type (vector3)");
}
sLog.exception ("Vector property with condition doesn't match against combo value");
}
return this->m_default;
return new CUserSettingVector3 (false, value, nullptr, "");
}
std::string CUserSettingVector3::Type = "color";

View File

@ -3,6 +3,7 @@
#include <glm/vec3.hpp>
#include "CUserSettingValue.h"
#include "WallpaperEngine/Core/CProject.h"
namespace WallpaperEngine::Core::Projects {
class CProperty;
@ -13,21 +14,16 @@ class CUserSettingVector3 : public CUserSettingValue {
public:
typedef glm::vec3 data_type;
static const CUserSettingVector3* fromJSON (const nlohmann::json& data);
static const CUserSettingVector3* fromJSON (const nlohmann::json& data, const CProject& project);
static const CUserSettingVector3* fromScalar (const glm::vec3 value);
static std::string Type;
[[nodiscard]] const glm::vec3& processValue (const std::map<std::string, const Projects::CProperty*>& properties) const;
[[nodiscard]] const glm::vec3& getDefaultValue () const;
private:
CUserSettingVector3 (
bool hasCondition, bool hasSource, glm::vec3 defaultValue, std::string source, std::string expectedValue);
bool hasCondition, glm::vec3 defaultValue, const Projects::CProperty* source, std::string expectedValue);
const glm::vec3 m_default;
const bool m_hasCondition;
const bool m_hasSource;
const std::string m_source;
const Projects::CProperty* m_source;
const std::string m_expectedValue;
};
} // namespace WallpaperEngine::Core::UserSettings

View File

@ -11,9 +11,9 @@ using namespace WallpaperEngine::Core::Wallpapers;
CScene::CScene (
const CProject& project, const CContainer* container, const Scenes::CCamera* camera, glm::vec3 ambientColor,
const CUserSettingBoolean* bloom, const CUserSettingFloat* bloomStrength, const CUserSettingFloat* bloomThreshold,
bool cameraFade, bool cameraParallax, double cameraParallaxAmount, double cameraParallaxDelay,
double cameraParallaxMouseInfluence, bool cameraPreview, bool cameraShake, double cameraShakeAmplitude,
double cameraShakeRoughness, double cameraShakeSpeed, const CUserSettingVector3* clearColor,
bool cameraFade, bool cameraParallax, float cameraParallaxAmount, float cameraParallaxDelay,
float cameraParallaxMouseInfluence, bool cameraPreview, bool cameraShake, float cameraShakeAmplitude,
float cameraShakeRoughness, float cameraShakeSpeed, const CUserSettingVector3* clearColor,
const Scenes::CProjection* orthogonalProjection, glm::vec3 skylightColor
) :
CWallpaper (Type, project),
@ -50,20 +50,20 @@ const CScene* CScene::fromFile (const std::string& filename, const CProject& pro
project, container,
Scenes::CCamera::fromJSON (jsonFindRequired (content, "camera", "Scenes must have a defined camera")),
jsonFindDefault<glm::vec3> (*general_it, "ambientcolor", glm::vec3 (0, 0, 0)),
jsonFindUserConfig<CUserSettingBoolean> (*general_it, "bloom", false),
jsonFindUserConfig<CUserSettingFloat> (*general_it, "bloomstrength", 0.0),
jsonFindUserConfig<CUserSettingFloat> (*general_it, "bloomthreshold", 0.0),
jsonFindUserConfig<CUserSettingBoolean> (*general_it, project, "bloom", false),
jsonFindUserConfig<CUserSettingFloat> (*general_it, project, "bloomstrength", 0.0),
jsonFindUserConfig<CUserSettingFloat> (*general_it, project, "bloomthreshold", 0.0),
jsonFindDefault<bool> (*general_it, "camerafade", false),
jsonFindDefault<bool> (*general_it, "cameraparallax", true),
jsonFindDefault<double> (*general_it, "cameraparallaxamount", 1.0f),
jsonFindDefault<double> (*general_it, "cameraparallaxdelay", 0.0f),
jsonFindDefault<double> (*general_it, "cameraparallaxmouseinfluence", 1.0f),
jsonFindDefault<float> (*general_it, "cameraparallaxamount", 1.0f),
jsonFindDefault<float> (*general_it, "cameraparallaxdelay", 0.0f),
jsonFindDefault<float> (*general_it, "cameraparallaxmouseinfluence", 1.0f),
jsonFindDefault<bool> (*general_it, "camerapreview", false),
jsonFindDefault<bool> (*general_it, "camerashake", false),
jsonFindDefault<double> (*general_it, "camerashakeamplitude", 0.0f),
jsonFindDefault<double> (*general_it, "camerashakeroughness", 0.0f),
jsonFindDefault<double> (*general_it, "camerashakespeed", 0.0f),
jsonFindUserConfig<CUserSettingVector3> (*general_it, "clearcolor", {1, 1, 1}),
jsonFindDefault<float> (*general_it, "camerashakeamplitude", 0.0f),
jsonFindDefault<float> (*general_it, "camerashakeroughness", 0.0f),
jsonFindDefault<float> (*general_it, "camerashakespeed", 0.0f),
jsonFindUserConfig<CUserSettingVector3> (*general_it, project, "clearcolor", {1, 1, 1}),
Scenes::CProjection::fromJSON (jsonFindRequired (*general_it, "orthogonalprojection", "General section must have orthogonal projection info")),
jsonFindDefault<glm::vec3> (*general_it, "skylightcolor", glm::vec3 (0, 0, 0))
);
@ -103,15 +103,15 @@ const glm::vec3& CScene::getAmbientColor () const {
}
bool CScene::isBloom () const {
return this->m_bloom->processValue (this->getProject ().getProperties ());
return this->m_bloom->getBool ();
}
double CScene::getBloomStrength () const {
return this->m_bloomStrength->processValue (this->getProject ().getProperties ());
float CScene::getBloomStrength () const {
return this->m_bloomStrength->getFloat ();
}
double CScene::getBloomThreshold () const {
return this->m_bloomThreshold->processValue (this->getProject ().getProperties ());
float CScene::getBloomThreshold () const {
return this->m_bloomThreshold->getFloat ();
}
bool CScene::isCameraFade () const {
@ -122,15 +122,15 @@ bool CScene::isCameraParallax () const {
return this->m_cameraParallax;
}
double CScene::getCameraParallaxAmount () const {
float CScene::getCameraParallaxAmount () const {
return this->m_cameraParallaxAmount;
}
double CScene::getCameraParallaxDelay () const {
float CScene::getCameraParallaxDelay () const {
return this->m_cameraParallaxDelay;
}
double CScene::getCameraParallaxMouseInfluence () const {
float CScene::getCameraParallaxMouseInfluence () const {
return this->m_cameraParallaxMouseInfluence;
}
@ -142,20 +142,20 @@ bool CScene::isCameraShake () const {
return this->m_cameraShake;
}
double CScene::getCameraShakeAmplitude () const {
float CScene::getCameraShakeAmplitude () const {
return this->m_cameraShakeAmplitude;
}
double CScene::getCameraShakeRoughness () const {
float CScene::getCameraShakeRoughness () const {
return this->m_cameraShakeRoughness;
}
double CScene::getCameraShakeSpeed () const {
float CScene::getCameraShakeSpeed () const {
return this->m_cameraShakeSpeed;
}
const glm::vec3& CScene::getClearColor () const {
return this->m_clearColor->processValue (this->getProject ().getProperties ());
return this->m_clearColor->getVec3 ();
}
const Scenes::CProjection* CScene::getOrthogonalProjection () const {

View File

@ -24,18 +24,18 @@ class CScene : public CWallpaper {
[[nodiscard]] const glm::vec3& getAmbientColor () const;
[[nodiscard]] bool isBloom () const;
[[nodiscard]] double getBloomStrength () const;
[[nodiscard]] double getBloomThreshold () const;
[[nodiscard]] float getBloomStrength () const;
[[nodiscard]] float getBloomThreshold () const;
[[nodiscard]] bool isCameraFade () const;
[[nodiscard]] bool isCameraParallax () const;
[[nodiscard]] double getCameraParallaxAmount () const;
[[nodiscard]] double getCameraParallaxDelay () const;
[[nodiscard]] double getCameraParallaxMouseInfluence () const;
[[nodiscard]] float getCameraParallaxAmount () const;
[[nodiscard]] float getCameraParallaxDelay () const;
[[nodiscard]] float getCameraParallaxMouseInfluence () const;
[[nodiscard]] bool isCameraPreview () const;
[[nodiscard]] bool isCameraShake () const;
[[nodiscard]] double getCameraShakeAmplitude () const;
[[nodiscard]] double getCameraShakeRoughness () const;
[[nodiscard]] double getCameraShakeSpeed () const;
[[nodiscard]] float getCameraShakeAmplitude () const;
[[nodiscard]] float getCameraShakeRoughness () const;
[[nodiscard]] float getCameraShakeSpeed () const;
[[nodiscard]] const glm::vec3& getClearColor () const;
[[nodiscard]] const Scenes::CProjection* getOrthogonalProjection () const;
[[nodiscard]] const glm::vec3& getSkylightColor () const;
@ -47,9 +47,9 @@ class CScene : public CWallpaper {
CScene (
const CProject& project, const CContainer* container, const Scenes::CCamera* camera, glm::vec3 ambientColor,
const CUserSettingBoolean* bloom, const CUserSettingFloat* bloomStrength, const CUserSettingFloat* bloomThreshold,
bool cameraFade, bool cameraParallax, double cameraParallaxAmount, double cameraParallaxDelay,
double cameraParallaxMouseInfluence, bool cameraPreview, bool cameraShake, double cameraShakeAmplitude,
double cameraShakeRoughness, double cameraShakeSpeed, const CUserSettingVector3* clearColor,
bool cameraFade, bool cameraParallax, float cameraParallaxAmount, float cameraParallaxDelay,
float cameraParallaxMouseInfluence, bool cameraPreview, bool cameraShake, float cameraShakeAmplitude,
float cameraShakeRoughness, float cameraShakeSpeed, const CUserSettingVector3* clearColor,
const Scenes::CProjection* orthogonalProjection, glm::vec3 skylightColor);
static const std::string Type;
@ -69,14 +69,14 @@ class CScene : public CWallpaper {
const CUserSettingFloat* m_bloomThreshold;
const bool m_cameraFade;
const bool m_cameraParallax;
const double m_cameraParallaxAmount;
const double m_cameraParallaxDelay;
const double m_cameraParallaxMouseInfluence;
const float m_cameraParallaxAmount;
const float m_cameraParallaxDelay;
const float m_cameraParallaxMouseInfluence;
const bool m_cameraPreview;
const bool m_cameraShake;
const double m_cameraShakeAmplitude;
const double m_cameraShakeRoughness;
const double m_cameraShakeSpeed;
const float m_cameraShakeAmplitude;
const float m_cameraShakeRoughness;
const float m_cameraShakeSpeed;
const CUserSettingVector3* m_clearColor;
const Scenes::CProjection* m_orthogonalProjection;
const glm::vec3 m_skylightColor;

View File

@ -708,156 +708,35 @@ void CPass::setupShaderVariables () {
// get one instance of it
CShaderVariable* var = parameters.vertex == nullptr ? parameters.fragment : parameters.vertex;
// ensure the shader's and the constant are of the same type
if (value->getType () == var->getType ()) {
this->addUniform (var->getName (), value);
continue;
}
// there's situations where this type mismatch is actually expected
// integers and floats are equivalent, this could be detected at load time
// but that'd mean to compile the shader in the load, and not on the render stage
// so take into account these conversions here
if (value->is<CShaderConstantFloat> () && var->is<CShaderVariableInteger> ()) {
// create an integer value from a float
this->addUniform (var->getName (), static_cast<int> (*value->as<CShaderConstantFloat> ()->getValue ()));
} else if (value->is<CShaderConstantInteger> () && var->is<CShaderVariableFloat> ()) {
// create a float value from an integer
this->addUniform (var->getName (), static_cast<float> (*value->as<CShaderConstantInteger> ()->getValue ()));
} else if (value->is<CShaderConstantVector4> () && var->is<CShaderVariableVector2> ()) {
auto* val = value->as<CShaderConstantVector4> ();
// create a new vector2 with the first two values
this->addUniform (var->getName (), {val->getValue ()->x, val->getValue ()->y});
} else if (value->is<CShaderConstantVector4> () && var->is<CShaderVariableVector3> ()) {
auto* val = value->as<CShaderConstantVector4> ();
this->addUniform (var->getName (), {val->getValue ()->x, val->getValue ()->y, val->getValue ()->z});
} else if (value->is<CShaderConstantVector3> () && var->is<CShaderVariableVector2> ()) {
auto* val = value->as<CShaderConstantVector3> ();
this->addUniform (var->getName (), {val->getValue ()->x, val->getValue ()->y});
} else if (value->is<CShaderConstantProperty> ()) {
const auto property = value->as<CShaderConstantProperty> ();
this->addUniform (var, property->getProperty ());
} else {
sLog.exception ("Constant ", name,
" type does not match pixel/vertex shader variable and cannot be converted (",
value->getType (), " to ", var->getType ());
}
// this takes care of all possible casts, even invalid ones, which will use whatever default behaviour
// of the underlying CDynamicValue used for the value
this->addUniform (var, value);
}
}
// define some basic methods for the template
void CPass::addUniform (CShaderVariable* value) {
if (value->is<CShaderVariableFloat> ())
this->addUniform (value->getName (),
static_cast<const float*> (value->as<CShaderVariableFloat> ()->getValue ()));
else if (value->is<CShaderVariableInteger> ())
this->addUniform (value->getName (),
static_cast<const int*> (value->as<CShaderVariableInteger> ()->getValue ()));
else if (value->is<CShaderVariableVector2> ())
this->addUniform (value->getName (),
static_cast<const glm::vec2*> (value->as<CShaderVariableVector2> ()->getValue ()));
else if (value->is<CShaderVariableVector3> ())
this->addUniform (value->getName (),
static_cast<const glm::vec3*> (value->as<CShaderVariableVector3> ()->getValue ()));
else if (value->is<CShaderVariableVector4> ())
this->addUniform (value->getName (),
static_cast<const glm::vec4*> (value->as<CShaderVariableVector4> ()->getValue ()));
else
sLog.exception ("Trying to add an uniform from an unknown type: ", value->getName ());
// no need to re-implement this, call the version that takes a CDynamicValue as second parameter
// and that handles casting and everything
this->addUniform (value, value);
}
void CPass::addUniform (CShaderVariable* value, const CProperty* setting) {
// TODO: CHECK THIS? CAN WE KEEP A REF SO THE VALUES ARE AUTOMATICALLY UPDATED?
// TODO: MAYBE PROVIDE PUBLIC CASTS FOR EVERYTHING INSTEAD OF MANUALLY DOING IT EVERYWHERE
if (value->is<CShaderVariableVector2> ()) {
if (setting->is<CPropertySlider> ()) {
const auto slider = setting->as<CPropertySlider> ();
// sliders have to be converted to vector2
this->addUniform (value->getName (), {slider->getValue (), slider->getValue ()});
} else if (setting->is<CPropertyColor> ()) {
const auto color = setting->as<CPropertyColor> ();
// colors are vec3, we just need vec2
this->addUniform (value->getName (), {color->getValue ().x, color->getValue ().y});
} else {
sLog.error ("Cannot convert setting ", setting->getName (), " to ", value->getName (), ". Using default value");
this->addUniform (value);
}
} else if (value->is<CShaderVariableFloat> ()) {
if (setting->is<CPropertySlider> ()) {
const auto slider = setting->as<CPropertySlider> ();
this->addUniform (value->getName (), slider->getValue ());
} else if (setting->is<CPropertyColor>()) {
const auto color = setting->as<CPropertyColor> ();
this->addUniform (value->getName (), &color->getValue ().x);
} else {
sLog.error ("Cannot convert setting ", setting->getName (), " to ", value->getName (), ". Using default value");
this->addUniform (value);
}
void CPass::addUniform (CShaderVariable* value, const CDynamicValue* setting) {
if (value->is<CShaderVariableFloat> ()) {
this->addUniform (value->getName (), setting->getFloat ());
} else if (value->is<CShaderVariableInteger> ()) {
this->addUniform (value->getName (), setting->getInt ());
} else if (value->is<CShaderVariableVector2> ()) {
this->addUniform (value->getName (), setting->getVec2 ());
} else if (value->is<CShaderVariableVector3> ()) {
if (setting->is<CPropertySlider> ()) {
const auto slider = setting->as<CPropertySlider> ();
this->addUniform (value->getName (), {slider->getValue (), slider->getValue (), slider->getValue ()});
} else if (setting->is<CPropertyColor>()) {
const auto color = setting->as<CPropertyColor> ();
this->addUniform (value->getName (), color->getValue ());
} else {
sLog.error ("Cannot convert setting ", setting->getName (), " to ", value->getName (), ". Using default value");
this->addUniform (value);
}
this->addUniform (value->getName (), setting->getVec3 ());
} else if (value->is<CShaderVariableVector4> ()) {
if (setting->is<CPropertySlider> ()) {
const auto slider = setting->as<CPropertySlider> ();
this->addUniform (value->getName (), {slider->getValue (), slider->getValue (), slider->getValue (), slider->getValue ()});
} else {
sLog.error ("Cannot convert setting ", setting->getName (), " to ", value->getName (), ". Using default value");
this->addUniform (value);
}
this->addUniform (value->getName (), setting->getVec4 ());
} else {
sLog.error ("Cannot convert setting ", setting->getName (), " to ", value->getName (), ". Using default value");
this->addUniform (value);
sLog.error ("Cannot convert setting dynamic value to ", value->getName (), ". Using default value");
}
}
void CPass::addUniform (const std::string& name, CShaderConstant* value) {
// now determine the constant's type and register the correct uniform for it
if (value->is<CShaderConstantFloat> ())
this->addUniform (name, value->as<CShaderConstantFloat> ()->getValue ());
else if (value->is<CShaderConstantInteger> ())
this->addUniform (name, value->as<CShaderConstantInteger> ()->getValue ());
else if (value->is<CShaderConstantVector2> ())
this->addUniform (name, value->as<CShaderConstantVector2> ()->getValue ());
else if (value->is<CShaderConstantVector3> ())
this->addUniform (name, value->as<CShaderConstantVector3> ()->getValue ());
else if (value->is<CShaderConstantVector4> ())
this->addUniform (name, value->as<CShaderConstantVector4> ()->getValue ());
else
sLog.exception ("Trying to add an uniform from an unknown type: ", name);
}
void CPass::addUniform (const std::string& name, const CShaderConstant* value) {
// now determine the constant's type and register the correct uniform for it
if (value->is<CShaderConstantFloat> ())
this->addUniform (name, value->as<CShaderConstantFloat> ()->getValue ());
else if (value->is<CShaderConstantInteger> ())
this->addUniform (name, value->as<CShaderConstantInteger> ()->getValue ());
else if (value->is<CShaderConstantVector2> ())
this->addUniform (name, value->as<CShaderConstantVector2> ()->getValue ());
else if (value->is<CShaderConstantVector3> ())
this->addUniform (name, value->as<CShaderConstantVector3> ()->getValue ());
else if (value->is<CShaderConstantVector4> ())
this->addUniform (name, value->as<CShaderConstantVector4> ()->getValue ());
else
sLog.exception ("Trying to add an uniform from an unknown type: ", name);
}
void CPass::addUniform (const std::string& name, int value) {
this->addUniform (name, UniformType::Integer, value);
}

View File

@ -109,9 +109,7 @@ class CPass final : public Helpers::CContextAware {
void setupAttributes ();
void addAttribute (const std::string& name, GLint type, GLint elements, const GLuint* value);
void addUniform (CShaderVariable* value);
void addUniform (CShaderVariable* value, const CProperty* setting);
void addUniform (const std::string& name, CShaderConstant* value);
void addUniform (const std::string& name, const CShaderConstant* value);
void addUniform (CShaderVariable* value, const CDynamicValue* setting);
void addUniform (const std::string& name, int value);
void addUniform (const std::string& name, double value);
void addUniform (const std::string& name, float value);

View File

@ -352,11 +352,9 @@ void CShaderUnit::parseComboConfiguration (const std::string& content, int defau
}
}
void CShaderUnit::parseParameterConfiguration (const std::string& type, const std::string& name,
const std::string& content) {
if (name == "g_Speed") {
sLog.out("speed!");
}
void CShaderUnit::parseParameterConfiguration (
const std::string& type, const std::string& name, const std::string& content
) {
json data = json::parse (content);
const auto material = data.find ("material");
const auto defvalue = data.find ("default");
@ -377,6 +375,7 @@ void CShaderUnit::parseParameterConfiguration (const std::string& type, const st
Variables::CShaderVariable* parameter = nullptr;
// TODO: SUPPORT VALUES FOR ALL THESE TYPES
// TODO: MAYBE EVEN CONNECT THESE TO THE CORRESPONDING PROPERTY SO THINGS ARE UPDATED AS THE ORIGIN VALUES CHANGE?
if (type == "vec4") {
parameter = new Variables::CShaderVariableVector4(WallpaperEngine::Core::aToVector4 (*defvalue));
} else if (type == "vec3") {

View File

@ -4,21 +4,8 @@
using namespace WallpaperEngine::Render::Shaders::Variables;
CShaderVariable::CShaderVariable (void* defaultValue, void* value, std::string type) :
m_type (std::move (type)),
m_defaultValue (defaultValue),
m_value (value) {}
const void* CShaderVariable::getValue () const {
if (this->m_value)
return this->m_value;
return this->m_defaultValue;
}
void CShaderVariable::setValue (void* value) {
this->m_value = value;
}
CShaderVariable::CShaderVariable (std::string type) :
m_type (std::move (type)) {}
const std::string& CShaderVariable::getIdentifierName () const {
return this->m_identifierName;

View File

@ -1,46 +1,38 @@
#pragma once
#include "WallpaperEngine/Core/DynamicValues/CDynamicValue.h"
#include <string>
namespace WallpaperEngine::Render::Shaders::Variables {
class CShaderVariable {
class CShaderVariable : public Core::DynamicValues::CDynamicValue {
public:
CShaderVariable (void* defaultValue, void* value, std::string type);
CShaderVariable (std::string type);
virtual ~CShaderVariable () = default;
template <class T> const T* as () const {
template <class T> [[nodiscard]] const T* as () const {
assert (is<T> ());
return reinterpret_cast<const T*> (this);
}
template <class T> T* as () {
template <class T> [[nodiscard]] T* as () {
assert (is<T> ());
return reinterpret_cast<T*> (this);
}
template <class T> bool is () {
template <class T> [[nodiscard]] bool is () {
return this->m_type == T::Type;
}
const std::string& getIdentifierName () const;
const std::string& getName () const;
const std::string& getType () const;
[[nodiscard]] const std::string& getIdentifierName () const;
[[nodiscard]] const std::string& getName () const;
[[nodiscard]] const std::string& getType () const;
void setIdentifierName (std::string identifierName);
void setName (const std::string& name);
const void* getValue () const;
virtual const int getSize () const = 0;
protected:
void setValue (void* value);
private:
std::string m_identifierName;
std::string m_name;
std::string m_type;
void* m_defaultValue;
void* m_value;
};
} // namespace WallpaperEngine::Render::Shaders::Variables

View File

@ -5,25 +5,14 @@
using namespace WallpaperEngine::Render::Shaders::Variables;
CShaderVariableFloat::CShaderVariableFloat (float defaultValue) :
CShaderVariable (&this->m_defaultValue, nullptr, Type),
m_defaultValue (defaultValue),
m_value (0) {}
CShaderVariable (Type) {
this->update (defaultValue);
}
CShaderVariableFloat::CShaderVariableFloat (float defaultValue, const std::string& name) :
CShaderVariable (&this->m_defaultValue, nullptr, Type),
m_defaultValue (defaultValue),
m_value (0) {
CShaderVariable (Type) {
this->setName (name);
}
void CShaderVariableFloat::setValue (float value) {
this->m_value = value;
CShaderVariable::setValue (&this->m_value);
}
const int CShaderVariableFloat::getSize () const {
return 1;
this->update (defaultValue);
}
const std::string CShaderVariableFloat::Type = "float";

View File

@ -8,14 +8,6 @@ class CShaderVariableFloat final : public CShaderVariable {
explicit CShaderVariableFloat (float defaultValue);
CShaderVariableFloat (float defaultValue, const std::string& name);
const int getSize () const override;
void setValue (float value);
static const std::string Type;
private:
float m_defaultValue;
float m_value;
};
} // namespace WallpaperEngine::Render::Shaders::Variables

View File

@ -5,24 +5,15 @@
using namespace WallpaperEngine::Render::Shaders::Variables;
CShaderVariableInteger::CShaderVariableInteger (int32_t defaultValue) :
CShaderVariable (&this->m_defaultValue, nullptr, Type),
m_defaultValue (defaultValue),
m_value (0) {}
CShaderVariable (Type) {
this->update (defaultValue);
}
CShaderVariableInteger::CShaderVariableInteger (int32_t defaultValue, const std::string& name) :
CShaderVariable (&this->m_defaultValue, nullptr, Type),
m_defaultValue (defaultValue),
m_value (0) {
CShaderVariable (Type) {
this->setName (name);
this->update (defaultValue);
}
void CShaderVariableInteger::setValue (int32_t value) {
this->m_value = value;
CShaderVariable::setValue (&this->m_value);
}
const int CShaderVariableInteger::getSize () const {
return 1;
}
const std::string CShaderVariableInteger::Type = "int";

View File

@ -8,14 +8,6 @@ class CShaderVariableInteger final : public CShaderVariable {
explicit CShaderVariableInteger (int32_t defaultValue);
CShaderVariableInteger (int32_t defaultValue, const std::string& name);
const int getSize () const override;
static const std::string Type;
void setValue (int32_t value);
private:
int32_t m_defaultValue;
int32_t m_value;
};
} // namespace WallpaperEngine::Render::Shaders::Variables

View File

@ -5,25 +5,14 @@
using namespace WallpaperEngine::Render::Shaders::Variables;
CShaderVariableVector2::CShaderVariableVector2 (const glm::vec2& defaultValue) :
CShaderVariable (&this->m_defaultValue, nullptr, Type),
m_defaultValue (defaultValue),
m_value (glm::vec2 ()) {}
CShaderVariable (Type) {
this->update (defaultValue);
}
CShaderVariableVector2::CShaderVariableVector2 (const glm::vec2& defaultValue, const std::string& name) :
CShaderVariable (&this->m_defaultValue, nullptr, Type),
m_defaultValue (defaultValue),
m_value (glm::vec2 ()) {
CShaderVariable (Type) {
this->setName (name);
}
void CShaderVariableVector2::setValue (const glm::vec2& value) {
this->m_value = value;
CShaderVariable::setValue (&this->m_value);
}
const int CShaderVariableVector2::getSize () const {
return 2;
this->update (defaultValue);
}
const std::string CShaderVariableVector2::Type = "vec2";

View File

@ -9,14 +9,6 @@ class CShaderVariableVector2 final : public CShaderVariable {
explicit CShaderVariableVector2 (const glm::vec2& defaultValue);
CShaderVariableVector2 (const glm::vec2& defaultValue, const std::string& name);
const int getSize () const override;
void setValue (const glm::vec2& value);
static const std::string Type;
private:
glm::vec2 m_defaultValue;
glm::vec2 m_value;
};
} // namespace WallpaperEngine::Render::Shaders::Variables

View File

@ -3,24 +3,14 @@
using namespace WallpaperEngine::Render::Shaders::Variables;
CShaderVariableVector3::CShaderVariableVector3 (const glm::vec3& defaultValue) :
CShaderVariable (&this->m_defaultValue, nullptr, Type),
m_defaultValue (defaultValue),
m_value (glm::vec3 ()) {}
CShaderVariable (Type) {
this->update (defaultValue);
}
CShaderVariableVector3::CShaderVariableVector3 (const glm::vec3& defaultValue, const std::string& name) :
CShaderVariable (&this->m_defaultValue, nullptr, Type),
m_defaultValue (defaultValue),
m_value (glm::vec3 ()) {
CShaderVariable (Type) {
this->setName (name);
}
void CShaderVariableVector3::setValue (const glm::vec3& value) {
this->m_value = value;
CShaderVariable::setValue (&this->m_value);
}
const int CShaderVariableVector3::getSize () const {
return 3;
this->update (defaultValue);
}
const std::string CShaderVariableVector3::Type = "vec3";

View File

@ -10,14 +10,6 @@ class CShaderVariableVector3 final : public CShaderVariable {
explicit CShaderVariableVector3 (const glm::vec3& defaultValue);
CShaderVariableVector3 (const glm::vec3& defaultValue, const std::string& name);
const int getSize () const override;
void setValue (const glm::vec3& value);
static const std::string Type;
private:
glm::vec3 m_defaultValue;
glm::vec3 m_value;
};
} // namespace WallpaperEngine::Render::Shaders::Variables

View File

@ -5,24 +5,14 @@
using namespace WallpaperEngine::Render::Shaders::Variables;
CShaderVariableVector4::CShaderVariableVector4 (const glm::vec4& defaultValue) :
CShaderVariable (&this->m_defaultValue, nullptr, Type),
m_defaultValue (defaultValue),
m_value (glm::vec4 ()) {}
CShaderVariable (Type) {
this->update (defaultValue);
}
CShaderVariableVector4::CShaderVariableVector4 (const glm::vec4& defaultValue, const std::string& name) :
CShaderVariable (&this->m_defaultValue, nullptr, Type),
m_defaultValue (defaultValue),
m_value (glm::vec4 ()) {
CShaderVariable (Type) {
this->setName (name);
}
void CShaderVariableVector4::setValue (const glm::vec4& value) {
this->m_value = value;
CShaderVariable::setValue (&this->m_value);
}
const int CShaderVariableVector4::getSize () const {
return 4;
this->update (defaultValue);
}
const std::string CShaderVariableVector4::Type = "vec4";

View File

@ -9,14 +9,6 @@ class CShaderVariableVector4 final : public CShaderVariable {
explicit CShaderVariableVector4 (const glm::vec4& defaultValue);
CShaderVariableVector4 (const glm::vec4& defaultValue, const std::string& name);
const int getSize () const override;
void setValue (const glm::vec4& value);
static const std::string Type;
private:
glm::vec4 m_defaultValue;
glm::vec4 m_value;
};
} // namespace WallpaperEngine::Render::Shaders::Variables