Welcome to mirror list, hosted at ThFree Co, Russian Federation.

transit_reader.hpp « transit « map - github.com/mapsme/omim.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 4b6a8c81b19fe8ba22b0cbd13aa6b40223c1152a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
#pragma once

#include "transit/transit_display_info.hpp"

#include "drape_frontend/drape_engine_safe_ptr.hpp"

#include "geometry/screenbase.hpp"

#include "indexer/data_source.hpp"
#include "indexer/feature_decl.hpp"

#include "base/thread.hpp"
#include "base/thread_pool.hpp"

#include <chrono>
#include <condition_variable>
#include <cstdint>
#include <functional>
#include <map>
#include <memory>
#include <mutex>
#include <set>
#include <string>
#include <vector>

class DataSource;

using FeatureCallback = std::function<void (FeatureType const &)>;
using TReadFeaturesFn = std::function<void (FeatureCallback const & , std::vector<FeatureID> const &)>;

class ReadTransitTask: public threads::IRoutine
{
public:
  ReadTransitTask(DataSource & dataSource, TReadFeaturesFn const & readFeaturesFn)
    : m_dataSource(dataSource), m_readFeaturesFn(readFeaturesFn)
  {}

  void Init(uint64_t id, MwmSet::MwmId const & mwmId,
            std::unique_ptr<TransitDisplayInfo> transitInfo = nullptr);
  uint64_t GetId() const { return m_id; }
  bool GetSuccess() const { return m_success; }

  void Do() override;
  void Reset() override;

  std::unique_ptr<TransitDisplayInfo> && GetTransitInfo();

private:
  template <typename T, typename TID>
  void FillItemsByIdMap(std::vector<T> const & items, std::map<TID, T> & itemsById)
  {
    for (auto const & item : items)
    {
      if (!m_loadSubset)
      {
        itemsById.insert(make_pair(item.GetId(), item));
      }
      else
      {
        auto it = itemsById.find(item.GetId());
        if (it != itemsById.end())
          it->second = item;
      }
    }
  };

  DataSource & m_dataSource;
  TReadFeaturesFn m_readFeaturesFn;

  uint64_t m_id = 0;
  MwmSet::MwmId m_mwmId;
  std::unique_ptr<TransitDisplayInfo> m_transitInfo;

  bool m_loadSubset = false;
  // Sets to true if Do() method was executed successfully.
  bool m_success = false;
};

class TransitReadManager
{
public:
  enum class TransitSchemeState
  {
    Disabled,
    Enabled,
    NoData,
  };

  using GetMwmsByRectFn = function<vector<MwmSet::MwmId>(m2::RectD const &)>;
  using TransitStateChangedFn = function<void(TransitSchemeState)>;

  TransitReadManager(DataSource & dataSource, TReadFeaturesFn const & readFeaturesFn,
                     GetMwmsByRectFn const & getMwmsByRectFn);
  ~TransitReadManager();

  void Start();
  void Stop();

  void SetDrapeEngine(ref_ptr<df::DrapeEngine> engine);
  void SetStateListener(TransitStateChangedFn const & onStateChangedFn);

  bool GetTransitDisplayInfo(TransitDisplayInfos & transitDisplayInfos);

  void EnableTransitSchemeMode(bool enable);
  void UpdateViewport(ScreenBase const & screen);
  void OnMwmDeregistered(MwmSet::MwmId const & mwmId);
  void Invalidate();

private:
  void OnTaskCompleted(threads::IRoutine * task);

  void ChangeState(TransitSchemeState newState);
  void ShrinkCacheToAllowableSize();
  void ClearCache(MwmSet::MwmId const & mwmId);

  std::unique_ptr<threads::ThreadPool> m_threadsPool;

  std::mutex m_mutex;
  std::condition_variable m_event;

  uint64_t m_nextTasksGroupId = 0;
  std::map<uint64_t, size_t> m_tasksGroups;

  DataSource & m_dataSource;
  TReadFeaturesFn m_readFeaturesFn;

  df::DrapeEngineSafePtr m_drapeEngine;

  TransitSchemeState m_state = TransitSchemeState::Disabled;
  TransitStateChangedFn m_onStateChangedFn;

  struct CacheEntry
  {
    CacheEntry(std::chrono::time_point<std::chrono::steady_clock> const & activeTime)
      : m_lastActiveTime(activeTime)
    {}

    bool m_isLoaded = false;
    size_t m_dataSize = 0;
    std::chrono::time_point<std::chrono::steady_clock> m_lastActiveTime;
  };

  GetMwmsByRectFn m_getMwmsByRectFn;
  std::vector<MwmSet::MwmId> m_lastVisibleMwms;
  std::set<MwmSet::MwmId> m_lastActiveMwms;
  std::map<MwmSet::MwmId, CacheEntry> m_mwmCache;
  size_t m_cacheSize = 0;
  bool m_isSchemeMode = false;
  pair<ScreenBase, bool> m_currentModelView = {ScreenBase(), false /* initialized */};
};