Phonon  4.7.0
 All Classes Namespaces Functions Variables Enumerations Enumerator Properties Pages
globaldescriptioncontainer.h
1 /*
2  Copyright (C) 2011 Harald Sitter <sitter@kde.org>
3 
4  This library is free software; you can redistribute it and/or
5  modify it under the terms of the GNU Lesser General Public
6  License as published by the Free Software Foundation; either
7  version 2.1 of the License, or (at your option) version 3, or any
8  later version accepted by the membership of KDE e.V. (or its
9  successor approved by the membership of KDE e.V.), Nokia Corporation
10  (or its successors, if any) and the KDE Free Qt Foundation, which shall
11  act as a proxy defined in Section 6 of version 3 of the license.
12 
13  This library 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 GNU
16  Lesser General Public License for more details.
17 
18  You should have received a copy of the GNU Lesser General Public
19  License along with this library. If not, see <http://www.gnu.org/licenses/>.
20 */
21 
22 #ifndef PHONON_GLOBALDESCRIPTIONCONTAINER_H
23 #define PHONON_GLOBALDESCRIPTIONCONTAINER_H
24 
25 #include <QtCore/QMap>
26 #include <QtCore/QDebug>
27 #include <QtCore/QtGlobal>
28 
29 #include <phonon/objectdescription.h>
30 
31 namespace Phonon
32 {
33 
34 class MediaController;
35 
59 template <typename D>
61 {
62 public:
63  typedef int global_id_t;
64  typedef int local_id_t;
65 
66  typedef QMap<global_id_t, D> GlobalDescriptorMap;
67  typedef QMapIterator<global_id_t, D> GlobalDescriptorMapIterator;
68 
69  typedef QMap<global_id_t, local_id_t> LocalIdMap;
70  typedef QMapIterator<global_id_t, local_id_t> LocaIdMapIterator;
71 
72 public:
73  static GlobalDescriptionContainer *self;
74 
75  static GlobalDescriptionContainer *instance()
76  {
77  if (!self)
78  self = new GlobalDescriptionContainer;
79  return self;
80  }
81 
82  virtual ~GlobalDescriptionContainer() {}
83 
88  {
89  QList<int> list;
90  GlobalDescriptorMapIterator it(m_globalDescriptors);
91  while (it.hasNext()) {
92  it.next();
93  list << it.key();
94  }
95  return list;
96  }
97 
103  D fromIndex(global_id_t key)
104  {
105  return m_globalDescriptors.value(key, D());
106  }
107 
108  // ----------- MediaController Specific ----------- //
109 
116  void register_(void *obj)
117  {
118  Q_ASSERT(obj);
119  Q_ASSERT(m_localIds.find(obj) == m_localIds.end());
120  m_localIds[obj] = LocalIdMap();
121  }
122 
130  void unregister_(void *obj)
131  {
132  // TODO: remove all descriptions that are *only* associated with this MC
133  Q_ASSERT(obj);
134  Q_ASSERT(m_localIds.find(obj) != m_localIds.end());
135  m_localIds[obj].clear();
136  m_localIds.remove(obj);
137  }
138 
144  void clearListFor(void *obj)
145  {
146  Q_ASSERT(obj);
147  Q_ASSERT_X(m_localIds.find(obj) != m_localIds.end(),
148  "clearing list",
149  "the object is not registered!");
150  m_localIds[obj].clear();
151  }
152 
166  void add(void *obj,
167  local_id_t index, const QString &name, const QString &type = QString())
168  {
169  Q_ASSERT(obj);
170  Q_ASSERT(m_localIds.find(obj) != m_localIds.end());
171 
172  QHash<QByteArray, QVariant> properties;
173  properties.insert("name", name);
174  properties.insert("description", "");
175  properties.insert("type", type);
176 
177  // Empty lists will start at 0.
178  global_id_t id = 0;
179  {
180  // Find id, either a descriptor with name and type is already present
181  // or get the next available index.
182  GlobalDescriptorMapIterator it(m_globalDescriptors);
183  while (it.hasNext()) {
184  it.next();
185  if (it.value().property("name") == name &&
186  it.value().property("type") == type) {
187  id = it.value().index();
188  }
189  }
190  if (id == 0)
191  id = nextFreeIndex();
192  }
193  D descriptor = D(id, properties);
194 
195  m_globalDescriptors.insert(id, descriptor);
196  m_localIds[obj].insert(id, index);
197  }
198 
207  void add(void *obj,
208  D descriptor)
209  {
210  Q_ASSERT(obj);
211  Q_ASSERT(m_localIds.find(obj) != m_localIds.end());
212  Q_ASSERT(m_globalDescriptors.find(descriptor.index()) == m_globalDescriptors.end());
213 
214  m_globalDescriptors.insert(descriptor.index(), descriptor);
215  m_localIds[obj].insert(descriptor.index(), descriptor.index());
216  }
217 
229  QList<D> listFor(const void *obj) const
230  {
231  Q_ASSERT(obj);
232  Q_ASSERT(m_localIds.find(obj) != m_localIds.end());
233 
234  QList<D> list;
235  LocaIdMapIterator it(m_localIds.value(obj));
236  while (it.hasNext()) {
237  it.next();
238  Q_ASSERT(m_globalDescriptors.find(it.key()) != m_globalDescriptors.end());
239  list << m_globalDescriptors[it.key()];
240  }
241  return list;
242  }
243 
250  int localIdFor(const void *obj, global_id_t key) const
251  {
252  Q_ASSERT(obj);
253  Q_ASSERT(m_localIds.find(obj) != m_localIds.end());
254  if (m_localIds[obj].find(key) == m_localIds[obj].end())
255  qWarning() << "WARNING:" << Q_FUNC_INFO
256  << ": supplied global ID is unknown for the object ("
257  << obj << ")";
258  return m_localIds[obj].value(key, 0);
259  }
260 
261 protected:
263  m_peak(0)
264  {
265  }
266 
270  global_id_t nextFreeIndex()
271  {
272  return ++m_peak;
273  }
274 
275  GlobalDescriptorMap m_globalDescriptors;
276  QMap<const void *, LocalIdMap> m_localIds;
277 
278  global_id_t m_peak;
279 };
280 
281 template <typename D>
282 GlobalDescriptionContainer<D> *GlobalDescriptionContainer<D>::self = 0;
283 
284 typedef GlobalDescriptionContainer<AudioChannelDescription> GlobalAudioChannels;
285 typedef GlobalDescriptionContainer<SubtitleDescription> GlobalSubtitles;
286 
287 } // Namespace Phonon
288 
289 #endif // PHONON_GLOBALDESCRIPTIONCONTAINER_H