diff options
author | Vladimir Byko-Ianko <v.bykoianko@corp.mail.ru> | 2015-07-30 13:51:24 +0300 |
---|---|---|
committer | Alex Zolotarev <alex@maps.me> | 2015-09-23 02:58:49 +0300 |
commit | c9ea450ec5fd459b4062dcb15a603f64f7ead06b (patch) | |
tree | 6a1df5edfbd90351785554e942c8847a20f38814 | |
parent | 4d1f0e8ef4cb0a2f2cfb4ee289938b28ee0745e4 (diff) |
Correction after colleagues comments. Adding unit tests. Some other changes.
-rw-r--r-- | platform/get_text_by_id.cpp | 23 | ||||
-rw-r--r-- | platform/get_text_by_id.hpp | 6 | ||||
-rw-r--r-- | platform/platform_tests/get_text_by_id_tests.cpp | 80 | ||||
-rw-r--r-- | routing/routing.pro | 1 | ||||
-rw-r--r-- | routing/routing_tests/turns_tts_text_tests.cpp | 111 | ||||
-rw-r--r-- | routing/turns_sound.cpp | 4 | ||||
-rw-r--r-- | routing/turns_sound_settings.cpp | 77 | ||||
-rw-r--r-- | routing/turns_sound_settings.hpp | 99 | ||||
-rw-r--r-- | routing/turns_tts_text.cpp | 149 | ||||
-rw-r--r-- | routing/turns_tts_text.hpp | 5 |
10 files changed, 309 insertions, 246 deletions
diff --git a/platform/get_text_by_id.cpp b/platform/get_text_by_id.cpp index d382787890..d2c8f028a2 100644 --- a/platform/get_text_by_id.cpp +++ b/platform/get_text_by_id.cpp @@ -9,6 +9,7 @@ #include "std/target_os.hpp" + namespace { string GetTextSourceString(platform::TextSource textSouce) @@ -38,19 +39,29 @@ GetTextById::GetTextById(TextSource textSouce, string const & localeName) {GetTextSourceString(textSouce), localeName + ".json"}, "localize.json"); // @TODO(vbykoianko) Add assert if locale path pathToJson is not valid. + LOG(LDEBUG, ("Trying to open json file at path", pathToJson)); string jsonBuffer; ReaderPtr<Reader>(GetPlatform().GetReader(pathToJson)).ReadAsString(jsonBuffer); + InitFromJson(jsonBuffer); +} + +GetTextById::GetTextById(string const & jsonBuffer) +{ + InitFromJson(jsonBuffer); +} +void GetTextById::InitFromJson(string const & jsonBuffer) +{ if (jsonBuffer.empty()) { - ASSERT(false, ("No json files found at the path", pathToJson)); + ASSERT(false, ("No json files found.")); return; } my::Json root(jsonBuffer.c_str()); if (root.get() == nullptr) { - ASSERT(false, ("Cannot parse the json file found at the path", pathToJson)); + ASSERT(false, ("Cannot parse the json file.")); return; } @@ -67,14 +78,14 @@ GetTextById::GetTextById(TextSource textSouce, string const & localeName) ASSERT_EQUAL(m_localeTexts.size(), json_object_size(root.get()), ()); } -pair<string, bool> GetTextById::operator()(string const & textId) const +string GetTextById::operator()(string const & textId) const { if (!IsValid()) - return make_pair(textId, false); + return ""; auto const textIt = m_localeTexts.find(textId); if (textIt == m_localeTexts.end()) - return make_pair(textId, false); - return make_pair(textIt->second, true); + return ""; + return textIt->second; } } // namespace platform diff --git a/platform/get_text_by_id.hpp b/platform/get_text_by_id.hpp index b70bac0cec..45c8fdb5e5 100644 --- a/platform/get_text_by_id.hpp +++ b/platform/get_text_by_id.hpp @@ -19,14 +19,18 @@ class GetTextById { public: GetTextById(TextSource textSouce, string const & localeName); + /// The constructor is used for writing unit tests only. + GetTextById(string const & jsonBuffer); bool IsValid() const { return !m_localeTexts.empty(); } /// @return a pair of a text string in a specified locale for textId and a boolean flag. /// If textId is found in m_localeTexts then the boolean flag is set to true. /// The boolean flag is set to false otherwise. - pair<string, bool> operator()(string const & textId) const; + string operator()(string const & textId) const; private: + void InitFromJson(string const & jsonBuffer); + unordered_map<string, string> m_localeTexts; }; } // namespace platform diff --git a/platform/platform_tests/get_text_by_id_tests.cpp b/platform/platform_tests/get_text_by_id_tests.cpp index e9a7df4bf9..b5228e3138 100644 --- a/platform/platform_tests/get_text_by_id_tests.cpp +++ b/platform/platform_tests/get_text_by_id_tests.cpp @@ -7,69 +7,69 @@ using namespace platform; UNIT_TEST(GetTextByIdEnglishTest) { platform::GetTextById getEnglish(TextSource::TtsSound, "en"); - TEST_EQUAL(getEnglish("make_a_slight_right_turn").first, "Make a slight right turn.", ()); - TEST_EQUAL(getEnglish("in_900_meters").first, "In 900 meters.", ()); - TEST_EQUAL(getEnglish("then").first, "Then.", ()); - TEST_EQUAL(getEnglish("in_1_mile").first, "In one mile.", ()); + TEST_EQUAL(getEnglish("make_a_slight_right_turn"), "Make a slight right turn.", ()); + TEST_EQUAL(getEnglish("in_900_meters"), "In 900 meters.", ()); + TEST_EQUAL(getEnglish("then"), "Then.", ()); + TEST_EQUAL(getEnglish("in_1_mile"), "In one mile.", ()); - TEST_EQUAL(getEnglish("some_nonexistent_key").first, "some_nonexistent_key", ()); - TEST(!getEnglish("some_nonexistent_key").second, ()); - TEST(!getEnglish("").second, ()); - TEST(!getEnglish(" ").second, ()); + TEST_EQUAL(getEnglish("some_nonexistent_key"), "", ()); + TEST_EQUAL(getEnglish("some_nonexistent_key"), "", ()); + TEST_EQUAL(getEnglish(""), "", ()); + TEST_EQUAL(getEnglish(" "), "", ()); } UNIT_TEST(GetTextByIdRussianTest) { platform::GetTextById getRussian(TextSource::TtsSound, "ru"); - TEST_EQUAL(getRussian("in_800_meters").first, "Через 800 метров.", ()); - TEST_EQUAL(getRussian("make_a_slight_right_turn").first, "Плавный поворот направо.", ()); - TEST_EQUAL(getRussian("take_the_6th_exit").first, "6-й поворот с кольца.", ()); - TEST_EQUAL(getRussian("in_1_mile").first, "Через одну милю.", ()); + TEST_EQUAL(getRussian("in_800_meters"), "Через 800 метров.", ()); + TEST_EQUAL(getRussian("make_a_slight_right_turn"), "Плавный поворот направо.", ()); + TEST_EQUAL(getRussian("take_the_6th_exit"), "6-й поворот с кольца.", ()); + TEST_EQUAL(getRussian("in_1_mile"), "Через одну милю.", ()); - TEST_EQUAL(getRussian("some_nonexistent_key").first, "some_nonexistent_key", ()); - TEST(!getRussian("some_nonexistent_key").second, ()); - TEST(!getRussian("").second, ()); - TEST(!getRussian(" ").second, ()); + TEST_EQUAL(getRussian("some_nonexistent_key"), "", ()); + TEST_EQUAL(getRussian("some_nonexistent_key"), "", ()); + TEST_EQUAL(getRussian(""), "", ()); + TEST_EQUAL(getRussian(" "), "", ()); } UNIT_TEST(GetTextByIdKoreanTest) { platform::GetTextById getKorean(TextSource::TtsSound, "ko"); - TEST_EQUAL(getKorean("in_700_meters").first, "700 미터 앞", ()); - TEST_EQUAL(getKorean("make_a_right_turn").first, "우회전입니다.", ()); - TEST_EQUAL(getKorean("take_the_5th_exit").first, "다섯 번째 출구입니다.", ()); - TEST_EQUAL(getKorean("in_5000_feet").first, "5000피트 앞", ()); + TEST_EQUAL(getKorean("in_700_meters"), "700 미터 앞", ()); + TEST_EQUAL(getKorean("make_a_right_turn"), "우회전입니다.", ()); + TEST_EQUAL(getKorean("take_the_5th_exit"), "다섯 번째 출구입니다.", ()); + TEST_EQUAL(getKorean("in_5000_feet"), "5000피트 앞", ()); - TEST_EQUAL(getKorean("some_nonexistent_key").first, "some_nonexistent_key", ()); - TEST(!getKorean("some_nonexistent_key").second, ()); - TEST(!getKorean("").second, ()); - TEST(!getKorean(" ").second, ()); + TEST_EQUAL(getKorean("some_nonexistent_key"), "", ()); + TEST_EQUAL(getKorean("some_nonexistent_key"), "", ()); + TEST_EQUAL(getKorean(""), "", ()); + TEST_EQUAL(getKorean(" "), "", ()); } UNIT_TEST(GetTextByIdArabicTest) { platform::GetTextById getArabic(TextSource::TtsSound, "ar"); - TEST_EQUAL(getArabic("in_1_kilometer").first, "بعد كيلو متر واحدٍ", ()); - TEST_EQUAL(getArabic("leave_the_roundabout").first, "اخرج من الطريق الدوار", ()); - TEST_EQUAL(getArabic("take_the_3rd_exit").first, "اسلك المخرج الثالث", ()); - TEST_EQUAL(getArabic("in_4000_feet").first, "بعد 4000 قدم", ()); + TEST_EQUAL(getArabic("in_1_kilometer"), "بعد كيلو متر واحدٍ", ()); + TEST_EQUAL(getArabic("leave_the_roundabout"), "اخرج من الطريق الدوار", ()); + TEST_EQUAL(getArabic("take_the_3rd_exit"), "اسلك المخرج الثالث", ()); + TEST_EQUAL(getArabic("in_4000_feet"), "بعد 4000 قدم", ()); - TEST_EQUAL(getArabic("some_nonexistent_key").first, "some_nonexistent_key", ()); - TEST(!getArabic("some_nonexistent_key").second, ()); - TEST(!getArabic("").second, ()); - TEST(!getArabic(" ").second, ()); + TEST_EQUAL(getArabic("some_nonexistent_key"), "", ()); + TEST_EQUAL(getArabic("some_nonexistent_key"), "", ()); + TEST_EQUAL(getArabic(""), "", ()); + TEST_EQUAL(getArabic(" "), "", ()); } UNIT_TEST(GetTextByIdFrenchTest) { platform::GetTextById getFrench(TextSource::TtsSound, "fr"); - TEST_EQUAL(getFrench("in_1_5_kilometers").first, "Dans un virgule cinq kilomètre.", ()); - TEST_EQUAL(getFrench("enter_the_roundabout").first, "Prenez le rond-point.", ()); - TEST_EQUAL(getFrench("take_the_2nd_exit").first, "Prenez la deuxième sortie.", ()); - TEST_EQUAL(getFrench("in_3500_feet").first, "Dans 3500 feet.", ()); + TEST_EQUAL(getFrench("in_1_5_kilometers"), "Dans un virgule cinq kilomètre.", ()); + TEST_EQUAL(getFrench("enter_the_roundabout"), "Prenez le rond-point.", ()); + TEST_EQUAL(getFrench("take_the_2nd_exit"), "Prenez la deuxième sortie.", ()); + TEST_EQUAL(getFrench("in_3500_feet"), "Dans 3500 feet.", ()); - TEST_EQUAL(getFrench("some_nonexistent_key").first, "some_nonexistent_key", ()); - TEST(!getFrench("some_nonexistent_key").second, ()); - TEST(!getFrench("").second, ()); - TEST(!getFrench(" ").second, ()); + TEST_EQUAL(getFrench("some_nonexistent_key"), "", ()); + TEST_EQUAL(getFrench("some_nonexistent_key"), "", ()); + TEST_EQUAL(getFrench(""), "", ()); + TEST_EQUAL(getFrench(" "), "", ()); } diff --git a/routing/routing.pro b/routing/routing.pro index b4926f8792..876bcf0c98 100644 --- a/routing/routing.pro +++ b/routing/routing.pro @@ -42,7 +42,6 @@ SOURCES += \ turns_tts_text.cpp \ vehicle_model.cpp \ - HEADERS += \ async_router.hpp \ base/astar_algorithm.hpp \ diff --git a/routing/routing_tests/turns_tts_text_tests.cpp b/routing/routing_tests/turns_tts_text_tests.cpp index 019f623afe..054e41693f 100644 --- a/routing/routing_tests/turns_tts_text_tests.cpp +++ b/routing/routing_tests/turns_tts_text_tests.cpp @@ -3,6 +3,9 @@ #include "routing/turns_sound_settings.hpp" #include "routing/turns_tts_text.hpp" +#include "std/string.hpp" + + namespace { using namespace routing::turns; @@ -46,23 +49,123 @@ UNIT_TEST(GetDirectionTextIdTest) UNIT_TEST(GetTtsTextTest) { + string const engShortJson = "\ + {\ + \"in_300_meters\":\"In 300 meters.\",\ + \"in_500_meters\":\"In 500 meters.\",\ + \"then\":\"Then.\",\ + \"make_a_right_turn\":\"Make a right turn.\",\ + \"make_a_left_turn\":\"Make a left turn.\",\ + \"you_have_reached_the_destination\":\"You have reached the destination.\"\ + }"; + + string const rusShortJson = "\ + {\ + \"in_300_meters\":\"Через 300 метров.\",\ + \"in_500_meters\":\"Через 500 метров.\",\ + \"then\":\"Затем.\",\ + \"make_a_right_turn\":\"Поворот направо.\",\ + \"make_a_left_turn\":\"Поворот налево.\",\ + \"you_have_reached_the_destination\":\"Вы достигли конца маршрута.\"\ + }"; + + GetTtsText getTtsText; //Notification(uint32_t distanceUnits, uint8_t exitNum, bool useThenInsteadOfDistance, // TurnDirection turnDir, LengthUnits lengthUnits) - GetTtsText getTtsText; - Notification const notifiation1(500, 0, false, TurnDirection::TurnRight, LengthUnits::Meters); Notification const notifiation2(300, 0, false, TurnDirection::TurnLeft, LengthUnits::Meters); Notification const notifiation3(0, 0, false, TurnDirection::ReachedYourDestination, LengthUnits::Meters); + Notification const notifiation4(0, 0, true, TurnDirection::TurnLeft, LengthUnits::Meters); - getTtsText.SetLocale("en"); + getTtsText.SetLocaleWithJson(engShortJson); TEST_EQUAL(getTtsText(notifiation1), "In 500 meters. Make a right turn.", ()); TEST_EQUAL(getTtsText(notifiation2), "In 300 meters. Make a left turn.", ()); TEST_EQUAL(getTtsText(notifiation3), "You have reached the destination.", ()); + TEST_EQUAL(getTtsText(notifiation4), "Then. Make a left turn.", ()); - getTtsText.SetLocale("ru"); + getTtsText.SetLocaleWithJson(rusShortJson); TEST_EQUAL(getTtsText(notifiation1), "Через 500 метров. Поворот направо.", ()); TEST_EQUAL(getTtsText(notifiation2), "Через 300 метров. Поворот налево.", ()); TEST_EQUAL(getTtsText(notifiation3), "Вы достигли конца маршрута.", ()); + TEST_EQUAL(getTtsText(notifiation4), "Затем. Поворот налево.", ()); +} + +UNIT_TEST(GetAllSoundedDistMetersTest) +{ + VecPairDist const allSoundedDistMeters = GetAllSoundedDistMeters(); + + TEST(is_sorted(allSoundedDistMeters.cbegin(), allSoundedDistMeters.cend(), + [](PairDist const & p1, PairDist const & p2) + { + return p1.first < p2.first; + }), ()); + + TEST_EQUAL(allSoundedDistMeters.size(), 17, ()); + PairDist const expected1 = { 50, "in_50_meters" }; + TEST_EQUAL(allSoundedDistMeters[0], expected1, ()); + PairDist const expected2 = { 700, "in_700_meters" }; + TEST_EQUAL(allSoundedDistMeters[8], expected2, ()); + PairDist const expected3 = { 3000, "in_3_kilometers" }; + TEST_EQUAL(allSoundedDistMeters[16], expected3, ()); +} + +UNIT_TEST(GetAllSoundedDistFeet) +{ + VecPairDist const allSoundedDistFeet = GetAllSoundedDistFeet(); + + TEST(is_sorted(allSoundedDistFeet.cbegin(), allSoundedDistFeet.cend(), + [](PairDist const & p1, PairDist const & p2) + { + return p1.first < p2.first; + }), ()); + + TEST_EQUAL(allSoundedDistFeet.size(), 22, ()); + PairDist const expected1 = { 50, "in_50_feet" }; + TEST_EQUAL(allSoundedDistFeet[0], expected1, ()); + PairDist const expected2 = { 700, "in_700_feet" }; + TEST_EQUAL(allSoundedDistFeet[7], expected2, ()); + PairDist const expected3 = { 10560, "in_2_miles" }; + TEST_EQUAL(allSoundedDistFeet[21], expected3, ()); +} + +UNIT_TEST(GetSoundedDistMeters) +{ + vector<uint32_t> const soundedDistMeters = GetSoundedDistMeters(); + VecPairDist const allSoundedDistMeters = GetAllSoundedDistMeters(); + + TEST(is_sorted(soundedDistMeters.cbegin(), soundedDistMeters.cend()), ()); + // Checking that allSounded contains any element of inst. + TEST(find_first_of(soundedDistMeters.cbegin(), soundedDistMeters.cend(), + allSoundedDistMeters.cbegin(), allSoundedDistMeters.cend(), + [](uint32_t p1, PairDist const & p2) + { + return p1 == p2.first; + }) != soundedDistMeters.cend(), ()); + + TEST_EQUAL(soundedDistMeters.size(), 11, ()); + TEST_EQUAL(soundedDistMeters[0], 200, ()); + TEST_EQUAL(soundedDistMeters[7], 900, ()); + TEST_EQUAL(soundedDistMeters[10], 2000, ()); +} + +UNIT_TEST(GetSoundedDistFeet) +{ + vector<uint32_t> soundedDistFeet = GetSoundedDistFeet(); + VecPairDist const allSoundedDistFeet = GetAllSoundedDistFeet(); + + TEST(is_sorted(soundedDistFeet.cbegin(), soundedDistFeet.cend()), ()); + // Checking that allSounded contains any element of inst. + TEST(find_first_of(soundedDistFeet.cbegin(), soundedDistFeet.cend(), + allSoundedDistFeet.cbegin(), allSoundedDistFeet.cend(), + [](uint32_t p1, PairDist const & p2) + { + return p1 == p2.first; + }) != soundedDistFeet.cend(), ()); + + TEST_EQUAL(soundedDistFeet.size(), 11, ()); + TEST_EQUAL(soundedDistFeet[0], 500, ()); + TEST_EQUAL(soundedDistFeet[7], 2000, ()); + TEST_EQUAL(soundedDistFeet[10], 5000, ()); } } // namespace diff --git a/routing/turns_sound.cpp b/routing/turns_sound.cpp index 431fa0195b..ba4ffc90a5 100644 --- a/routing/turns_sound.cpp +++ b/routing/turns_sound.cpp @@ -115,13 +115,13 @@ void TurnsSound::SetLengthUnits(LengthUnits units) case LengthUnits::Meters: m_settings = Settings(20 /* notificationTimeSeconds */, 200 /* minNotificationDistanceUnits */, 2000 /* maxNotificationDistanceUnits */, - soundedDistancesMeters /* soundedDistancesUnits */, + GetSoundedDistMeters() /* soundedDistancesUnits */, LengthUnits::Meters /* lengthUnits */); return; case LengthUnits::Feet: m_settings = Settings(20 /* notificationTimeSeconds */, 500 /* minNotificationDistanceUnits */, 5000 /* maxNotificationDistanceUnits */, - soundedDistancesFeet /* soundedDistancesUnits */, + GetSoundedDistFeet() /* soundedDistancesUnits */, LengthUnits::Feet /* lengthUnits */); return; } diff --git a/routing/turns_sound_settings.cpp b/routing/turns_sound_settings.cpp index 223235bf64..5acbf8b384 100644 --- a/routing/turns_sound_settings.cpp +++ b/routing/turns_sound_settings.cpp @@ -4,6 +4,8 @@ #include "base/string_utils.hpp" +#include "std/algorithm.hpp" + namespace routing { @@ -104,6 +106,81 @@ string DebugPrint(Notification const & notification) << ", m_lengthUnits == " << DebugPrint(notification.m_lengthUnits) << " ]" << endl; return out.str(); } + +VecPairDist const & GetAllSoundedDistMeters() +{ + // The vector below has to be sorted. It is checked in unit test GetAllSoundedDistMetersTest + static VecPairDist const inst = + { + { 50, "in_50_meters" }, + { 100, "in_100_meters" }, + { 200, "in_200_meters" }, + { 250, "in_250_meters" }, + { 300, "in_300_meters" }, + { 400, "in_400_meters" }, + { 500, "in_500_meters" }, + { 600, "in_600_meters" }, + { 700, "in_700_meters" }, + { 750, "in_750_meters" }, + { 800, "in_800_meters" }, + { 900, "in_900_meters" }, + { 1000, "in_1_kilometer" }, + { 1500, "in_1_5_kilometers" }, + { 2000, "in_2_kilometers" }, + { 2500, "in_2_5_kilometers" }, + { 3000, "in_3_kilometers" } + }; + return inst; +} + +VecPairDist const & GetAllSoundedDistFeet() +{ + // The vector below has to be sorted. It is checked in unit test GetAllSoundedDistFeet + static VecPairDist const inst = + { + { 50, "in_50_feet" }, + { 100, "in_100_feet" }, + { 200, "in_200_feet" }, + { 300, "in_300_feet" }, + { 400, "in_400_feet" }, + { 500, "in_500_feet" }, + { 600, "in_600_feet" }, + { 700, "in_700_feet" }, + { 800, "in_800_feet" }, + { 900, "in_900_feet" }, + { 1000, "in_1000_feet" }, + { 1500, "in_1500_feet" }, + { 2000, "in_2000_feet" }, + { 2500, "in_2500_feet" }, + { 3000, "in_3000_feet" }, + { 3500, "in_3500_feet" }, + { 4000, "in_4000_feet" }, + { 4500, "in_4500_feet" }, + { 5000, "in_5000_feet" }, + { 5280, "in_1_mile" }, + { 7920, "in_1_5_miles" }, + { 10560, "in_2_miles" } + }; + return inst; +} + +vector<uint32_t> const & GetSoundedDistMeters() +{ + // The vector has to be sorted. Besides that any of its elements has to be contained in + // the vector which GetAllSoundedDistMeters() returns. + // It is checked in the unit test GetSoundedDistMeters. + static vector<uint32_t> const inst = { 200, 300, 400, 500, 600, 700, 800, 900, 1000, 1500, 2000 }; + return inst; +} + +vector<uint32_t> const & GetSoundedDistFeet() +{ + // The vector has to be sorted. Besides that any of its elements has to be contained in + // the vector which GetAllSoundedDistFeet() returns. + // It is checked in the unit test GetSoundedDistFeet. + static vector<uint32_t> const inst = { 500, 600, 700, 800, 900, 1000, 1500, 2000, 3000, 4000, 5000 }; + return inst; +} } // namespace sound } // namespace turns } // namespace routing diff --git a/routing/turns_sound_settings.hpp b/routing/turns_sound_settings.hpp index 5295c7a340..f003911608 100644 --- a/routing/turns_sound_settings.hpp +++ b/routing/turns_sound_settings.hpp @@ -15,81 +15,6 @@ enum class LengthUnits Feet }; -// All sounded distance for TTS in meters and kilometers. -enum class AllSoundedDistancesMeters -{ - In50 = 50, - In100 = 100, - In200 = 200, - In250 = 250, - In300 = 300, - In400 = 400, - In500 = 500, - In600 = 600, - In700 = 700, - In750 = 750, - In800 = 800, - In900 = 900, - InOneKm = 1000, - InOneAndHalfKm = 1500, - InTwoKm = 2000, - InTwoAndHalfKm = 2500, - InThreeKm = 3000 -}; - -// All sounded distance for TTS in feet and miles. -enum class AllSoundedDistancesFeet -{ - In50 = 50, - In100 = 100, - In200 = 200, - In300 = 300, - In400 = 400, - In500 = 500, - In600 = 600, - In700 = 700, - In800 = 800, - In900 = 900, - In1000 = 1000, - In1500 = 1500, - In2000 = 2000, - In2500 = 2500, - In3000 = 3000, - In3500 = 3500, - In4000 = 4000, - In4500 = 4500, - In5000 = 5000, - InOneMile = 5280, - InOneAndHalfMiles = 7920, - InTwoMiles = 10560 -}; - -vector<uint32_t> const soundedDistancesMeters = - { static_cast<uint32_t>(AllSoundedDistancesMeters::In200), - static_cast<uint32_t>(AllSoundedDistancesMeters::In300), - static_cast<uint32_t>(AllSoundedDistancesMeters::In400), - static_cast<uint32_t>(AllSoundedDistancesMeters::In500), - static_cast<uint32_t>(AllSoundedDistancesMeters::In600), - static_cast<uint32_t>(AllSoundedDistancesMeters::In700), - static_cast<uint32_t>(AllSoundedDistancesMeters::In800), - static_cast<uint32_t>(AllSoundedDistancesMeters::In900), - static_cast<uint32_t>(AllSoundedDistancesMeters::InOneKm), - static_cast<uint32_t>(AllSoundedDistancesMeters::InOneAndHalfKm), - static_cast<uint32_t>(AllSoundedDistancesMeters::InTwoKm)}; - -vector<uint32_t> const soundedDistancesFeet = - { static_cast<uint32_t>(AllSoundedDistancesFeet::In500), - static_cast<uint32_t>(AllSoundedDistancesFeet::In600), - static_cast<uint32_t>(AllSoundedDistancesFeet::In700), - static_cast<uint32_t>(AllSoundedDistancesFeet::In800), - static_cast<uint32_t>(AllSoundedDistancesFeet::In900), - static_cast<uint32_t>(AllSoundedDistancesFeet::In1000), - static_cast<uint32_t>(AllSoundedDistancesFeet::In1500), - static_cast<uint32_t>(AllSoundedDistancesFeet::In2000), - static_cast<uint32_t>(AllSoundedDistancesFeet::In3000), - static_cast<uint32_t>(AllSoundedDistancesFeet::In4000), - static_cast<uint32_t>(AllSoundedDistancesFeet::In5000)}; - string DebugPrint(LengthUnits const & lengthUnits); /// \brief The Settings struct is a structure for gathering information about turn sound @@ -180,6 +105,30 @@ struct Notification string DebugPrint(Notification const & turnGeom); +using PairDist = pair<uint32_t, char const *>; +using VecPairDist = vector<PairDist>; + +/// @return a reference to a vector of pairs of a distance in meters and a text id. +/// All the distances are translated in supported languages and can be pronounced. +VecPairDist const & GetAllSoundedDistMeters(); +/// @return a reference to a vector of pairs of a distance in feet and a text id. +/// All the distances are translated in supported languages and can be pronounced. +VecPairDist const & GetAllSoundedDistFeet(); + +// @TODO(vbykoianko) Now GetSoundedDistMeters/Feet() functions returns a subset of +// the result of GetAllSoundedDistMeters/Feet() functions. So GetAllSoundedDistMeters/Feet() +// returns more distances. +// After the tuning of turn sound notification is finished to do +// * remove all unnecessary distances from GetAllSoundedDistMeters/Feet(). +// * remove all unnecessary string form resources. It let us to reduce the size of apk/ipa by 10-20KB. +// * remove GetSoundedDistMeters/Feet() and use lambda in TurnsSound::SetLengthUnits +// to convert from vector<pair<uint32_t, char const *>> to vector<uint32_t>. + +/// @return distance in meters which are used for turn sound generation. +vector<uint32_t> const & GetSoundedDistMeters(); +/// @return distance in feet which are used for turn sound generation. +vector<uint32_t> const & GetSoundedDistFeet(); + } // namespace sound } // namespace turns } // namespace routing diff --git a/routing/turns_tts_text.cpp b/routing/turns_tts_text.cpp index c1027248dc..95f7936b6d 100644 --- a/routing/turns_tts_text.cpp +++ b/routing/turns_tts_text.cpp @@ -1,30 +1,51 @@ #include "routing/turns_sound_settings.hpp" #include "routing/turns_tts_text.hpp" +#include "std/algorithm.hpp" +#include "std/string.hpp" #include "std/utility.hpp" +namespace +{ + using namespace routing::turns::sound; + string DistToTextId(VecPairDist::const_iterator begin, VecPairDist::const_iterator end, uint32_t dist) + { + VecPairDist::const_iterator distToSound = + lower_bound(begin, end, dist, [](PairDist const & p1, uint32_t p2) + { + return p1.first < p2; + }); + if (distToSound == end) + { + ASSERT(false, ("notification.m_distanceUnits is not correct.")); + return ""; + } + return distToSound->second; + } +} // namespace + namespace routing { namespace turns { namespace sound { -GetTtsText::GetTtsText() +void GetTtsText::SetLocale(string const & locale) { - m_getEng.reset(new platform::GetTextById(platform::TextSource::TtsSound, "en")); - ASSERT(m_getEng && m_getEng->IsValid(), ()); + m_getCurLang.reset(new platform::GetTextById(platform::TextSource::TtsSound, locale)); + ASSERT(m_getCurLang && m_getCurLang->IsValid(), ()); } -void GetTtsText::SetLocale(string const & locale) +void GetTtsText::SetLocaleWithJson(string const & jsonBuffer) { - m_getCurLang.reset(new platform::GetTextById(platform::TextSource::TtsSound, locale)); + m_getCurLang.reset(new platform::GetTextById(jsonBuffer)); ASSERT(m_getCurLang && m_getCurLang->IsValid(), ()); } string GetTtsText::operator()(Notification const & notification) const { - if (notification.m_distanceUnits == 0) + if (notification.m_distanceUnits == 0 && !notification.m_useThenInsteadOfDistance) return GetTextById(GetDirectionTextId(notification)); return GetTextById(GetDistanceTextId(notification)) + " " + @@ -35,16 +56,12 @@ string GetTtsText::GetTextById(string const & textId) const { ASSERT(!textId.empty(), ()); - platform::GetTextById const & getCurLang = *m_getCurLang; - platform::GetTextById const & getEng = *m_getEng; - if (m_getCurLang && m_getCurLang->IsValid()) + if (!m_getCurLang || !m_getCurLang->IsValid()) { - pair<string, bool> const text = getCurLang(textId); - if (text.second) - return text.first; // textId is found in m_getCurLang - return getEng(textId).first; // textId is not found in m_getCurLang + ASSERT(false, ()); + return ""; } - return getEng(textId).first; + return (*m_getCurLang)(textId); } string GetDistanceTextId(Notification const & notification) @@ -64,107 +81,11 @@ string GetDistanceTextId(Notification const & notification) ASSERT(false, ()); return ""; case LengthUnits::Meters: - for (uint32_t const dist : soundedDistancesMeters) - { - if (notification.m_distanceUnits == dist) - { - switch(static_cast<AllSoundedDistancesMeters>(notification.m_distanceUnits)) - { - case AllSoundedDistancesMeters::In50: - return "in_50_meters"; - case AllSoundedDistancesMeters::In100: - return "in_100_meters"; - case AllSoundedDistancesMeters::In200: - return "in_200_meters"; - case AllSoundedDistancesMeters::In250: - return "in_250_meters"; - case AllSoundedDistancesMeters::In300: - return "in_300_meters"; - case AllSoundedDistancesMeters::In400: - return "in_400_meters"; - case AllSoundedDistancesMeters::In500: - return "in_500_meters"; - case AllSoundedDistancesMeters::In600: - return "in_600_meters"; - case AllSoundedDistancesMeters::In700: - return "in_700_meters"; - case AllSoundedDistancesMeters::In750: - return "in_750_meters"; - case AllSoundedDistancesMeters::In800: - return "in_800_meters"; - case AllSoundedDistancesMeters::In900: - return "in_900_meters"; - case AllSoundedDistancesMeters::InOneKm: - return "in_1_kilometer"; - case AllSoundedDistancesMeters::InOneAndHalfKm: - return "in_1_5_kilometers"; - case AllSoundedDistancesMeters::InTwoKm: - return "in_2_kilometers"; - case AllSoundedDistancesMeters::InTwoAndHalfKm: - return "in_2_5_kilometers"; - case AllSoundedDistancesMeters::InThreeKm: - return "in_3_kilometers"; - } - } - } - ASSERT(false, ("notification.m_distanceUnits is not correct. Check soundedDistancesMeters.")); - return ""; + return DistToTextId(GetAllSoundedDistMeters().cbegin(), GetAllSoundedDistMeters().cend(), + notification.m_distanceUnits); case LengthUnits::Feet: - for (uint32_t const dist : soundedDistancesFeet) - { - if (notification.m_distanceUnits == dist) - { - switch(static_cast<AllSoundedDistancesFeet>(notification.m_distanceUnits)) - { - case AllSoundedDistancesFeet::In50: - return "in_50_feet"; - case AllSoundedDistancesFeet::In100: - return "in_100_feet"; - case AllSoundedDistancesFeet::In200: - return "in_200_feet"; - case AllSoundedDistancesFeet::In300: - return "in_300_feet"; - case AllSoundedDistancesFeet::In400: - return "in_400_feet"; - case AllSoundedDistancesFeet::In500: - return "in_500_feet"; - case AllSoundedDistancesFeet::In600: - return "in_600_feet"; - case AllSoundedDistancesFeet::In700: - return "in_700_feet"; - case AllSoundedDistancesFeet::In800: - return "in_800_feet"; - case AllSoundedDistancesFeet::In900: - return "in_900_feet"; - case AllSoundedDistancesFeet::In1000: - return "in_1000_feet"; - case AllSoundedDistancesFeet::In1500: - return "in_1500_feet"; - case AllSoundedDistancesFeet::In2000: - return "in_2000_feet"; - case AllSoundedDistancesFeet::In2500: - return "in_2500_feet"; - case AllSoundedDistancesFeet::In3000: - return "in_3000_feet"; - case AllSoundedDistancesFeet::In3500: - return "in_3500_feet"; - case AllSoundedDistancesFeet::In4000: - return "in_4000_feet"; - case AllSoundedDistancesFeet::In4500: - return "in_4500_feet"; - case AllSoundedDistancesFeet::In5000: - return "in_5000_feet"; - case AllSoundedDistancesFeet::InOneMile: - return "in_1_mile"; - case AllSoundedDistancesFeet::InOneAndHalfMiles: - return "in_1_5_miles"; - case AllSoundedDistancesFeet::InTwoMiles: - return "in_2_miles"; - } - } - } - ASSERT(false, ("notification.m_distanceUnits is not correct. Check soundedDistancesFeet.")); - return ""; + return DistToTextId(GetAllSoundedDistFeet().cbegin(), GetAllSoundedDistFeet().cend(), + notification.m_distanceUnits); } ASSERT(false, ()); return ""; diff --git a/routing/turns_tts_text.hpp b/routing/turns_tts_text.hpp index a74c455207..e83cc4e834 100644 --- a/routing/turns_tts_text.hpp +++ b/routing/turns_tts_text.hpp @@ -21,16 +21,15 @@ struct Notification; class GetTtsText { public: - GetTtsText(); - string operator()(Notification const & notification) const; void SetLocale(string const & locale); + /// SetLocaleWithJson is used for writing unit tests only. + void SetLocaleWithJson(string const & jsonBuffer); private: string GetTextById(string const & textId) const; unique_ptr<platform::GetTextById> m_getCurLang; - unique_ptr<platform::GetTextById> m_getEng; }; /// Generates text message id about the distance of the notification. For example: In 300 meters. |