2
* This file is part of the Ubuntu TV Media Scanner
3
* Copyright (C) 2012-2013 Canonical Ltd.
5
* This program is free software: you can redistribute it and/or modify
6
* it under the terms of the GNU Lesser General Public License version 3 as
7
* published by the Free Software Foundation.
9
* This program is distributed in the hope that it will be useful,
10
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
* GNU Lesser General Public License for more details.
14
* You should have received a copy of the GNU Lesser General Public License
15
* along with this program. If not, see <http://www.gnu.org/licenses/>.
17
* Contact: Jim Hodapp <jim.hodapp@canonical.com>
18
* Authored by: Mathias Hasselmann <mathias@openismus.com>
20
#ifndef MEDIASCANNER_GLIBUTILS_H
21
#define MEDIASCANNER_GLIBUTILS_H
23
// GLib Based Libraries
25
#include <gio/gunixmounts.h>
27
#include <gst/pbutils/gstdiscoverer.h>
28
#include <gudev/gudev.h>
31
#include <boost/function.hpp>
32
#include <boost/date_time/posix_time/posix_time_duration.hpp>
34
// C++ Standard Library
37
// Media Scanner Library
38
#include "mediascanner/declarations.h"
40
namespace mediascanner {
43
// GObject structure to GType mappings /////////////////////////////////////////
45
template<typename> GType GetGType();
47
template<> inline GType GetGType<GArray>() {
51
template<> inline GType GetGType<GByteArray>() {
52
return G_TYPE_BYTE_ARRAY;
55
template<> inline GType GetGType<GClosure>() {
56
return G_TYPE_CLOSURE;
59
template<> inline GType GetGType<GDate>() {
63
template<> inline GType GetGType<GDateTime>() {
64
return G_TYPE_DATE_TIME;
67
template<> inline GType GetGType<GDrive>() {
71
template<> inline GType GetGType<GError>() {
75
template<> inline GType GetGType<GFile>() {
79
template<> inline GType GetGType<GFileMonitor>() {
80
return G_TYPE_FILE_MONITOR;
83
template<> inline GType GetGType<GFileType>() {
84
return G_TYPE_FILE_TYPE;
87
template<> inline GType GetGType<GHashTable>() {
88
return G_TYPE_HASH_TABLE;
91
template<> inline GType GetGType<GKeyFile>() {
92
return G_TYPE_KEY_FILE;
95
template<> inline GType GetGType<GIcon>() {
99
template<> inline GType GetGType<GMainContext>() {
100
return G_TYPE_MAIN_CONTEXT;
103
template<> inline GType GetGType<GMainLoop>() {
104
return G_TYPE_MAIN_LOOP;
107
template<> inline GType GetGType<GMatchInfo>() {
108
return G_TYPE_MATCH_INFO;
111
template<> inline GType GetGType<GMount>() {
115
template<> inline GType GetGType<GObject>() {
116
return G_TYPE_OBJECT;
119
template<> inline GType GetGType<GPtrArray>() {
120
return G_TYPE_PTR_ARRAY;
123
template<> inline GType GetGType<GRegex>() {
127
template<> inline GType GetGType<GSettings>() {
128
return G_TYPE_SETTINGS;
131
template<> inline GType GetGType<GSource>() {
132
return G_TYPE_SOURCE;
135
template<> inline GType GetGType<GString>() {
136
return G_TYPE_GSTRING;
139
template<> inline GType GetGType<GValue>() {
143
template<> inline GType GetGType<GVolume>() {
144
return G_TYPE_VOLUME;
147
template<> inline GType GetGType<GVolumeMonitor>() {
148
return G_TYPE_VOLUME_MONITOR;
151
template<> inline GType GetGType<GVariantBuilder>() {
152
return G_TYPE_VARIANT_BUILDER;
155
template<> inline GType GetGType<GVariantType>() {
156
return G_TYPE_VARIANT;
159
template<> inline GType GetGType<GrlCaps>() {
160
return GRL_CAPS_TYPE;
163
template<> inline GType GetGType<GrlConfig>() {
164
return GRL_TYPE_CONFIG;
167
template<> inline GType GetGType<GrlData>() {
168
return GRL_TYPE_DATA;
171
template<> inline GType GetGType<GrlMedia>() {
172
return GRL_TYPE_MEDIA;
175
template<> inline GType GetGType<GrlPlugin>() {
176
return GRL_TYPE_PLUGIN;
179
template<> inline GType GetGType<GrlRegistry>() {
180
return GRL_TYPE_REGISTRY;
183
template<> inline GType GetGType<GrlRelatedKeys>() {
184
return GRL_TYPE_RELATED_KEYS;
187
template<> inline GType GetGType<GrlSource>() {
188
return GRL_TYPE_SOURCE;
191
template<> inline GType GetGType<GstDiscovererInfo>() {
192
return GST_TYPE_DISCOVERER_INFO;
195
template<> inline GType GetGType<GstDiscovererStreamInfo>() {
196
return GST_TYPE_DISCOVERER_STREAM_INFO;
199
template<> inline GType GetGType<GstDiscovererAudioInfo>() {
200
return GST_TYPE_DISCOVERER_AUDIO_INFO;
203
template<> inline GType GetGType<GstDiscovererContainerInfo>() {
204
return GST_TYPE_DISCOVERER_CONTAINER_INFO;
207
template<> inline GType GetGType<GstDiscovererVideoInfo>() {
208
return GST_TYPE_DISCOVERER_VIDEO_INFO;
211
template<> inline GType GetGType<GUdevClient>() {
212
return G_UDEV_TYPE_CLIENT;
215
template<> inline GType GetGType<GUdevDevice>() {
216
return G_UDEV_TYPE_DEVICE;
219
// GLib boxing and GObject reference counting //////////////////////////////////
221
template<typename Type>
223
static Type *Copy(Type *p);
224
static void Free(Type *p);
227
template<typename Type>
228
struct BoxedCopyHelper {
229
static Type *Copy(Type *p) {
230
return static_cast<Type *>(g_boxed_copy(GetGType<Type>(), p));
233
static void Free(Type *p) {
234
g_boxed_free(GetGType<Type>(), p);
238
template<typename Type>
239
struct MiniObjectCopyHelper {
240
static Type *Copy(Type *p) {
241
return reinterpret_cast<Type *>
242
(gst_mini_object_ref(GST_MINI_OBJECT_CAST(p)));
245
static void Free(Type *p) {
246
gst_mini_object_unref(GST_MINI_OBJECT_CAST(p));
250
template<typename Type>
251
struct ObjectCopyHelper {
252
static Type *Copy(Type *p) {
253
return static_cast<Type *>(g_object_ref(p));
256
static void Free(Type *p) {
261
template<typename Type, typename List = GList>
262
struct ListCopyHelper {
263
static List *Copy(List *const other) {
264
List *const copy = CopyHelper<List>::Copy(other);
266
for (List *l = copy; l; l = l->next) {
267
Type *const data = static_cast<Type *>(l->data);
268
l->data = CopyHelper<Type>::Copy(data);
274
static void Free(GList *list) {
275
for (List *l = list; l; l = l->next) {
276
Type *const data = static_cast<Type *>(l->data);
277
CopyHelper<Type>::Free(data);
280
CopyHelper<List>::Free(list);
284
template<> struct CopyHelper<GMainLoop> :
285
public BoxedCopyHelper<GMainLoop> { };
286
template<> struct CopyHelper<GMainContext> :
287
public BoxedCopyHelper<GMainContext> { };
288
template<> struct CopyHelper<GValue> :
289
public BoxedCopyHelper<GValue> { };
291
template<> struct CopyHelper<GCancellable> :
292
public ObjectCopyHelper<GCancellable> { };
293
template<> struct CopyHelper<GDBusConnection> :
294
public ObjectCopyHelper<GDBusConnection> { };
295
template<> struct CopyHelper<GDrive> :
296
public ObjectCopyHelper<GDrive> { };
297
template<> struct CopyHelper<GFile> :
298
public ObjectCopyHelper<GFile> { };
299
template<> struct CopyHelper<GFileEnumerator> :
300
public ObjectCopyHelper<GFileEnumerator> { };
301
template<> struct CopyHelper<GFileInfo> :
302
public ObjectCopyHelper<GFileInfo> { };
303
template<> struct CopyHelper<GFileMonitor> :
304
public ObjectCopyHelper<GFileMonitor> { };
305
template<> struct CopyHelper<GIcon> :
306
public ObjectCopyHelper<GIcon> { };
307
template<> struct CopyHelper<GMount> :
308
public ObjectCopyHelper<GMount> { };
309
template<> struct CopyHelper<GSettings> :
310
public ObjectCopyHelper<GSettings> { };
311
template<> struct CopyHelper<GVolume> :
312
public ObjectCopyHelper<GVolume> { };
313
template<> struct CopyHelper<GVolumeMonitor> :
314
public ObjectCopyHelper<GVolumeMonitor> { };
316
template<> struct CopyHelper<GDBusMethodInvocation> :
317
public ObjectCopyHelper<GDBusMethodInvocation> { };
318
template<> struct CopyHelper<GDBusProxy> :
319
public ObjectCopyHelper<GDBusProxy> { };
321
template<> struct CopyHelper<GrlCaps> :
322
public ObjectCopyHelper<GrlCaps> { };
323
template<> struct CopyHelper<GrlConfig> :
324
public ObjectCopyHelper<GrlConfig> { };
325
template<> struct CopyHelper<GrlData> :
326
public ObjectCopyHelper<GrlData> { };
327
template<> struct CopyHelper<GrlMedia> :
328
public ObjectCopyHelper<GrlMedia> { };
329
template<> struct CopyHelper<GrlOperationOptions> :
330
public ObjectCopyHelper<GrlOperationOptions> { };
331
template<> struct CopyHelper<GrlPlugin> :
332
public ObjectCopyHelper<GrlPlugin> { };
333
template<> struct CopyHelper<GrlRegistry> :
334
public ObjectCopyHelper<GrlRegistry> { };
335
template<> struct CopyHelper<GrlRelatedKeys> :
336
public ObjectCopyHelper<GrlRelatedKeys> { };
337
template<> struct CopyHelper<GrlSource> :
338
public ObjectCopyHelper<GrlSource> { };
340
template<> struct CopyHelper<GstCaps> :
341
public MiniObjectCopyHelper<GstCaps> { };
342
template<> struct CopyHelper<GstDiscoverer> :
343
public ObjectCopyHelper<GstDiscoverer> { };
344
template<> struct CopyHelper<GstDiscovererInfo> :
345
public ObjectCopyHelper<GstDiscovererInfo> { };
346
template<> struct CopyHelper<GstDiscovererStreamInfo> :
347
public ObjectCopyHelper<GstDiscovererStreamInfo> { };
349
template<> struct CopyHelper<GUdevClient> :
350
public ObjectCopyHelper<GUdevClient> { };
351
template<> struct CopyHelper<GUdevDevice> :
352
public ObjectCopyHelper<GUdevDevice> { };
354
template<> struct CopyHelper<char> {
355
static char *Copy(char *p) { return g_strdup(p); }
356
static void Free(char *p) { g_free(p); }
359
template<> struct CopyHelper<char *> {
360
static char **Copy(char **p) { return g_strdupv(p); }
361
static void Free(char **p) { g_strfreev(p); }
364
template<> struct CopyHelper<GDBusArgInfo> {
365
static GDBusArgInfo *Copy(GDBusArgInfo *p) {
366
return g_dbus_arg_info_ref(p);
369
static void Free(GDBusArgInfo *p) {
370
g_dbus_arg_info_unref(p);
374
template<> struct CopyHelper<GDBusInterfaceInfo> {
375
static GDBusInterfaceInfo *Copy(GDBusInterfaceInfo *p) {
376
return g_dbus_interface_info_ref(p);
379
static void Free(GDBusInterfaceInfo *p) {
380
g_dbus_interface_info_unref(p);
384
template<> struct CopyHelper<GDBusMethodInfo> {
385
static GDBusMethodInfo *Copy(GDBusMethodInfo *p) {
386
return g_dbus_method_info_ref(p);
389
static void Free(GDBusMethodInfo *p) {
390
g_dbus_method_info_unref(p);
394
template<> struct CopyHelper<GDBusPropertyInfo> {
395
static GDBusPropertyInfo *Copy(GDBusPropertyInfo *p) {
396
return g_dbus_property_info_ref(p);
399
static void Free(GDBusPropertyInfo *p) {
400
g_dbus_property_info_unref(p);
404
template<> struct CopyHelper<GDBusSignalInfo> {
405
static GDBusSignalInfo *Copy(GDBusSignalInfo *p) {
406
return g_dbus_signal_info_ref(p);
409
static void Free(GDBusSignalInfo *p) {
410
g_dbus_signal_info_unref(p);
414
template<> struct CopyHelper<GError> {
415
static GError *Copy(GError *p) { return g_error_copy(p); }
416
static void Free(GError *p) { g_error_free(p); }
419
template<> struct CopyHelper<GKeyFile> {
420
static GKeyFile *Copy(GKeyFile *p) {
421
return g_key_file_ref(p);
424
static void Free(GKeyFile *p) {
429
template<> struct CopyHelper<GList> {
430
static GList *Copy(GList *p) { return g_list_copy(p); }
431
static void Free(GList *p) { g_list_free(p); }
434
template<> struct CopyHelper<GParamSpec> {
435
static GParamSpec *Copy(GParamSpec *p) { return g_param_spec_ref(p); }
436
static void Free(GParamSpec *p) { g_param_spec_unref(p); }
439
template<> struct CopyHelper<GPtrArray> {
440
static GPtrArray *Copy(GPtrArray *p) { return g_ptr_array_ref(p); }
441
static void Free(GPtrArray *p) { g_ptr_array_unref(p); }
444
template<> struct CopyHelper<GThread> {
445
static GThread *Copy(GThread *p) { return g_thread_ref(p); }
446
static void Free(GThread *p) { g_thread_unref(p); }
449
template<> struct CopyHelper<GUnixMountEntry> {
450
static void Free(GUnixMountEntry *p) { g_unix_mount_free(p); }
453
template<> struct CopyHelper<GVariant> {
454
static GVariant *Copy(GVariant *p) { return g_variant_ref(p); }
455
static void Free(GVariant *p) { g_variant_unref(p); }
458
template<> struct CopyHelper<GstStructure> {
459
static GstStructure *Copy(GstStructure *p) { return gst_structure_copy(p); }
460
static void Free(GstStructure *p) { gst_structure_free(p); }
463
// Cast helpers ////////////////////////////////////////////////////////////////
465
template<typename SourceType, typename TargetType>
467
static TargetType *cast(SourceType *p);
470
template<typename SourceType, typename TargetType>
471
struct TypeInstanceCastHelper {
472
static TargetType *Apply(SourceType *p) {
473
if (G_TYPE_CHECK_INSTANCE_TYPE(p, GetGType<TargetType>()))
474
return reinterpret_cast<TargetType *>(p);
480
template<typename SourceType>
481
struct TypeInstanceCastHelper<SourceType, GTypeInstance> {
482
static GTypeInstance *Apply(SourceType *p) {
483
return reinterpret_cast<GTypeInstance *>(p);
487
template<typename TargetType>
488
struct CastHelper<GrlMedia, TargetType> :
489
public TypeInstanceCastHelper<GrlMedia, TargetType> { };
491
template<typename TargetType>
492
struct CastHelper<GrlSource, TargetType> :
493
public TypeInstanceCastHelper<GrlSource, TargetType> { };
495
template<typename TargetType>
496
struct CastHelper<GstDiscovererStreamInfo, TargetType> :
497
public TypeInstanceCastHelper<GstDiscovererStreamInfo, TargetType> { };
499
} // namespace internal
501
// Smart pointers for GLib boxed types and GObjects ////////////////////////////
504
* @brief A shared smart-pointer for GLib related types. Via its helper classes
505
* this smart-pointer supports a wide variety of GLib related types, such as
506
* GObjects, GstMiniObjects, boxed types, and even simple GLists.
507
* @see internal::CopyHelper, internal::CastHelper
509
template<typename T, typename CopyHelper>
513
* @brief Creates an emtpy pointer not holding any object.
520
* @brief Copies another pointer instance. For reference counted objects
521
* this new pointer will hold a new reference to the object. For boxed
522
* types and similiar a new copy of the original object is created.
523
* @param other The instance to initialize from.
524
* @see take(), wrap(), wrap_static()
526
Wrapper(const Wrapper<T> &other)
532
* @brief Destroys the smart-pointer. For reference counted objects
533
* this drops the reference hold, for other types this frees the object
538
CopyHelper::Free(m_ptr);
542
* @brief Releases the wrapped object. This detaches the wrapped object
543
* from this smart-pointer without dropping the reference or freeing it.
544
* Use this function to transfer ownership of the wrapped object.
545
* @return A pointer to the wrapped object, or @c null if no object
555
* @brief This function gives access to the wrapped object.
556
* @return A pointer to the wrapped object.
563
* @brief Creates a new reference to, or a new copy of the wrapped object.
564
* This function is useful to initialize C structures or arrays.
565
* @return A pointer to the new reference, or the new object.
568
return CopyHelper::Copy(get());
572
* @brief This function casts the wrapped object to a different type.
573
* @return A pointer to the wrapped object.
575
template<typename B> B *get() const {
576
return internal::CastHelper<T, B>::Apply(get());
580
* @brief This operator gives access to the wrapped object's members.
581
* @return A pointer to the wrapped object.
583
T *operator->() const {
588
* @brief This function requests to wrap a different object.
589
* If the wrapped objects are reference-counted, the reference to the
590
* old object is dropped, and a reference to the new object is stored.
591
* For other types the old object is freed and a copy of the new object
593
* @param p The new object to store, or @c null.
594
* @see take(), out_param()
596
void reset(T *p = 0) {
599
CopyHelper::Free(m_ptr);
604
m_ptr = CopyHelper::Copy(p);
609
* @brief This function requests to take ownership of a different object.
610
* If the wrapped objects are reference-counted, the reference to the
611
* old object is dropped, for other types the old object is freed.
612
* As this function takes ownership of the passed object, no new reference
613
* is created, and no copy is created.
614
* @param p The new object to store, or @c null.
615
* @see reset(), out_param()
620
CopyHelper::Free(m_ptr);
627
* @brief Resets the smart-pointer and returns a pointer to the internal
628
* object pointer. This is useful to wrap objects retreived by output
630
* @return A pointer to the internal object pointer.
631
* @see reset(), take()
639
* @brief The assignment operator is an alias of the reset() method.
640
* @param p The new object to store, or @c null
641
* @return A reference to this smart-pointer.
643
Wrapper<T> &operator=(T *p) {
649
* @brief The assignment operator is an alias of the reset() method.
650
* @param p The new object to store, or @c null
651
* @return A reference to this smart-pointer.
653
Wrapper<T> &operator=(const Wrapper<T> &other) {
654
return operator=(other.get());
658
* @brief This operator casts the wrapped object to another type.
659
* This cast operator also serves as safe bool cast. The more natural
660
* operator bool() is problematic because it leads to unwanted implicit
661
* casts. Also note that there is no non-const "operatpr T *()" to avoid
662
* ambiguity problems for the compiler.
664
operator const T *() const {
669
* @brief This operator checks if this pointer actually wraps an object.
670
* @return @c true if this pointer wraps an object.
672
bool operator!() const {
677
* @brief This operator compares two pointers for equality.
678
* @param p The other pointer to compare with.
679
* @return @c true if both pointers are equal.
681
bool operator==(const T *p) const {
686
* @brief This operator compares two pointers for inequality.
687
* @param p The other pointer to compare with.
688
* @return @c true if both pointers are not equal.
690
bool operator!=(const T *p) const {
691
return !operator==(p);
698
template<typename T, typename List = GList>
699
struct ListWrapper : public Wrapper<List, internal::ListCopyHelper<T> > {
700
typedef Wrapper<List, internal::ListCopyHelper<T> > inherited;
702
ListWrapper(const Wrapper<List> &other) // NOLINT: runtime/explicit
707
* @brief Constructs a ListWrapper that directly takes ownership of @list.
708
* This constructor is useful since creating a deep copy of a list can be
711
explicit ListWrapper(List *list) {
712
inherited::take(list);
717
* @brief A type-safe function for creating shallow copies of structures.
718
* @param T The structure's type.
719
* @param p A pointer to the structure to copy.
720
* @return A new copy of the structure, as returned by @c g_memdup().
723
inline T* shallow_copy(const T *p) {
724
return static_cast<T *>(g_memdup(p, sizeof(T)));
728
* @brief A type-safe function for creating shallow copies of pointer arrays.
729
* @param T The array's element type.
730
* @param N The number of elements in the array.
731
* @param p A pointer to the array to copy.
732
* @return A new copy of the array, as returned by @c g_memdup().
734
template<typename T, size_t N>
735
static T* array_copy(const T (&p)[N]) {
736
return static_cast<T*>(g_memdup(p, sizeof p));
740
* @brief Wraps a pointer to an object by a shared smart-pointer.
741
* This function doesn't take ownership of the object. It therefore @b does
742
* increase the object's reference count.
743
* @param T The type of the object to wrap.
744
* @param p The pointer to the object to wrap.
745
* @return A new Wrapper instance that holds a new reference to the object.
748
inline Wrapper<T> wrap(T *p) {
755
* @brief Wraps a pointer to an object by a shared smart-pointer.
756
* This function takes ownership of the object. It therefore @b doesn't
757
* increase the object's reference count.
758
* @param T The type of the object to wrap.
759
* @param p The pointer to the object to wrap.
760
* @return A new Wrapper instance that holds now owns the object.
763
inline Wrapper<T> take(T *p) {
770
* @brief Wraps a statically allocated structure by a shared smart-pointer.
771
* This function creates a shallow copy of the structure and then takes
772
* ownership of that copy.
773
* @param T The type of the structure to wrap.
774
* @param p The pointer to the structure to wrap.
775
* @return A new Wrapper instance that holds owns a copy of the structure.
778
inline Wrapper<T> wrap_static(const T *p) {
779
return take(shallow_copy(p));
782
// GLib event loop integration /////////////////////////////////////////////////
785
* @brief Type-safe destroy notifier.
786
* This function can be used as destroy notifier for GLib functions.
787
* It automatically invokes the proper @c delete operator of @p T.
788
* @param T The type of the object to destroy.
789
* @param user_data A pointer to the object to destroy.
792
inline void DestroyNotify(gpointer user_data) {
793
delete static_cast<T *>(user_data);
797
inline void ClosureNotify(gpointer user_data, GClosure *) {
798
delete static_cast<T *>(user_data);
802
* @brief The Source class provides access to the GLib event source mechanism.
807
* @brief The signature of a regular idle source.
808
* @return If this function returns @c false it is automatically removed
809
* from the list of event sources and will not be called again.
811
typedef boost::function<bool()> SourceFunction;
814
* @brief The signature of a single-call idle source.
815
* This function is called excactly once. After returning it is
816
* automatically removed from the list of event sources and will not be
819
typedef boost::function<void()> OneCallFunction;
822
* @brief Removes an event source handler.
823
* @param id The source handler's identifier.
824
* @return @c True if the identifier was valid and the handler got removed.
826
static bool Remove(unsigned id) {
827
return g_source_remove(id);
831
static gboolean on_source_function(gpointer data) {
832
SourceFunction *const function = static_cast<SourceFunction *>(data);
835
return (*function)();
840
static gboolean on_one_call_function(gpointer data) {
841
OneCallFunction *const function = static_cast<OneCallFunction *>(data);
851
* @brief The Idle class provides access to GLib's idle source mechanism.
852
* It manages functions which get called whenever there are no higher priority
853
* events pending to the default main loop.
857
class Idle : public Source {
860
* @brief Installs a regular idle source. This source will be invoked
861
* until the @p function returns @c false. After that it be removed
862
* automatically from the list of event sources.
863
* @param function The function to be called on idle.
864
* @param priority The priority of the idle source.
865
* @return The identifier (greater than 0) of the event source.
866
* @see AddOnce(), Source::Remove()
868
static unsigned Add(const SourceFunction &function,
869
int priority = G_PRIORITY_DEFAULT) {
870
return g_idle_add_full(priority,
871
&Source::on_source_function,
872
new SourceFunction(function),
873
&DestroyNotify<SourceFunction>);
877
* @brief Installs a single-call idle source. This source will be called
878
* exactly once. After that it be removed automatically from the list of
880
* @param function The function to be called on idle.
881
* @param priority The priority of the idle source.
882
* @return The identifier (greater than 0) of the event source.
883
* @see Add(), Source::Remove()
885
static unsigned AddOnce(const OneCallFunction &function,
886
int priority = G_PRIORITY_DEFAULT) {
887
return g_idle_add_full(priority,
888
&Source::on_one_call_function,
889
new OneCallFunction(function),
890
&DestroyNotify<OneCallFunction>);
895
* @brief The Timeout class provides access to GLib's timeout mechanism.
896
* It manages functions which get called whenever a given time interval
899
* Note that timeout functions might get delayed if the event loop gets
900
* blocked by other sources.
904
class Timeout : public Source {
907
* @brief This type describes time durations. Note that the duration's
908
* resolution impacts which resolution the timeout source will have.
910
typedef boost::posix_time::time_duration Duration;
913
* @brief Adds a new timeout function to the event loop. The timeout
914
* gets automatically removed from the list of event sources if @p function
917
* Note that the exact timeout mechanism is selected upon the @p interval
918
* parameter's resolution. If the resolution is in seconds (or even less
919
* granular) timeout sources of seconds precision are created. Otherwise
920
* the sources have milliseconds resolution.
922
* @param interval The time between calls to the function.
923
* @param function The function to be called on idle.
924
* @param priority The priority of the idle source.
925
* @return The identifier (greater than 0) of the event source.
926
* @see AddOnce(), Source::Remove()
928
static unsigned Add(Duration interval,
929
const SourceFunction &function,
930
int priority = G_PRIORITY_DEFAULT_IDLE) {
931
if (interval.resolution() == boost::date_time::sec) {
932
return g_timeout_add_seconds_full(priority,
933
interval.total_seconds(),
934
&Source::on_source_function,
935
new SourceFunction(function),
936
&DestroyNotify<SourceFunction>);
939
return g_timeout_add_full(priority,
940
interval.total_milliseconds(),
941
&Source::on_source_function,
942
new SourceFunction(function),
943
&DestroyNotify<SourceFunction>);
947
* @brief Adds a new timeout function to the event loop that is called
948
* exactly once. After its invocation the timeout gets automatically
949
* removed from the list of event sources if @p function returns @c false.
951
* Note that the exact timeout mechanism is selected upon the @p interval
952
* parameter's resolution. If the resolution is in seconds (or even less
953
* granular) timeout sources of seconds precision are created. Otherwise
954
* the sources have milliseconds resolution.
956
* @param interval The time between calls to the function.
957
* @param function The function to be called on idle.
958
* @param priority The priority of the idle source.
959
* @return The identifier (greater than 0) of the event source.
960
* @see AddOnce(), Source::Remove()
962
static unsigned AddOnce(Duration interval,
963
const OneCallFunction &function,
964
int priority = G_PRIORITY_DEFAULT_IDLE) {
965
if (interval.fractional_seconds() == 0) {
966
return g_timeout_add_seconds_full(priority,
967
interval.total_seconds(),
968
&Source::on_one_call_function,
969
new OneCallFunction(function),
970
&DestroyNotify<OneCallFunction>);
973
return g_timeout_add_full(priority,
974
interval.total_milliseconds(),
975
&Source::on_one_call_function,
976
new OneCallFunction(function),
977
&DestroyNotify<OneCallFunction>);
981
// String conversions //////////////////////////////////////////////////////////
984
* @brief Describes a @c GError. The returned string contains
985
* the error domain, the error code, and of course the error message.
986
* @param error The error to describe, or @c null
987
* @return A description of the error if appliable.
989
std::string to_string(const GError *error);
992
* @brief Describes GStreamer capabilities
993
* @param caps The capabilities to describe, or @c null
994
* @return A describption of the capabilities if appliable
996
std::string to_string(const GstCaps *caps);
998
// GParamSpec helpers //////////////////////////////////////////////////////////
1001
* @brief Creates a @c GParamSpec for boxed types. This function is useful in
1002
* static variable initialization to defer @c G_TYPE_* calls that could lead
1003
* to warnings about the missing @c g_type_init() invocation.
1004
* @param BoxedType G_TYPE_BOXED derived type of this property.
1005
* @param name Canonical name of the property specified.
1006
* @param nick Nick name for the property specified.
1007
* @param blurb Description of the property specified.
1008
* @param flags Flags for the property specified.
1009
* @return A newly created parameter specification.
1011
template<typename BoxedType>
1012
inline GParamSpec *MakeParamSpecBoxed(const char *name,
1015
GParamFlags flags) {
1016
return ::g_param_spec_boxed(name, nick, blurb,
1017
internal::GetGType<BoxedType>(), flags);
1020
} // namespace mediascanner
1022
#endif // MEDIASCANNER_GLIBUTILS_H