swift
interpolationsetupprovider.cpp
1 // SPDX-FileCopyrightText: Copyright (C) 2018 swift Project Community / Contributors
2 // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-swift-pilot-client-1
3 
5 
6 using namespace swift::misc::aviation;
7 
8 namespace swift::misc::simulation
9 {
10  CInterpolationAndRenderingSetupPerCallsign
11  IInterpolationSetupProvider::getInterpolationSetupPerCallsignOrDefault(const CCallsign &callsign) const
12  {
13  QReadLocker l(&m_lockSetup);
14  if (!m_setupsPerCallsign.contains(callsign)) { return { callsign, m_globalSetup }; }
15  return m_setupsPerCallsign.value(callsign);
16  }
17 
18  CInterpolationSetupList IInterpolationSetupProvider::getInterpolationSetupsPerCallsign() const
19  {
20  const SetupsPerCallsign setups = this->getSetupsPerCallsign();
21  return { setups.values() };
22  }
23 
24  bool IInterpolationSetupProvider::hasSetupsPerCallsign() const
25  {
26  QReadLocker l(&m_lockSetup);
27  return !m_setupsPerCallsign.isEmpty();
28  }
29 
30  bool IInterpolationSetupProvider::setInterpolationSetupsPerCallsign(const CInterpolationSetupList &setups,
31  bool ignoreSameAsGlobal)
32  {
33  const CInterpolationAndRenderingSetupGlobal gs = this->getInterpolationSetupGlobal();
34  SetupsPerCallsign setupsPerCs;
35  for (const CInterpolationAndRenderingSetupPerCallsign &setup : setups)
36  {
37  if (ignoreSameAsGlobal && setup.isEqualToGlobal(gs)) { continue; }
38  setupsPerCs.insert(setup.getCallsign(), setup);
39  }
40  {
41  QWriteLocker l(&m_lockSetup);
42  if (m_setupsPerCallsign.isEmpty() && setupsPerCs.isEmpty()) { return false; }
43  m_setupsPerCallsign = setupsPerCs;
44  }
45  this->emitInterpolationSetupChanged();
46  return true;
47  }
48 
49  CInterpolationAndRenderingSetupGlobal IInterpolationSetupProvider::getInterpolationSetupGlobal() const
50  {
51  QReadLocker l(&m_lockSetup);
52  return m_globalSetup;
53  }
54 
55  CCallsignSet IInterpolationSetupProvider::getLogCallsigns() const
56  {
57  const SetupsPerCallsign setups = this->getSetupsPerCallsign();
58  CCallsignSet callsigns;
59  for (const auto [callsign, setup] : makePairsRange(setups))
60  {
61  if (setup.logInterpolation()) { callsigns.insert(callsign); }
62  }
63  return callsigns;
64  }
65 
66  bool IInterpolationSetupProvider::isLogCallsign(const CCallsign &callsign) const
67  {
68  QReadLocker l(&m_lockSetup);
69  if (!m_setupsPerCallsign.contains(callsign)) { return false; }
70  return m_setupsPerCallsign[callsign].logInterpolation();
71  }
72 
73  bool IInterpolationSetupProvider::setInterpolationMode(const QString &modeAsString, const CCallsign &callsign)
74  {
75  CInterpolationAndRenderingSetupPerCallsign setup = this->getInterpolationSetupPerCallsignOrDefault(callsign);
76  if (!setup.setInterpolatorMode(modeAsString)) { return false; }
77 
78  // changed value
79  return this->setInterpolationSetupPerCallsign(setup, callsign, true);
80  }
81 
82  bool IInterpolationSetupProvider::setLogInterpolation(bool log, const CCallsign &callsign)
83  {
84  CInterpolationAndRenderingSetupPerCallsign setup = this->getInterpolationSetupPerCallsignOrDefault(callsign);
85  if (!setup.setLogInterpolation(log)) { return false; }
86 
87  // changed value
88  return this->setInterpolationSetupPerCallsign(setup, callsign, true);
89  }
90 
91  bool IInterpolationSetupProvider::setInterpolationSetupGlobal(const CInterpolationAndRenderingSetupGlobal &setup)
92  {
93  {
94  QWriteLocker l(&m_lockSetup);
95  if (m_globalSetup == setup) { return false; }
96  m_globalSetup = setup;
97  }
98  this->emitInterpolationSetupChanged();
99  return true;
100  }
101 
102  bool IInterpolationSetupProvider::setInterpolationSetupPerCallsign(
103  const CInterpolationAndRenderingSetupPerCallsign &setup, const CCallsign &callsign, bool removeGlobalSetup)
104  {
105  if (removeGlobalSetup)
106  {
107  const CInterpolationAndRenderingSetupGlobal gs = this->getInterpolationSetupGlobal();
108  if (setup.isEqualToGlobal(gs))
109  {
110  QWriteLocker l(&m_lockSetup);
111  m_setupsPerCallsign.remove(callsign);
112  return false;
113  }
114  }
115  {
116  QWriteLocker l(&m_lockSetup);
117  m_setupsPerCallsign[callsign] = setup;
118  }
119  this->emitInterpolationSetupChanged();
120  return true;
121  }
122 
123  bool IInterpolationSetupProvider::removeInterpolationSetupPerCallsign(const CCallsign &callsign)
124  {
125  bool removed = false;
126  {
127  QWriteLocker l(&m_lockSetup);
128  removed = m_setupsPerCallsign.remove(callsign) > 0;
129  }
130  if (removed) { this->emitInterpolationSetupChanged(); }
131  return removed;
132  }
133 
134  void IInterpolationSetupProvider::setLogCallsign(bool log, const CCallsign &callsign)
135  {
136  CInterpolationAndRenderingSetupPerCallsign setup = this->getInterpolationSetupPerCallsignOrDefault(callsign);
137  if (setup.logInterpolation() == log) { return; }
138  setup.setLogInterpolation(log);
139  this->setInterpolationSetupPerCallsign(setup, callsign);
140  }
141 
142  void IInterpolationSetupProvider::clearInterpolationLogCallsigns()
143  {
144  SetupsPerCallsign setupsCopy = this->getSetupsPerCallsign();
145  if (setupsCopy.isEmpty()) { return; }
146 
147  // potential risk, changes inbetween in another thread are missed now
148  // on the other side, we keep locks for a minimal time frame
149  SetupsPerCallsign setupsToKeep;
150  CInterpolationAndRenderingSetupGlobal global = this->getInterpolationSetupGlobal();
151  for (auto [callsign, setup] : makePairsRange(setupsCopy))
152  {
153  setup.setLogInterpolation(false);
154  if (setup.isEqualToGlobal(global)) { continue; }
155  setupsToKeep.insert(callsign, setup);
156  }
157  {
158  QWriteLocker l(&m_lockSetup);
159  m_setupsPerCallsign = setupsToKeep;
160  }
161  this->emitInterpolationSetupChanged();
162  }
163 
164  int IInterpolationSetupProvider::clearInterpolationSetupsPerCallsign()
165  {
166  int r = 0;
167  {
168  QWriteLocker l(&m_lockSetup);
169  r = m_setupsPerCallsign.size();
170  m_setupsPerCallsign.clear();
171  }
172 
173  if (r > 0) { this->emitInterpolationSetupChanged(); }
174  return r;
175  }
176 
177  bool IInterpolationSetupProvider::logAnyCallsign() const
178  {
179  const SetupsPerCallsign setupsCopy = this->getSetupsPerCallsign();
180  if (setupsCopy.isEmpty()) { return false; }
181  return std::any_of(
182  setupsCopy.cbegin(), setupsCopy.cend(),
183  [](const CInterpolationAndRenderingSetupPerCallsign &setup) { return setup.logInterpolation(); });
184  }
185 
186  IInterpolationSetupProvider::SetupsPerCallsign IInterpolationSetupProvider::getSetupsPerCallsign() const
187  {
188  QReadLocker l(&m_lockSetup);
189  return m_setupsPerCallsign;
190  }
191 
192  // pin vtables to this file
193  void CInterpolationSetupAware::anchor() {}
194 
195  CInterpolationAndRenderingSetupPerCallsign
196  CInterpolationSetupAware::getInterpolationSetupPerCallsignOrDefault(const CCallsign &callsign) const
197  {
198  if (!this->hasProvider()) { return {}; }
199  return this->provider()->getInterpolationSetupPerCallsignOrDefault(callsign);
200  }
201 
202  CInterpolationAndRenderingSetupGlobal CInterpolationSetupAware::getInterpolationSetupGlobal() const
203  {
204  if (!this->hasProvider()) { return {}; }
205  return this->provider()->getInterpolationSetupGlobal();
206  }
207 } // namespace swift::misc::simulation
iterator insert(const_iterator hint, const T &value)
For compatibility with std::inserter.
Definition: collection.h:199
Value object encapsulating information of a callsign.
Definition: callsign.h:30
Value object for a set of callsigns.
Definition: callsignset.h:26
bool setInterpolatorMode(InterpolatorMode mode)
Set interpolator mode.
Value object for interpolator and rendering per callsign.
bool isEqualToGlobal(const CInterpolationAndRenderingSetupGlobal &globalSetup) const
Equal to global setup?
auto makePairsRange(const T &container)
Returns a const CRange for iterating over the keys and values of a Qt associative container.
Definition: range.h:374
QMap< Key, T >::const_iterator cbegin() const const
QMap< Key, T >::const_iterator cend() const const
QMap< Key, T >::iterator insert(QMap< Key, T >::const_iterator pos, const Key &key, const T &value)
bool isEmpty() const const
QList< T > values() const const