#include "EffectParser.h" #include "MaterialParser.h" #include "WallpaperEngine/Data/Model/DynamicValue.h" #include "WallpaperEngine/Data/Model/Effect.h" #include "WallpaperEngine/Data/Model/Material.h" #include "WallpaperEngine/Data/Model/Project.h" #include "WallpaperEngine/FileSystem/Container.h" using namespace WallpaperEngine::Data::Parsers; using namespace WallpaperEngine::Data::Model; EffectUniquePtr EffectParser::load (const Project& project, const std::string& filename) { const auto effectJson = JSON::parseAsset (project.assetLocator->readString (filename)); return parse (effectJson, project); } EffectUniquePtr EffectParser::parse (const JSON& it, const Project& project) { const auto dependencies = it.optional ("dependencies"); const auto fbos = it.optional ("fbos"); return std::make_unique (Effect { .name = it.optional ("name", ""), .description = it.optional ("description", ""), .group = it.optional ("group", ""), .preview = it.optional ("preview", ""), .dependencies = dependencies.has_value () ? parseDependencies (*dependencies) : std::vector {}, .passes = parseEffectPasses (it.require ("passes", "Effect file must have passes"), project), .fbos = fbos.has_value () ? parseFBOs (*fbos) : std::vector {}, }); } std::vector EffectParser::parseDependencies (const JSON& it) { std::vector result = {}; if (!it.is_array ()) { return result; } for (const auto& cur : it) { result.push_back (cur); } return result; } std::vector EffectParser::parseEffectPasses (const JSON& it, const Project& project) { std::vector result = {}; if (!it.is_array ()) { return result; } for (const auto& cur : it) { const auto binds = cur.optional ("bind"); const auto command = cur.optional ("command"); const auto material = cur.optional ("material"); result.push_back ( std::make_unique (EffectPass { .material = material.has_value () ? MaterialParser::load (project, *material) : std::optional {}, .binds = binds.has_value () ? parseBinds (binds.value ()) : std::map {}, .command = command.has_value () ? (command.value () == "copy" ? Command_Copy : Command_Swap) : std::optional {}, .source = command.has_value () ? cur.require ("source", "Effect command must have a source") : cur.optional ("source"), .target = command.has_value () ? cur.require ("target", "Effect command must have a target") : cur.optional ("target"), }) ); } return result; } std::map EffectParser::parseBinds (const JSON& it) { std::map 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; } std::vector EffectParser::parseFBOs (const JSON& it) { std::vector result = {}; if (!it.is_array ()) { return result; } for (const auto& cur : it) { result.push_back ( std::make_unique (FBO { .name = cur.require ("name", "FBO must have a name"), .format = cur.optional ("format", "rgba8888"), .scale = cur.optional ("scale", 1.0f), .unique = cur.optional ("unique", false), }) ); } return result; }