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
151
152
153
154
155
156
|
#pragma once
#include "../geometry/rect2d.hpp"
#include "../base/mutex.hpp"
#include "../std/deque.hpp"
#include "../std/string.hpp"
#include "../std/utility.hpp"
#include "../std/vector.hpp"
/// Information about stored mwm.
class MwmInfo
{
public:
MwmInfo();
m2::RectD m_limitRect; ///< Limit rect of mwm.
uint8_t m_minScale; ///< Min zoom level of mwm.
uint8_t m_maxScale; ///< Max zoom level of mwm.
inline bool IsExist() const
{
return (m_status == STATUS_ACTIVE || m_status == STATUS_UPDATE);
}
inline bool IsActive() const { return (m_status == STATUS_ACTIVE); }
enum MwmTypeT { COUNTRY, WORLD, COASTS };
MwmTypeT GetType() const;
enum Status
{
STATUS_ACTIVE,
STATUS_TO_REMOVE,
STATUS_REMOVED,
STATUS_UPDATE
};
uint8_t m_lockCount; ///< Number of locks.
uint8_t m_status; ///< Current country status.
};
class MwmSet
{
public:
typedef size_t MwmId;
explicit MwmSet(size_t cacheSize = 5);
virtual ~MwmSet() = 0;
class MwmValueBase
{
public:
virtual ~MwmValueBase() {}
};
// Mwm lock, which is used to lock mwm when its FileContainer is used.
class MwmLock
{
public:
MwmLock(MwmSet & mwmSet, MwmId mwmId);
~MwmLock();
inline MwmValueBase * GetValue() const { return m_pValue; }
string GetCountryName() const;
inline MwmId GetID() const { return m_id; }
private:
MwmSet & m_mwmSet;
MwmId m_id;
MwmValueBase * m_pValue;
};
/// Add new mwm. Returns false, if mwm with given fileName already exists.
/// @param[in] fileName File name (without full path) of country.
/// @param[out] rect Limit rect of country.
/// @return Map format version or -1 if not added
//@{
protected:
int AddImpl(string const & fileName, m2::RectD & rect);
public:
int Add(string const & fileName, m2::RectD & rect);
inline bool Add(string const & fileName)
{
m2::RectD dummy;
return (-1 != Add(fileName, dummy));
}
//@}
/// @name Remove mwm.
//@{
protected:
/// @return true - map is free; false - map is busy
//@{
bool RemoveImpl(MwmId id);
bool RemoveImpl(string const & fileName);
//@}
public:
void Remove(string const & fileName);
void RemoveAll();
//@}
/// @param[in] file File name without extension.
bool IsLoaded(string const & file) const;
/// Get ids of all mwms. Some of them may be with not active status.
/// In that case, LockValue returns NULL.
void GetMwmInfo(vector<MwmInfo> & info) const;
// Clear caches.
void ClearCache();
protected:
/// @return mwm format version
virtual int GetInfo(string const & name, MwmInfo & info) const = 0;
virtual MwmValueBase * CreateValue(string const & name) const = 0;
void Cleanup();
private:
typedef deque<pair<MwmId, MwmValueBase *> > CacheType;
MwmValueBase * LockValue(MwmId id);
void UnlockValue(MwmId id, MwmValueBase * p);
/// Find first removed mwm or add a new one.
/// @precondition This function is always called under mutex m_lock.
MwmId GetFreeId();
/// Do the cleaning for [beg, end) without acquiring the mutex.
/// @precondition This function is always called under mutex m_lock.
void ClearCacheImpl(CacheType::iterator beg, CacheType::iterator end);
CacheType m_cache;
size_t m_cacheSize;
protected:
static const MwmId INVALID_MWM_ID = static_cast<MwmId>(-1);
/// Find mwm with a given name.
/// @precondition This function is always called under mutex m_lock.
MwmId GetIdByName(string const & name);
/// @precondition This function is always called under mutex m_lock.
void ClearCache(MwmId id);
/// Update given MwmInfo.
/// @precondition This function is always called under mutex m_lock.
virtual void UpdateMwmInfo(MwmId id);
vector<MwmInfo> m_info;
vector<string> m_name;
threads::Mutex m_lock;
};
|