EffectParser.cpp 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. #include "EffectParser.h"
  2. #include "MaterialParser.h"
  3. #include "WallpaperEngine/Data/Model/DynamicValue.h"
  4. #include "WallpaperEngine/Data/Model/Effect.h"
  5. #include "WallpaperEngine/Data/Model/Material.h"
  6. #include "WallpaperEngine/Data/Model/Project.h"
  7. #include "WallpaperEngine/FileSystem/Container.h"
  8. using namespace WallpaperEngine::Data::Parsers;
  9. using namespace WallpaperEngine::Data::Model;
  10. EffectUniquePtr EffectParser::load (const Project& project, const std::string& filename) {
  11. const auto effectJson = JSON::parseAsset (project.assetLocator->readString (filename));
  12. return parse (effectJson, project);
  13. }
  14. EffectUniquePtr EffectParser::parse (const JSON& it, const Project& project) {
  15. const auto dependencies = it.optional ("dependencies");
  16. const auto fbos = it.optional ("fbos");
  17. return std::make_unique<Effect> (Effect {
  18. .name = it.optional<std::string> ("name", ""),
  19. .description = it.optional<std::string> ("description", ""),
  20. .group = it.optional<std::string> ("group", ""),
  21. .preview = it.optional<std::string> ("preview", ""),
  22. .dependencies = dependencies.has_value () ? parseDependencies (*dependencies) : std::vector<std::string> {},
  23. .passes = parseEffectPasses (it.require ("passes", "Effect file must have passes"), project),
  24. .fbos = fbos.has_value () ? parseFBOs (*fbos) : std::vector<FBOUniquePtr> {},
  25. });
  26. }
  27. std::vector<std::string> EffectParser::parseDependencies (const JSON& it) {
  28. std::vector<std::string> result = {};
  29. if (!it.is_array ()) {
  30. return result;
  31. }
  32. for (const auto& cur : it) {
  33. result.push_back (cur);
  34. }
  35. return result;
  36. }
  37. std::vector<EffectPassUniquePtr> EffectParser::parseEffectPasses (const JSON& it, const Project& project) {
  38. std::vector<EffectPassUniquePtr> result = {};
  39. if (!it.is_array ()) {
  40. return result;
  41. }
  42. for (const auto& cur : it) {
  43. const auto binds = cur.optional ("bind");
  44. const auto command = cur.optional ("command");
  45. const auto material = cur.optional ("material");
  46. result.push_back (
  47. std::make_unique<EffectPass> (EffectPass {
  48. .material = material.has_value () ? MaterialParser::load (project, *material)
  49. : std::optional<MaterialUniquePtr> {},
  50. .binds = binds.has_value () ? parseBinds (binds.value ()) : std::map<int, std::string> {},
  51. .command = command.has_value () ? (command.value () == "copy" ? Command_Copy : Command_Swap)
  52. : std::optional<PassCommandType> {},
  53. .source = command.has_value ()
  54. ? cur.require<std::string> ("source", "Effect command must have a source")
  55. : cur.optional<std::string> ("source"),
  56. .target = command.has_value ()
  57. ? cur.require<std::string> ("target", "Effect command must have a target")
  58. : cur.optional<std::string> ("target"),
  59. })
  60. );
  61. }
  62. return result;
  63. }
  64. std::map<int, std::string> EffectParser::parseBinds (const JSON& it) {
  65. std::map<int, std::string> result = {};
  66. if (!it.is_array ()) {
  67. return result;
  68. }
  69. for (const auto& cur : it) {
  70. result.emplace (
  71. cur.require ("index", "Texture binds must have an index"),
  72. cur.require ("name", "Texture bind must name the FBO that should be used")
  73. );
  74. }
  75. return result;
  76. }
  77. std::vector<FBOUniquePtr> EffectParser::parseFBOs (const JSON& it) {
  78. std::vector<FBOUniquePtr> result = {};
  79. if (!it.is_array ()) {
  80. return result;
  81. }
  82. for (const auto& cur : it) {
  83. result.push_back (
  84. std::make_unique<FBO> (FBO {
  85. .name = cur.require<std::string> ("name", "FBO must have a name"),
  86. .format = cur.optional<std::string> ("format", "rgba8888"),
  87. .scale = cur.optional ("scale", 1.0f),
  88. .unique = cur.optional ("unique", false),
  89. })
  90. );
  91. }
  92. return result;
  93. }