| @@ -1,6 +1,34 @@ | |||
| JUCE breaking changes | |||
| ===================== | |||
| Develop Branch | |||
| ============= | |||
| Change | |||
| ------ | |||
| The writeAsJSON virtual method of the DynamicObject class requires an | |||
| additional parameter, maximumDecimalPlaces, to specify the maximum precision of | |||
| floating point numbers. | |||
| Possible Issues | |||
| --------------- | |||
| Classes which inherit from DynamicObject and override this method will need to | |||
| update their method signature. | |||
| Workaround | |||
| ---------- | |||
| Your custom DynamicObject class can choose to ignore the additional parameter | |||
| if you don't wish to support this behaviour. | |||
| Rationale | |||
| --------- | |||
| When serialising the results of calculations to JSON the rounding of floating | |||
| point numbers can result in numbers with 17 significant figures where only a | |||
| few are required. This change to DynamicObject is required to support | |||
| truncating those numbers. | |||
| Version 5.1.0 | |||
| ============= | |||
| @@ -91,7 +91,7 @@ DynamicObject::Ptr DynamicObject::clone() | |||
| return d; | |||
| } | |||
| void DynamicObject::writeAsJSON (OutputStream& out, const int indentLevel, const bool allOnOneLine) | |||
| void DynamicObject::writeAsJSON (OutputStream& out, const int indentLevel, const bool allOnOneLine, int maximumDecimalPlaces) | |||
| { | |||
| out << '{'; | |||
| if (! allOnOneLine) | |||
| @@ -107,7 +107,7 @@ void DynamicObject::writeAsJSON (OutputStream& out, const int indentLevel, const | |||
| out << '"'; | |||
| JSONFormatter::writeString (out, properties.getName (i)); | |||
| out << "\": "; | |||
| JSONFormatter::write (out, properties.getValueAt (i), indentLevel + JSONFormatter::indentSize, allOnOneLine); | |||
| JSONFormatter::write (out, properties.getValueAt (i), indentLevel + JSONFormatter::indentSize, allOnOneLine, maximumDecimalPlaces); | |||
| if (i < numValues - 1) | |||
| { | |||
| @@ -113,14 +113,14 @@ public: | |||
| never need to call it directly, but it's virtual so that custom object types | |||
| can stringify themselves appropriately. | |||
| */ | |||
| virtual void writeAsJSON (OutputStream&, int indentLevel, bool allOnOneLine); | |||
| virtual void writeAsJSON (OutputStream&, int indentLevel, bool allOnOneLine, int maximumDecimalPlaces); | |||
| private: | |||
| //============================================================================== | |||
| NamedValueSet properties; | |||
| #if JUCE_CATCH_DEPRECATED_CODE_MISUSE | |||
| // These methods have been deprecated - use var::invoke instead | |||
| // This method has been deprecated - use var::invoke instead | |||
| virtual void invokeMethod (const Identifier&, const var*, int) {} | |||
| #endif | |||
| @@ -323,7 +323,8 @@ class JSONFormatter | |||
| { | |||
| public: | |||
| static void write (OutputStream& out, const var& v, | |||
| const int indentLevel, const bool allOnOneLine) | |||
| const int indentLevel, const bool allOnOneLine, | |||
| int maximumDecimalPlaces) | |||
| { | |||
| if (v.isString()) | |||
| { | |||
| @@ -343,14 +344,18 @@ public: | |||
| { | |||
| out << (static_cast<bool> (v) ? "true" : "false"); | |||
| } | |||
| else if (v.isDouble()) | |||
| { | |||
| out << String (static_cast<double> (v), maximumDecimalPlaces); | |||
| } | |||
| else if (v.isArray()) | |||
| { | |||
| writeArray (out, *v.getArray(), indentLevel, allOnOneLine); | |||
| writeArray (out, *v.getArray(), indentLevel, allOnOneLine, maximumDecimalPlaces); | |||
| } | |||
| else if (v.isObject()) | |||
| { | |||
| if (DynamicObject* object = v.getDynamicObject()) | |||
| object->writeAsJSON (out, indentLevel, allOnOneLine); | |||
| object->writeAsJSON (out, indentLevel, allOnOneLine, maximumDecimalPlaces); | |||
| else | |||
| jassertfalse; // Only DynamicObjects can be converted to JSON! | |||
| } | |||
| @@ -420,7 +425,8 @@ public: | |||
| } | |||
| static void writeArray (OutputStream& out, const Array<var>& array, | |||
| const int indentLevel, const bool allOnOneLine) | |||
| const int indentLevel, const bool allOnOneLine, | |||
| int maximumDecimalPlaces) | |||
| { | |||
| out << '['; | |||
| @@ -434,7 +440,7 @@ public: | |||
| if (! allOnOneLine) | |||
| writeSpaces (out, indentLevel + indentSize); | |||
| write (out, array.getReference(i), indentLevel + indentSize, allOnOneLine); | |||
| write (out, array.getReference(i), indentLevel + indentSize, allOnOneLine, maximumDecimalPlaces); | |||
| if (i < array.size() - 1) | |||
| { | |||
| @@ -493,16 +499,16 @@ Result JSON::parse (const String& text, var& result) | |||
| return JSONParser::parseObjectOrArray (text.getCharPointer(), result); | |||
| } | |||
| String JSON::toString (const var& data, const bool allOnOneLine) | |||
| String JSON::toString (const var& data, const bool allOnOneLine, int maximumDecimalPlaces) | |||
| { | |||
| MemoryOutputStream mo (1024); | |||
| JSONFormatter::write (mo, data, 0, allOnOneLine); | |||
| JSONFormatter::write (mo, data, 0, allOnOneLine, maximumDecimalPlaces); | |||
| return mo.toUTF8(); | |||
| } | |||
| void JSON::writeToStream (OutputStream& output, const var& data, const bool allOnOneLine) | |||
| void JSON::writeToStream (OutputStream& output, const var& data, const bool allOnOneLine, int maximumDecimalPlaces) | |||
| { | |||
| JSONFormatter::write (output, data, 0, allOnOneLine); | |||
| JSONFormatter::write (output, data, 0, allOnOneLine, maximumDecimalPlaces); | |||
| } | |||
| String JSON::escapeString (StringRef s) | |||
| @@ -90,10 +90,12 @@ public: | |||
| /** Returns a string which contains a JSON-formatted representation of the var object. | |||
| If allOnOneLine is true, the result will be compacted into a single line of text | |||
| with no carriage-returns. If false, it will be laid-out in a more human-readable format. | |||
| The maximumDecimalPlaces parameter determines the precision of floating point numbers. | |||
| @see writeToStream | |||
| */ | |||
| static String toString (const var& objectToFormat, | |||
| bool allOnOneLine = false); | |||
| bool allOnOneLine = false, | |||
| int maximumDecimalPlaces = 20); | |||
| /** Parses a string that was created with the toString() method. | |||
| This is slightly different to the parse() methods because they will reject primitive | |||
| @@ -105,11 +107,13 @@ public: | |||
| /** Writes a JSON-formatted representation of the var object to the given stream. | |||
| If allOnOneLine is true, the result will be compacted into a single line of text | |||
| with no carriage-returns. If false, it will be laid-out in a more human-readable format. | |||
| The maximumDecimalPlaces parameter determines the precision of floating point numbers. | |||
| @see toString | |||
| */ | |||
| static void writeToStream (OutputStream& output, | |||
| const var& objectToFormat, | |||
| bool allOnOneLine = false); | |||
| bool allOnOneLine = false, | |||
| int maximumDecimalPlaces = 20); | |||
| /** Returns a version of a string with any extended characters escaped. */ | |||
| static String escapeString (StringRef); | |||
| @@ -827,7 +827,7 @@ struct JavascriptEngine::RootObject : public DynamicObject | |||
| DynamicObject::Ptr clone() override { return new FunctionObject (*this); } | |||
| void writeAsJSON (OutputStream& out, int /*indentLevel*/, bool /*allOnOneLine*/) override | |||
| void writeAsJSON (OutputStream& out, int /*indentLevel*/, bool /*allOnOneLine*/, int /*maximumDecimalPlaces*/) override | |||
| { | |||
| out << "function " << functionCode; | |||
| } | |||