Skip to content
This repository has been archived by the owner on Aug 8, 2023. It is now read-only.

[core] Add number-format expression #14840

Merged
merged 1 commit into from
Jun 27, 2019
Merged

[core] Add number-format expression #14840

merged 1 commit into from
Jun 27, 2019

Conversation

jmalanen
Copy link
Contributor

@jmalanen jmalanen commented Jun 4, 2019

Fixes: #13632

@jmalanen
Copy link
Contributor Author

jmalanen commented Jun 4, 2019

The number-format/currency test is still disabled because there are differences in the output between GL-JS and GL-Native:

Original
f([{},{"properties":{"locale":"ja-JP","currency":"JPY"}}])
Expected: "JP¥ 123,457"
Actual: "¥123,457"
f([{},{"properties":{"locale":"de-DE","currency":"EUR"}}])
Expected: "€ 123,456.79"
Actual: "123.456,79 €"

Roundtripped through serialize()
f([{},{"properties":{"locale":"ja-JP","currency":"JPY"}}])
Expected: "JP¥ 123,457"
Actual: "¥123,457"
f([{},{"properties":{"locale":"de-DE","currency":"EUR"}}])
Expected: "€ 123,456.79"
Actual: "123.456,79 €"

src/mbgl/style/expression/number_format.cpp Outdated Show resolved Hide resolved
src/mbgl/style/expression/number_format.cpp Outdated Show resolved Hide resolved
src/mbgl/style/expression/number_format.cpp Show resolved Hide resolved
src/mbgl/style/expression/number_format.cpp Show resolved Hide resolved
src/mbgl/style/expression/number_format.cpp Outdated Show resolved Hide resolved
src/mbgl/style/expression/number_format.cpp Outdated Show resolved Hide resolved
src/mbgl/style/expression/number_format.cpp Outdated Show resolved Hide resolved
src/mbgl/style/expression/number_format.cpp Outdated Show resolved Hide resolved
src/mbgl/style/expression/number_format.cpp Outdated Show resolved Hide resolved
@jmalanen jmalanen force-pushed the jmalanen-number-format branch 5 times, most recently from 31fa02e to fbde1db Compare June 4, 2019 15:13
@jmalanen
Copy link
Contributor Author

jmalanen commented Jun 4, 2019

I disabled also the remaining tests. The CI test system doesn't have "en-US" locale installed, which is expected by the GL-JS tests. This causes tests to fail since the outputs don't match.

Serialized

  • 123,456.789+ 123456.789Original
    f([{},{}])
    Expected: "123,456.789"
    Actual: "123456.789"

Roundtripped through serialize()
f([{},{}])
Expected: "123,456.789"
Actual: "123456.789"

  • failed number-format/default

Original
f([{},{"properties":{"locale":"en-US","min":15,"max":20}}])
Expected: "987,654,321.234568000000000"
Actual: "987654321.234568000000000"
f([{},{"properties":{"locale":"en-US","min":2,"max":4}}])
Expected: "987,654,321.2346"
Actual: "987654321.2346"

Roundtripped through serialize()
f([{},{"properties":{"locale":"en-US","min":15,"max":20}}])
Expected: "987,654,321.234568000000000"
Actual: "987654321.234568000000000"
f([{},{"properties":{"locale":"en-US","min":2,"max":4}}])
Expected: "987,654,321.2346"
Actual: "987654321.2346"

  • failed number-format/precision

@jmalanen jmalanen force-pushed the jmalanen-number-format branch 3 times, most recently from a700d8c to 44bd11f Compare June 5, 2019 07:58
test/style/expression/expression.test.cpp Show resolved Hide resolved
src/mbgl/style/expression/number_format.cpp Outdated Show resolved Hide resolved
src/mbgl/style/expression/number_format.cpp Outdated Show resolved Hide resolved
src/mbgl/style/expression/number_format.cpp Outdated Show resolved Hide resolved
std::vector<mbgl::Value> serialized{{ getOperator() }};
serialized.emplace_back(number->serialize());

std::unordered_map<std::string, mbgl::Value> options;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

options seem to have just a few items, looks like std::unordered_map is an overkill, better use std::map

include/mbgl/style/expression/number_format.hpp Outdated Show resolved Hide resolved
src/mbgl/style/expression/number_format.cpp Outdated Show resolved Hide resolved
include/mbgl/style/expression/number_format.hpp Outdated Show resolved Hide resolved
src/mbgl/style/expression/number_format.cpp Outdated Show resolved Hide resolved
src/mbgl/style/expression/number_format.cpp Outdated Show resolved Hide resolved
src/mbgl/style/expression/number_format.cpp Outdated Show resolved Hide resolved
@pozdnyakov
Copy link
Contributor

