diff --git a/base/base.pro b/base/base.pro index 2d0599c67e..c43bda3b11 100644 --- a/base/base.pro +++ b/base/base.pro @@ -79,3 +79,4 @@ HEADERS += \ scheduled_task.hpp \ thread_pool.hpp \ stl_iterator.hpp \ + enum_flags.hpp \ diff --git a/base/enum_flags.hpp b/base/enum_flags.hpp new file mode 100644 index 0000000000..687c8414cb --- /dev/null +++ b/base/enum_flags.hpp @@ -0,0 +1,88 @@ +/* +Copyright (c) 2013, Yuri Yaryshev (aka Lord Odin) + +The MIT License (MIT) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + +/* +Usage sample: + +#indlude "enum_flags.h" + +ENUM_FLAGS(foo_t) +enum class foo_t + { + none = 0x00, + a = 0x01, + b = 0x02 + }; + +ENUM_FLAGS(foo2_t) +enum class foo2_t + { + none = 0x00, + d = 0x01, + e = 0x02 + }; + +int _tmain(int argc, _TCHAR* argv[]) + { + if(flags(foo_t::a & foo_t::b)) {}; + // if(flags(foo2_t::d & foo_t::b)) {}; // Type safety test - won't compile if uncomment + }; + +*/ + +#ifndef __ENUM_FLAGS_H__ +#define __ENUM_FLAGS_H__ + +/* +Use this line before header, if you don't want flags(T x) function to be implemented for your enum. +#define USE_ENUM_FLAGS_FUNCTION 0 +*/ + +#ifndef USE_ENUM_FLAGS_FUNCTION +#define USE_ENUM_FLAGS_FUNCTION 1 +#endif + + +#define ENUM_FLAGS_EX_NO_FLAGS_FUNC(T,INT_T) \ +enum class T; \ +inline bool operator & (T x, T y) { return (static_cast(x) & static_cast(y)) != 0; }; \ +inline T operator | (T x, T y) { return static_cast (static_cast(x) | static_cast(y)); }; \ +inline T operator ^ (T x, T y) { return static_cast (static_cast(x) ^ static_cast(y)); }; \ +inline T operator ~ (T x) { return static_cast (~static_cast(x)); }; \ +inline T& operator |= (T& x, T y) { x = x | y; return x; }; \ +inline T& operator ^= (T& x, T y) { x = x ^ y; return x; }; + +#if(USE_ENUM_FLAGS_FUNCTION) + + #define ENUM_FLAGS_EX(T,INT_T) ENUM_FLAGS_EX_NO_FLAGS_FUNC(T,INT_T) \ + inline bool flags(T x) { return static_cast(x) != 0;}; + +#else + + #define ENUM_FLAGS_EX(T,INT_T) ENUM_FLAGS_EX_NO_FLAGS_FUNC(T,INT_T) + +#endif + +#define ENUM_FLAGS(T) ENUM_FLAGS_EX(T,intptr_t) +#endif diff --git a/map/framework.cpp b/map/framework.cpp index 436355d975..e87c40a18b 100644 --- a/map/framework.cpp +++ b/map/framework.cpp @@ -182,6 +182,7 @@ static void GetResourcesMaps(vector & outMaps) Framework::Framework() : m_navigator(m_scales), m_animator(this), + m_routingSession(bind(&Framework::BuildRouteFailed, this, _1)), m_queryMaxScaleMode(false), m_width(0), m_height(0), @@ -299,9 +300,7 @@ void Framework::DownloadCountry(TIndex const & index, TMapOptions const & option if (validOptions == TMapOptions::EMapOnly || GetPlatform().IsPro()) m_storage.DownloadCountry(index, options); else - { - /// @TODO Show BuyProToRouting Dialog - } + ShowDialog("routing_only_in_pro", DialogOptions::Cancel | DialogOptions::BuyPro); } TStatus Framework::GetCountryStatus(TIndex const & index) const @@ -656,6 +655,17 @@ void Framework::DrawModel(shared_ptr const & e, Invalidate(); } +void Framework::ShowDialog(string const & messageID, DialogOptions const & options) +{ + if (m_showDlgCallback) + m_showDlgCallback(messageID, options); +} + +void Framework::SetShowDialogListener(TShowDialogFn const & fn) +{ + m_showDlgCallback = fn; +} + bool Framework::IsCountryLoaded(m2::PointD const & pt) const { // Correct, but slow version (check country polygon). @@ -1864,6 +1874,13 @@ void Framework::BuildRoute(m2::PointD const & destination) }); } +void Framework::BuildRouteFailed(IRouter::ResultCode errorCode) +{ + ///@TODO resolve message about this error + string messageID = "route_build_failed_reason"; + ShowDialog(messageID, DialogOptions::Ok); +} + void Framework::FollowRoute() { GetLocationState()->StartRouteFollow(); diff --git a/map/framework.hpp b/map/framework.hpp index 97295b74cc..167d1dfcce 100644 --- a/map/framework.hpp +++ b/map/framework.hpp @@ -32,6 +32,7 @@ #include "../geometry/rect2d.hpp" #include "../geometry/screenbase.hpp" +#include "../base/enum_flags.hpp" #include "../base/strings_bundle.hpp" #include "../std/vector.hpp" @@ -55,6 +56,13 @@ namespace anim { class Controller; } class CountryStatusDisplay; class BenchmarkEngine; +ENUM_FLAGS(DialogOptions) +enum class DialogOptions +{ + Cancel = 0x1, + Ok = 0x2, + BuyPro = 0x4 +}; /// Uncomment line to make fixed position settings and /// build version for screenshots. @@ -240,6 +248,14 @@ public: m2::RectD const & renderRect, int baseScale, bool isTilingQuery); + void ShowDialog(string const & messageID, DialogOptions const & options); + + typedef function TShowDialogFn; + void SetShowDialogListener(TShowDialogFn const & fn); + +private: + TShowDialogFn m_showDlgCallback; + private: search::Engine * GetSearchEngine() const; search::SearchParams m_lastSearch; @@ -484,6 +500,7 @@ public: //@{ bool IsRoutingActive() const; void BuildRoute(m2::PointD const & destination); + void BuildRouteFailed(routing::IRouter::ResultCode errorCode); void FollowRoute(); void CloseRouting(); void GetRouteFollowingInfo(location::FollowingInfo & info) const; diff --git a/map/routing_session.cpp b/map/routing_session.cpp index 72564a4f7e..b3d1d856d7 100644 --- a/map/routing_session.cpp +++ b/map/routing_session.cpp @@ -14,22 +14,23 @@ namespace routing static int const ON_ROUTE_MISSED_COUNT = 10; -RoutingSession::RoutingSession() +RoutingSession::RoutingSession(TErrorCallbackFn const & errorFn) : m_router(nullptr) , m_route(string()) , m_state(RoutingNotActive) + , m_errorCallback(errorFn) { } void RoutingSession::BuildRoute(m2::PointD const & startPoint, m2::PointD const & endPoint, - ReadyCallback const & callback) + TReadyCallbackFn const & callback) { ASSERT(m_router != nullptr, ()); m_router->SetFinalPoint(endPoint); RebuildRoute(startPoint, callback); } -void RoutingSession::RebuildRoute(m2::PointD const & startPoint, ReadyCallback const & callback) +void RoutingSession::RebuildRoute(m2::PointD const & startPoint, TReadyCallbackFn const & callback) { ASSERT(m_router != nullptr, ()); Reset(); @@ -44,7 +45,7 @@ void RoutingSession::RebuildRoute(m2::PointD const & startPoint, ReadyCallback c } else { - /// @todo Save error code here and return to the UI by demand. + m_errorCallback(e); } }); } diff --git a/map/routing_session.hpp b/map/routing_session.hpp index b3f0b10938..898d75f3de 100644 --- a/map/routing_session.hpp +++ b/map/routing_session.hpp @@ -38,16 +38,16 @@ public: * RouteFinished -> RouteNotReady // start new route */ - RoutingSession(); + typedef function TErrorCallbackFn; + RoutingSession(TErrorCallbackFn const & errorFn); void SetRouter(IRouter * router); - typedef function ReadyCallback; + typedef function TReadyCallbackFn; /// @param[in] startPoint and endPoint in mercator - void BuildRoute(m2::PointD const & startPoint, m2::PointD const & endPoint, - ReadyCallback const & callback); + void BuildRoute(m2::PointD const & startPoint, m2::PointD const & endPoint, TReadyCallbackFn const & callback); - void RebuildRoute(m2::PointD const & startPoint, ReadyCallback const & callback); + void RebuildRoute(m2::PointD const & startPoint, TReadyCallbackFn const & callback); bool IsActive() const; void Reset(); @@ -62,6 +62,8 @@ private: Route m_route; State m_state; + TErrorCallbackFn m_errorCallback; + /// Current position metrics to check for RouteNeedRebuild state. double m_lastDistance; int m_moveAwayCounter; diff --git a/storage/storage_defines.hpp b/storage/storage_defines.hpp index 10b63f4276..9921a61907 100644 --- a/storage/storage_defines.hpp +++ b/storage/storage_defines.hpp @@ -1,5 +1,7 @@ #pragma once +#include "../base/enum_flags.hpp" + #include "../std/stdint.hpp" #include "../std/utility.hpp" @@ -18,27 +20,13 @@ namespace storage EOutOfMemFailed // EDownloadFailed because not enough memory }; - enum class TMapOptions : uint8_t + ENUM_FLAGS(TMapOptions) + enum class TMapOptions { EMapOnly = 0x1, ECarRouting = 0x2, EMapWithCarRouting = 0x3 }; - inline TMapOptions operator | (TMapOptions const & lhs, TMapOptions const & rhs) - { - return static_cast(static_cast(lhs) | static_cast(rhs)); - } - - inline TMapOptions & operator |= (TMapOptions & lhs, TMapOptions rhs) - { - return lhs = static_cast(static_cast(lhs) | static_cast(rhs)); - } - - inline bool operator & (TMapOptions const & testedFlags, TMapOptions const & match) - { - return (static_cast(testedFlags) & static_cast(match)) != 0; - } - typedef pair LocalAndRemoteSizeT; }