Phonon

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 <QMap>
26#include <QDebug>
27#include <QtGlobal>
28
29#include <phonon/objectdescription.h>
30
31namespace Phonon
32{
33
34class MediaController;
35
36/**
37 * \internal
38 *
39 * A container for object descriptions.
40 * The primary use of this container is to turn ObjectDescriptions with unique
41 * id scope smaller than backend into globally unique ones.
42 *
43 * For example a MediaController enhances a MediaObject, you may have multiple
44 * MediaObjects and thus MediaControllers in one application. The interface
45 * to query all subtitles is only available on the backend class itself though,
46 * so the index/id of the descriptions handed to a Phonon API user must be
47 * unique with global scope.
48 * This is where the GlobalDescriptionContainer comes in. It allows arbitrary
49 * objects to register (using object address) with the container (which is a
50 * singleton).
51 * The object hands its locally unique ObjectDescriptions to the container, which
52 * turns it into a globally unique description and maps the global id to the
53 * local id.
54 *
55 * That way it is possible to easily map local to global description objects.
56 *
57 * \author Harald Sitter <sitter@kde.org>
58 */
59template <typename D>
61{
62public:
63 typedef int global_id_t;
64 typedef int local_id_t;
65
68
71
72public:
73 static GlobalDescriptionContainer *self;
74
75 static GlobalDescriptionContainer *instance()
76 {
77 if (!self)
79 return self;
80 }
81
83
84 /**
85 * \returns a list of all global unique IDs of all stored ObjectDescriptions
86 */
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
98 /**
99 * \param key the global ID of the ObjectDescription
100 *
101 * \returns ObjectDescriptions associated with a given ID
102 */
103 D fromIndex(global_id_t key)
104 {
105 return m_globalDescriptors.value(key, D());
106 }
107
108 // ----------- MediaController Specific ----------- //
109
110 /**
111 * Registers a new object within the container.
112 * This essentially creates a new empty ID map.
113 *
114 * \param obj The reference object
115 */
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
123 /**
124 * Unregisters a object from the container.
125 * This essentially clears the ID map and removes all traces of the
126 * object.
127 *
128 * \param obj The object
129 */
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
139 /**
140 * Clear the internal mapping of global to local id for a given object.
141 *
142 * \param obj The object
143 */
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
153 /**
154 * Adds a new description object for a specific object.
155 * A description object *must* have a global unique id, which is ensured
156 * by using this function, which will either reuse an existing equal
157 * ObjectDescription or use the next free unique ID.
158 * Using the provided index the unique ID is then mapped to the one of the
159 * specific object.
160 *
161 * \param obj The object
162 * \param index local ID (i.e. within the object @obj)
163 * \param name Name of the description
164 * \param type Type of the description (e.g. file)
165 */
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
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
199 /**
200 * Overload function.
201 * The index of the provided descriptor *must* be unique within the
202 * context of the container.
203 *
204 * \param obj The object
205 * \param descriptor the DescriptionObject with unique index
206 */
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
218 /**
219 * List of ObjectDescriptions for a given object, the
220 * descriptions are limied by the scope of the type (obviously), so you only
221 * get ObjectDescription from the container.
222 *
223 * \param obj The object
224 *
225 * \returns the list of ObjectDescriptions for a given object, the
226 * descriptions are limied by the scope of the type (obviously), so you only
227 * get subtitle descriptions from a subtitle container.
228 */
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
244 /**
245 * \param obj The object
246 * \param key the global ID (i.e. index of an ObjectDescription)
247 *
248 * \returns the local ID associated with the description object
249 */
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
261protected:
263 m_peak(0)
264 {
265 }
266
267 /**
268 * \returns next free unique index to be used as global ID for an ObjectDescription
269 */
270 global_id_t nextFreeIndex()
271 {
272 return ++m_peak;
273 }
274
275 GlobalDescriptorMap m_globalDescriptors;
277
278 global_id_t m_peak;
279};
280
281template <typename D>
282GlobalDescriptionContainer<D> *GlobalDescriptionContainer<D>::self = 0;
283
284typedef GlobalDescriptionContainer<AudioChannelDescription> GlobalAudioChannels;
285typedef GlobalDescriptionContainer<SubtitleDescription> GlobalSubtitles;
286
287} // Namespace Phonon
288
289#endif // PHONON_GLOBALDESCRIPTIONCONTAINER_H
void unregister_(void *obj)
Unregisters a object from the container.
int localIdFor(const void *obj, global_id_t key) const
void add(void *obj, D descriptor)
Overload function.
QList< D > listFor(const void *obj) const
List of ObjectDescriptions for a given object, the descriptions are limied by the scope of the type (...
void add(void *obj, local_id_t index, const QString &name, const QString &type=QString())
Adds a new description object for a specific object.
void clearListFor(void *obj)
Clear the internal mapping of global to local id for a given object.
void register_(void *obj)
Registers a new object within the container.
iterator end()
iterator find(const Key &key)
iterator insert(const Key &key, const T &value)
T value(const Key &key, const T &defaultValue) const const
bool hasNext() const const
const Key & key() const const
const T & value() const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Tue Mar 26 2024 11:20:24 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.