#pragma once #include "traffic/speed_groups.hpp" #include "indexer/mwm_set.hpp" #include #include #include namespace platform { class HttpClient; } namespace traffic { // This class is responsible for providing the real-time // information about road traffic for one mwm file. class TrafficInfo { public: static uint8_t const kLatestKeysVersion; static uint8_t const kLatestValuesVersion; enum class Availability { IsAvailable, NoData, ExpiredData, ExpiredApp, Unknown }; struct RoadSegmentId { // m_dir can be kForwardDirection or kReverseDirection. static uint8_t constexpr kForwardDirection = 0; static uint8_t constexpr kReverseDirection = 1; RoadSegmentId(); RoadSegmentId(uint32_t fid, uint16_t idx, uint8_t dir); bool operator==(RoadSegmentId const & o) const { return m_fid == o.m_fid && m_idx == o.m_idx && m_dir == o.m_dir; } bool operator<(RoadSegmentId const & o) const { if (m_fid != o.m_fid) return m_fid < o.m_fid; if (m_idx != o.m_idx) return m_idx < o.m_idx; return m_dir < o.m_dir; } uint32_t GetFid() const { return m_fid; } uint16_t GetIdx() const { return m_idx; } uint8_t GetDir() const { return m_dir; } // The ordinal number of feature this segment belongs to. uint32_t m_fid; // The ordinal number of this segment in the list of // its feature's segments. uint16_t m_idx : 15; // The direction of the segment. uint8_t m_dir : 1; }; // todo(@m) unordered_map? using Coloring = std::map; TrafficInfo() = default; TrafficInfo(MwmSet::MwmId const & mwmId, int64_t currentDataVersion); static TrafficInfo BuildForTesting(Coloring && coloring); void SetTrafficKeysForTesting(std::vector const & keys); // Fetches the latest traffic data from the server and updates the coloring and ETag. // Construct the url by passing an MwmId. // The ETag or entity tag is part of HTTP, the protocol for the World Wide Web. // It is one of several mechanisms that HTTP provides for web cache validation, // which allows a client to make conditional requests. // *NOTE* This method must not be called on the UI thread. bool ReceiveTrafficData(std::string & etag); // Returns the latest known speed group by a feature segment's id // or SpeedGroup::Unknown if there is no information about the segment. SpeedGroup GetSpeedGroup(RoadSegmentId const & id) const; MwmSet::MwmId const & GetMwmId() const { return m_mwmId; } Coloring const & GetColoring() const { return m_coloring; } Availability GetAvailability() const { return m_availability; } // Extracts RoadSegmentIds from mwm and stores them in a sorted order. static void ExtractTrafficKeys(std::string const & mwmPath, std::vector & result); // Adds the unknown values to the partially known coloring map |knownColors| // so that the keys of the resulting map are exactly |keys|. static void CombineColorings(std::vector const & keys, TrafficInfo::Coloring const & knownColors, TrafficInfo::Coloring & result); // Serializes the keys of the coloring map to |result|. // The keys are road segments ids which do not change during // an mwm's lifetime so there's no point in downloading them every time. // todo(@m) Document the format. static void SerializeTrafficKeys(std::vector const & keys, std::vector & result); static void DeserializeTrafficKeys(std::vector const & data, std::vector & result); static void SerializeTrafficValues(std::vector const & values, std::vector & result); static void DeserializeTrafficValues(std::vector const & data, std::vector & result); private: enum class ServerDataStatus { New, NotChanged, NotFound, Error, }; friend void UnitTest_TrafficInfo_UpdateTrafficData(); // todo(@m) A temporary method. Remove it once the keys are added // to the generator and the data is regenerated. bool ReceiveTrafficKeys(); // Tries to read the values of the Coloring map from server into |values|. // Returns result of communicating with server as ServerDataStatus. // Otherwise, returns false and does not change m_coloring. ServerDataStatus ReceiveTrafficValues(std::string & etag, std::vector & values); // Updates the coloring and changes the availability status if needed. bool UpdateTrafficData(std::vector const & values); ServerDataStatus ProcessFailure(platform::HttpClient const & request, int64_t const mwmVersion); // The mapping from feature segments to speed groups (see speed_groups.hpp). Coloring m_coloring; // The keys of the coloring map. The values are downloaded periodically // and combined with the keys to form m_coloring. // *NOTE* The values must be received in the exact same order that the // keys are saved in. std::vector m_keys; MwmSet::MwmId m_mwmId; Availability m_availability = Availability::Unknown; int64_t m_currentDataVersion = 0; }; class TrafficObserver { public: virtual ~TrafficObserver() = default; virtual void OnTrafficInfoClear() = 0; virtual void OnTrafficInfoAdded(traffic::TrafficInfo && info) = 0; virtual void OnTrafficInfoRemoved(MwmSet::MwmId const & mwmId) = 0; }; std::string DebugPrint(TrafficInfo::RoadSegmentId const & id); } // namespace traffic