1cb93a386Sopenharmony_ci/* 2cb93a386Sopenharmony_ci* Copyright 2019 Google LLC 3cb93a386Sopenharmony_ci* 4cb93a386Sopenharmony_ci* Use of this source code is governed by a BSD-style license that can be 5cb93a386Sopenharmony_ci* found in the LICENSE file. 6cb93a386Sopenharmony_ci*/ 7cb93a386Sopenharmony_ci 8cb93a386Sopenharmony_ci#ifndef SkParticleSerialization_DEFINED 9cb93a386Sopenharmony_ci#define SkParticleSerialization_DEFINED 10cb93a386Sopenharmony_ci 11cb93a386Sopenharmony_ci#include "modules/particles/include/SkReflected.h" 12cb93a386Sopenharmony_ci 13cb93a386Sopenharmony_ci#include "include/core/SkString.h" 14cb93a386Sopenharmony_ci#include "include/private/SkTArray.h" 15cb93a386Sopenharmony_ci#include "src/utils/SkJSON.h" 16cb93a386Sopenharmony_ci#include "src/utils/SkJSONWriter.h" 17cb93a386Sopenharmony_ci 18cb93a386Sopenharmony_ciclass SkToJsonVisitor : public SkFieldVisitor { 19cb93a386Sopenharmony_cipublic: 20cb93a386Sopenharmony_ci SkToJsonVisitor(SkJSONWriter& writer) : fWriter(writer) {} 21cb93a386Sopenharmony_ci 22cb93a386Sopenharmony_ci // Primitives 23cb93a386Sopenharmony_ci void visit(const char* name, float& f) override { 24cb93a386Sopenharmony_ci fWriter.appendFloat(name, f); 25cb93a386Sopenharmony_ci } 26cb93a386Sopenharmony_ci void visit(const char* name, int& i) override { 27cb93a386Sopenharmony_ci fWriter.appendS32(name, i); 28cb93a386Sopenharmony_ci } 29cb93a386Sopenharmony_ci void visit(const char* name, bool& b) override { 30cb93a386Sopenharmony_ci fWriter.appendBool(name, b); 31cb93a386Sopenharmony_ci } 32cb93a386Sopenharmony_ci void visit(const char* name, SkString& s) override { 33cb93a386Sopenharmony_ci if (s.contains('\n')) { 34cb93a386Sopenharmony_ci SkTArray<SkString> lines; 35cb93a386Sopenharmony_ci SkStrSplit(s.c_str(), "\n", kStrict_SkStrSplitMode, &lines); 36cb93a386Sopenharmony_ci fWriter.beginArray(name); 37cb93a386Sopenharmony_ci for (const auto& line : lines) { 38cb93a386Sopenharmony_ci fWriter.appendString(line.c_str()); 39cb93a386Sopenharmony_ci } 40cb93a386Sopenharmony_ci fWriter.endArray(); 41cb93a386Sopenharmony_ci } else { 42cb93a386Sopenharmony_ci fWriter.appendString(name, s.c_str()); 43cb93a386Sopenharmony_ci } 44cb93a386Sopenharmony_ci } 45cb93a386Sopenharmony_ci 46cb93a386Sopenharmony_ci // Compound types 47cb93a386Sopenharmony_ci void visit(sk_sp<SkReflected>& e, const SkReflected::Type* baseType) override { 48cb93a386Sopenharmony_ci fWriter.appendString("Type", e ? e->getType()->fName : "Null"); 49cb93a386Sopenharmony_ci } 50cb93a386Sopenharmony_ci 51cb93a386Sopenharmony_ci void enterObject(const char* name) override { fWriter.beginObject(name); } 52cb93a386Sopenharmony_ci void exitObject() override { fWriter.endObject(); } 53cb93a386Sopenharmony_ci 54cb93a386Sopenharmony_ci int enterArray(const char* name, int oldCount) override { 55cb93a386Sopenharmony_ci fWriter.beginArray(name); 56cb93a386Sopenharmony_ci return oldCount; 57cb93a386Sopenharmony_ci } 58cb93a386Sopenharmony_ci ArrayEdit exitArray() override { 59cb93a386Sopenharmony_ci fWriter.endArray(); 60cb93a386Sopenharmony_ci return ArrayEdit(); 61cb93a386Sopenharmony_ci } 62cb93a386Sopenharmony_ci 63cb93a386Sopenharmony_ciprivate: 64cb93a386Sopenharmony_ci SkJSONWriter& fWriter; 65cb93a386Sopenharmony_ci}; 66cb93a386Sopenharmony_ci 67cb93a386Sopenharmony_ciclass SkFromJsonVisitor : public SkFieldVisitor { 68cb93a386Sopenharmony_cipublic: 69cb93a386Sopenharmony_ci SkFromJsonVisitor(const skjson::Value& v) : fRoot(v) { 70cb93a386Sopenharmony_ci fStack.push_back(&fRoot); 71cb93a386Sopenharmony_ci } 72cb93a386Sopenharmony_ci 73cb93a386Sopenharmony_ci void visit(const char* name, float& f) override { 74cb93a386Sopenharmony_ci TryParse(get(name), f); 75cb93a386Sopenharmony_ci } 76cb93a386Sopenharmony_ci void visit(const char* name, int& i) override { 77cb93a386Sopenharmony_ci TryParse(get(name), i); 78cb93a386Sopenharmony_ci } 79cb93a386Sopenharmony_ci void visit(const char* name, bool& b) override { 80cb93a386Sopenharmony_ci TryParse(get(name), b); 81cb93a386Sopenharmony_ci } 82cb93a386Sopenharmony_ci void visit(const char* name, SkString& s) override { 83cb93a386Sopenharmony_ci if (const skjson::ArrayValue* lines = get(name)) { 84cb93a386Sopenharmony_ci s.reset(); 85cb93a386Sopenharmony_ci bool first = true; 86cb93a386Sopenharmony_ci for (const skjson::StringValue* line : *lines) { 87cb93a386Sopenharmony_ci if (line) { 88cb93a386Sopenharmony_ci if (!first) { 89cb93a386Sopenharmony_ci s.append("\n"); 90cb93a386Sopenharmony_ci } 91cb93a386Sopenharmony_ci s.append(line->begin(), line->size()); 92cb93a386Sopenharmony_ci first = false; 93cb93a386Sopenharmony_ci } 94cb93a386Sopenharmony_ci } 95cb93a386Sopenharmony_ci } else { 96cb93a386Sopenharmony_ci TryParse(get(name), s); 97cb93a386Sopenharmony_ci } 98cb93a386Sopenharmony_ci } 99cb93a386Sopenharmony_ci 100cb93a386Sopenharmony_ci void visit(sk_sp<SkReflected>& e, const SkReflected::Type* baseType) override { 101cb93a386Sopenharmony_ci const skjson::StringValue* typeString = get("Type"); 102cb93a386Sopenharmony_ci const char* type = typeString ? typeString->begin() : "Null"; 103cb93a386Sopenharmony_ci e = SkReflected::CreateInstance(type); 104cb93a386Sopenharmony_ci } 105cb93a386Sopenharmony_ci 106cb93a386Sopenharmony_ci void enterObject(const char* name) override { 107cb93a386Sopenharmony_ci fStack.push_back((const skjson::ObjectValue*)get(name)); 108cb93a386Sopenharmony_ci } 109cb93a386Sopenharmony_ci void exitObject() override { 110cb93a386Sopenharmony_ci fStack.pop_back(); 111cb93a386Sopenharmony_ci } 112cb93a386Sopenharmony_ci 113cb93a386Sopenharmony_ci int enterArray(const char* name, int oldCount) override { 114cb93a386Sopenharmony_ci const skjson::ArrayValue* arrVal = get(name); 115cb93a386Sopenharmony_ci fStack.push_back(arrVal); 116cb93a386Sopenharmony_ci fArrayIndexStack.push_back(0); 117cb93a386Sopenharmony_ci return arrVal ? arrVal->size() : 0; 118cb93a386Sopenharmony_ci } 119cb93a386Sopenharmony_ci ArrayEdit exitArray() override { 120cb93a386Sopenharmony_ci fStack.pop_back(); 121cb93a386Sopenharmony_ci fArrayIndexStack.pop_back(); 122cb93a386Sopenharmony_ci return ArrayEdit(); 123cb93a386Sopenharmony_ci } 124cb93a386Sopenharmony_ci 125cb93a386Sopenharmony_ciprivate: 126cb93a386Sopenharmony_ci const skjson::Value& get(const char* name) { 127cb93a386Sopenharmony_ci if (const skjson::Value* cur = fStack.back()) { 128cb93a386Sopenharmony_ci if (cur->is<skjson::ArrayValue>()) { 129cb93a386Sopenharmony_ci SkASSERT(!name); 130cb93a386Sopenharmony_ci return cur->as<skjson::ArrayValue>()[fArrayIndexStack.back()++]; 131cb93a386Sopenharmony_ci } else if (!name) { 132cb93a386Sopenharmony_ci return *cur; 133cb93a386Sopenharmony_ci } else if (cur->is<skjson::ObjectValue>()) { 134cb93a386Sopenharmony_ci return cur->as<skjson::ObjectValue>()[name]; 135cb93a386Sopenharmony_ci } 136cb93a386Sopenharmony_ci } 137cb93a386Sopenharmony_ci static skjson::NullValue gNull; 138cb93a386Sopenharmony_ci return gNull; 139cb93a386Sopenharmony_ci } 140cb93a386Sopenharmony_ci 141cb93a386Sopenharmony_ci static bool TryParse(const skjson::Value& v, float& f) { 142cb93a386Sopenharmony_ci if (const skjson::NumberValue* num = v) { 143cb93a386Sopenharmony_ci f = static_cast<float>(**num); 144cb93a386Sopenharmony_ci return true; 145cb93a386Sopenharmony_ci } 146cb93a386Sopenharmony_ci return false; 147cb93a386Sopenharmony_ci } 148cb93a386Sopenharmony_ci 149cb93a386Sopenharmony_ci static bool TryParse(const skjson::Value& v, int& i) { 150cb93a386Sopenharmony_ci if (const skjson::NumberValue* num = v) { 151cb93a386Sopenharmony_ci double dbl = **num; 152cb93a386Sopenharmony_ci i = static_cast<int>(dbl); 153cb93a386Sopenharmony_ci return static_cast<double>(i) == dbl; 154cb93a386Sopenharmony_ci } 155cb93a386Sopenharmony_ci return false; 156cb93a386Sopenharmony_ci } 157cb93a386Sopenharmony_ci 158cb93a386Sopenharmony_ci static bool TryParse(const skjson::Value& v, SkString& s) { 159cb93a386Sopenharmony_ci if (const skjson::StringValue* str = v) { 160cb93a386Sopenharmony_ci s.set(str->begin(), str->size()); 161cb93a386Sopenharmony_ci return true; 162cb93a386Sopenharmony_ci } 163cb93a386Sopenharmony_ci return false; 164cb93a386Sopenharmony_ci } 165cb93a386Sopenharmony_ci 166cb93a386Sopenharmony_ci static bool TryParse(const skjson::Value& v, bool& b) { 167cb93a386Sopenharmony_ci switch (v.getType()) { 168cb93a386Sopenharmony_ci case skjson::Value::Type::kNumber: 169cb93a386Sopenharmony_ci b = SkToBool(*v.as<skjson::NumberValue>()); 170cb93a386Sopenharmony_ci return true; 171cb93a386Sopenharmony_ci case skjson::Value::Type::kBool: 172cb93a386Sopenharmony_ci b = *v.as<skjson::BoolValue>(); 173cb93a386Sopenharmony_ci return true; 174cb93a386Sopenharmony_ci default: 175cb93a386Sopenharmony_ci break; 176cb93a386Sopenharmony_ci } 177cb93a386Sopenharmony_ci 178cb93a386Sopenharmony_ci return false; 179cb93a386Sopenharmony_ci } 180cb93a386Sopenharmony_ci 181cb93a386Sopenharmony_ci const skjson::Value& fRoot; 182cb93a386Sopenharmony_ci SkSTArray<16, const skjson::Value*, true> fStack; 183cb93a386Sopenharmony_ci SkSTArray<16, size_t, true> fArrayIndexStack; 184cb93a386Sopenharmony_ci}; 185cb93a386Sopenharmony_ci 186cb93a386Sopenharmony_ci#endif // SkParticleSerialization_DEFINED 187