| @@ -1,6 +1,34 @@ | |||||
| JUCE breaking changes | 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 | Version 5.1.0 | ||||
| ============= | ============= | ||||
| @@ -91,7 +91,7 @@ DynamicObject::Ptr DynamicObject::clone() | |||||
| return d; | 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 << '{'; | out << '{'; | ||||
| if (! allOnOneLine) | if (! allOnOneLine) | ||||
| @@ -107,7 +107,7 @@ void DynamicObject::writeAsJSON (OutputStream& out, const int indentLevel, const | |||||
| out << '"'; | out << '"'; | ||||
| JSONFormatter::writeString (out, properties.getName (i)); | JSONFormatter::writeString (out, properties.getName (i)); | ||||
| out << "\": "; | 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) | if (i < numValues - 1) | ||||
| { | { | ||||
| @@ -113,14 +113,14 @@ public: | |||||
| never need to call it directly, but it's virtual so that custom object types | never need to call it directly, but it's virtual so that custom object types | ||||
| can stringify themselves appropriately. | can stringify themselves appropriately. | ||||
| */ | */ | ||||
| virtual void writeAsJSON (OutputStream&, int indentLevel, bool allOnOneLine); | |||||
| virtual void writeAsJSON (OutputStream&, int indentLevel, bool allOnOneLine, int maximumDecimalPlaces); | |||||
| private: | private: | ||||
| //============================================================================== | //============================================================================== | ||||
| NamedValueSet properties; | NamedValueSet properties; | ||||
| #if JUCE_CATCH_DEPRECATED_CODE_MISUSE | #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) {} | virtual void invokeMethod (const Identifier&, const var*, int) {} | ||||
| #endif | #endif | ||||
| @@ -323,7 +323,8 @@ class JSONFormatter | |||||
| { | { | ||||
| public: | public: | ||||
| static void write (OutputStream& out, const var& v, | 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()) | if (v.isString()) | ||||
| { | { | ||||
| @@ -343,14 +344,18 @@ public: | |||||
| { | { | ||||
| out << (static_cast<bool> (v) ? "true" : "false"); | out << (static_cast<bool> (v) ? "true" : "false"); | ||||
| } | } | ||||
| else if (v.isDouble()) | |||||
| { | |||||
| out << String (static_cast<double> (v), maximumDecimalPlaces); | |||||
| } | |||||
| else if (v.isArray()) | else if (v.isArray()) | ||||
| { | { | ||||
| writeArray (out, *v.getArray(), indentLevel, allOnOneLine); | |||||
| writeArray (out, *v.getArray(), indentLevel, allOnOneLine, maximumDecimalPlaces); | |||||
| } | } | ||||
| else if (v.isObject()) | else if (v.isObject()) | ||||
| { | { | ||||
| if (DynamicObject* object = v.getDynamicObject()) | if (DynamicObject* object = v.getDynamicObject()) | ||||
| object->writeAsJSON (out, indentLevel, allOnOneLine); | |||||
| object->writeAsJSON (out, indentLevel, allOnOneLine, maximumDecimalPlaces); | |||||
| else | else | ||||
| jassertfalse; // Only DynamicObjects can be converted to JSON! | jassertfalse; // Only DynamicObjects can be converted to JSON! | ||||
| } | } | ||||
| @@ -420,7 +425,8 @@ public: | |||||
| } | } | ||||
| static void writeArray (OutputStream& out, const Array<var>& array, | static void writeArray (OutputStream& out, const Array<var>& array, | ||||
| const int indentLevel, const bool allOnOneLine) | |||||
| const int indentLevel, const bool allOnOneLine, | |||||
| int maximumDecimalPlaces) | |||||
| { | { | ||||
| out << '['; | out << '['; | ||||
| @@ -434,7 +440,7 @@ public: | |||||
| if (! allOnOneLine) | if (! allOnOneLine) | ||||
| writeSpaces (out, indentLevel + indentSize); | 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) | if (i < array.size() - 1) | ||||
| { | { | ||||
| @@ -493,16 +499,16 @@ Result JSON::parse (const String& text, var& result) | |||||
| return JSONParser::parseObjectOrArray (text.getCharPointer(), 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); | MemoryOutputStream mo (1024); | ||||
| JSONFormatter::write (mo, data, 0, allOnOneLine); | |||||
| JSONFormatter::write (mo, data, 0, allOnOneLine, maximumDecimalPlaces); | |||||
| return mo.toUTF8(); | 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) | String JSON::escapeString (StringRef s) | ||||
| @@ -90,10 +90,12 @@ public: | |||||
| /** Returns a string which contains a JSON-formatted representation of the var object. | /** 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 | 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. | 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 | @see writeToStream | ||||
| */ | */ | ||||
| static String toString (const var& objectToFormat, | 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. | /** Parses a string that was created with the toString() method. | ||||
| This is slightly different to the parse() methods because they will reject primitive | 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. | /** 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 | 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. | 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 | @see toString | ||||
| */ | */ | ||||
| static void writeToStream (OutputStream& output, | static void writeToStream (OutputStream& output, | ||||
| const var& objectToFormat, | const var& objectToFormat, | ||||
| bool allOnOneLine = false); | |||||
| bool allOnOneLine = false, | |||||
| int maximumDecimalPlaces = 20); | |||||
| /** Returns a version of a string with any extended characters escaped. */ | /** Returns a version of a string with any extended characters escaped. */ | ||||
| static String escapeString (StringRef); | static String escapeString (StringRef); | ||||
| @@ -827,7 +827,7 @@ struct JavascriptEngine::RootObject : public DynamicObject | |||||
| DynamicObject::Ptr clone() override { return new FunctionObject (*this); } | 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; | out << "function " << functionCode; | ||||
| } | } | ||||