There is a quite significant binary size increase with the patch, removal of unneeded optional could help to fix it.

@pozdnyakov
Copy link
Contributor

@jmalanen pls see @kkaefer's patch removing using <locale> and <iostream>. Using of these classes must be causing the binary size increase.

@1ec5
Copy link
Contributor

1ec5 commented Jun 5, 2019

Use of the platforms’ built-in internationalization functionality will result in much less binary size increase compared to the current implementation in this PR.

@jmalanen jmalanen requested a review from a team June 6, 2019 12:54
Copy link
Contributor

@1ec5 1ec5 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for implementing the iOS/macOS side of things! We’re close, but we do need to figure out the right way to manage these formatter objects, as @julianrex points out.

uint8_t minFractionDigits,
uint8_t maxFractionDigits) {
NSNumberFormatter *_numberFormatter;
_numberFormatter = [[NSNumberFormatter alloc] init];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this method always get called on the same thread? If so, we can initialize the object just once using dispatch_once, hold onto it statically, and modify the options each time the method is called. Otherwise, we’ll need to lazily create a different formatter for each combination of options.

Alternatively, we can drop down to CFNumberFormatter, which might not have the same overhead.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Previously, I had suggest _numberFormatter as the variable name with the assumption that the variable would be global rather than local. The underscore is unnecessary for a local variable.

(Also, you can combine a local variable declaration and definition on the same line.)

Copy link
Contributor Author

@jmalanen jmalanen Jun 19, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for the comments. Now the object is initialized just once using dispatch_once.

uint8_t maxFractionDigits) {
NSNumberFormatter *_numberFormatter;
_numberFormatter = [[NSNumberFormatter alloc] init];
_numberFormatter.locale = !localeId.empty() ? [NSLocale localeWithLocaleIdentifier:@(localeId.c_str())] : nil;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should make sure the default locale matches the default locale of the comparison expression operators as well as the number formatter in GL JS. nil results in either the application’s current locale or the system preferred locale; can’t remember which off the top of my head.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I checked the NSNumberFormatter documentation, but couldn't find what's the default locale in case of nil.

@1ec5 1ec5 added Core The cross-platform C++ core, aka mbgl expressions labels Jun 11, 2019
@jmalanen jmalanen force-pushed the jmalanen-number-format branch 11 times, most recently from f4fa5bd to 855e48f Compare June 19, 2019 12:33
@jmalanen jmalanen requested a review from 1ec5 June 24, 2019 11:04
@jmalanen jmalanen force-pushed the jmalanen-number-format branch 3 times, most recently from 141a46b to 252658f Compare June 25, 2019 10:55
@jmalanen jmalanen requested a review from tmpsantos June 25, 2019 11:27
Copy link
Contributor

@tmpsantos tmpsantos left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, just concerned about adding a dependency on QML for Qt.

platform/qt/src/format_number.cpp Show resolved Hide resolved
optional<std::unique_ptr<Expression>> locale_,
optional<std::unique_ptr<Expression>> currency_,
optional<std::unique_ptr<Expression>> minFractionDigits_,
optional<std::unique_ptr<Expression>> maxFractionDigits_)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why not just std::unique_ptr<Expression> maxFractionDigits_ , maxFractionDigits(std::move(maxFractionDigits_)); (same for others) ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

optional<std::unique_ptr<Expression>> locale_,
optional<std::unique_ptr<Expression>> currency_,
optional<std::unique_ptr<Expression>> minFractionDigits_,
optional<std::unique_ptr<Expression>> maxFractionDigits_);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

complex class needs not-inlined destructor

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

Copy link
Contributor

@pozdnyakov pozdnyakov left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm, thanks for following


QString formatted;
// Qt Locale::toString() API takes only one precision argument
(void)minFractionDigits;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: you don't need to do this, you can just remove minFractionDigits from the function signature.

@jmalanen jmalanen merged commit 0ca8ea6 into master Jun 27, 2019
@jmalanen jmalanen deleted the jmalanen-number-format branch June 28, 2019 11:30
@chloekraw chloekraw modified the milestone: release-ristretto Aug 20, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Core The cross-platform C++ core, aka mbgl expressions iOS Mapbox Maps SDK for iOS macOS Mapbox Maps SDK for macOS
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Port 'number-format' expression to native
6 participants