Renderer, ...: use PixelRect::GetCenter()
[xcsoar.git] / src / Device / SettingsMap.hpp
blob4c60422e3cfa10d23f75f2f5ceadd075d544cd13
1 /*
2 Copyright_License {
4 XCSoar Glide Computer - http://www.xcsoar.org/
5 Copyright (C) 2000-2013 The XCSoar Project
6 A detailed list of copyright holders can be found in the file "AUTHORS".
8 This program is free software; you can redistribute it and/or
9 modify it under the terms of the GNU General Public License
10 as published by the Free Software Foundation; either version 2
11 of the License, or (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
24 #ifndef XCSOAR_DEVICE_SETTINGS_MAP_HPP
25 #define XCSOAR_DEVICE_SETTINGS_MAP_HPP
27 #include "Util/Serial.hpp"
28 #include "Time/TimeoutClock.hpp"
29 #include "Thread/Mutex.hpp"
30 #include "Operation/Operation.hpp"
32 #ifdef HAVE_POSIX
33 #include "Thread/Cond.hpp"
34 #else
35 #include "OS/Sleep.h"
36 #endif
38 #include <map>
39 #include <string>
40 #include <algorithm>
42 /**
43 * A thread-safe store for named values received from a device. The
44 * driver's NMEA parser fills values, and another thread may wait for
45 * this.
47 * The caller is responsible for locking and unlocking an instance for
48 * each method call.
50 template<typename V>
51 class DeviceSettingsMap {
52 Mutex mutex;
53 #ifdef HAVE_POSIX
54 Cond cond;
55 #endif
57 struct Item {
58 V value;
60 bool old;
62 explicit Item(const V &_value):value(_value) {}
65 typedef std::map<std::string, Item> Map;
67 Map map;
69 public:
70 class const_iterator {
71 typename Map::const_iterator i;
73 public:
74 explicit const_iterator(typename Map::const_iterator _i):i(_i) {}
76 const V &operator*() const {
77 return i->second.value;
80 const V *operator->() const {
81 return &i->second.value;
84 bool operator==(const const_iterator &other) const {
85 return i == other.i;
88 bool operator!=(const const_iterator &other) const {
89 return i != other.i;
93 void Lock() {
94 mutex.Lock();
97 void Unlock() {
98 mutex.Unlock();
101 operator Mutex &() const {
102 return const_cast<Mutex &>(mutex);
105 template<typename K>
106 void MarkOld(const K &key) {
107 auto i = map.find(key);
108 if (i != map.end())
109 i->second.old = true;
112 template<typename K>
113 const_iterator Wait(const K &key, OperationEnvironment &env,
114 TimeoutClock &timeout) {
115 while (true) {
116 auto i = map.find(key);
117 if (i != map.end() && !i->second.old)
118 return const_iterator(i);
120 if (env.IsCancelled())
121 return end();
123 int remaining = timeout.GetRemainingSigned();
124 if (remaining <= 0)
125 return end();
127 #ifdef HAVE_POSIX
128 cond.Wait(*this, remaining);
129 #else
130 /* Windows doesn't have condition objects, sorry for this ugly
131 kludge :-( */
132 Sleep(std::min(remaining, 250));
133 #endif
137 template<typename K>
138 const_iterator Wait(const K &key, OperationEnvironment &env,
139 unsigned timeout_ms) {
140 TimeoutClock timeout(timeout_ms);
141 return Wait(key, env, timeout);
144 template<typename K>
145 gcc_pure
146 const_iterator find(const K &key) const {
147 return const_iterator(map.find(key));
150 gcc_pure
151 const_iterator end() const {
152 return const_iterator(map.end());
155 template<typename K>
156 void Set(const K &key, const V &value) {
157 auto i = map.insert(std::make_pair(key, Item(value)));
158 Item &item = i.first->second;
159 item.old = false;
160 if (!i.second)
161 item.value = value;
163 #ifdef HAVE_POSIX
164 cond.Broadcast();
165 #endif
168 template<typename K>
169 void erase(const K &key) {
170 map.erase(key);
173 void clear() {
174 map.clear();
178 #endif