diff options
author | Zeeshan Ali <zeeshanak@gnome.org> | 2018-04-12 18:51:39 +0200 |
---|---|---|
committer | Zeeshan Ali <zeeshanak@gnome.org> | 2018-04-17 12:30:20 +0200 |
commit | da29f99d2cd292174d6d785cdb531455d141eda0 (patch) | |
tree | a2705c944a8fdee2adb0381f12938c538b78bd13 | |
parent | 10d346e95892cc12e0155a8087f14a979a182392 (diff) | |
download | geoclue-da29f99d2cd292174d6d785cdb531455d141eda0.tar.gz |
Add GClueMinUINT class
This is a helper class that keeps a list of guint values and the minimum
value from this list. In the following patches, it will be used by
location sources to use the minimum time-threshold (location update rate)
from all the time-thresholds requested by different applications.
https://bugs.freedesktop.org/show_bug.cgi?id=105993
-rw-r--r-- | src/Makefile.am | 2 | ||||
-rw-r--r-- | src/gclue-min-uint.c | 251 | ||||
-rw-r--r-- | src/gclue-min-uint.h | 68 |
3 files changed, 321 insertions, 0 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index 20c36c1..86d786c 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -136,6 +136,8 @@ libgeoclue_internal_la_SOURCES = \ gclue-location-source.c \ gclue-locator.h \ gclue-locator.c \ + gclue-min-uint.h \ + gclue-min-uint.c \ gclue-service-manager.h \ gclue-service-manager.c \ gclue-service-client.h \ diff --git a/src/gclue-min-uint.c b/src/gclue-min-uint.c new file mode 100644 index 0000000..1f421aa --- /dev/null +++ b/src/gclue-min-uint.c @@ -0,0 +1,251 @@ +/* vim: set et ts=8 sw=8: */ +/* gclue-min-uint.c + * + * Copyright (C) 2018 Collabora Ltd. + * + * Geoclue is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * Geoclue is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License along + * with Geoclue; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Author: Zeeshan Ali (Khattak) <zeeshanak@gnome.org> + */ + +#include "gclue-min-uint.h" + +/** + * SECTION:gclue-min-uint + * @short_description: Easy way to keep track of minimum of a bunch of values + * @include: gclue-glib/gclue-location-source.h + * + * This is a helper class that keeps a list of guint values and the minimum + * value from this list. It is used by location sources to use the minimum + * time-threshold (location update rate) from all the time-thresholds requested + * by different applications. + **/ + +G_DEFINE_TYPE (GClueMinUINT, gclue_min_uint, G_TYPE_OBJECT) + +struct _GClueMinUINTPrivate +{ + GHashTable *all_values; + + gboolean notify_value; +}; + +enum +{ + PROP_0, + PROP_VALUE, + LAST_PROP +}; + +static GParamSpec *gParamSpecs[LAST_PROP]; + +static void +gclue_min_uint_finalize (GObject *object) +{ + g_clear_pointer (&GCLUE_MIN_UINT (object)->priv->all_values, + g_hash_table_unref); + + /* Chain up to the parent class */ + G_OBJECT_CLASS (gclue_min_uint_parent_class)->finalize (object); +} + +static void +gclue_min_uint_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GClueMinUINT *muint = GCLUE_MIN_UINT (object); + + switch (prop_id) { + case PROP_VALUE: + g_value_set_uint (value, gclue_min_uint_get_value (muint)); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static void +gclue_min_uint_class_init (GClueMinUINTClass *klass) +{ + GObjectClass *object_class; + + object_class = G_OBJECT_CLASS (klass); + object_class->finalize = gclue_min_uint_finalize; + object_class->get_property = gclue_min_uint_get_property; + + g_type_class_add_private (object_class, sizeof (GClueMinUINTPrivate)); + + gParamSpecs[PROP_VALUE] = g_param_spec_uint ("value", + "Value", + "The mininum value", + 0, + G_MAXINT, + 0, + G_PARAM_READABLE); + g_object_class_install_property (object_class, + PROP_VALUE, + gParamSpecs[PROP_VALUE]); +} + +static void +gclue_min_uint_init (GClueMinUINT *muint) +{ + muint->priv = G_TYPE_INSTANCE_GET_PRIVATE (muint, + GCLUE_TYPE_MIN_UINT, + GClueMinUINTPrivate); + muint->priv->all_values = g_hash_table_new (g_direct_hash, + g_direct_equal); + muint->priv->notify_value = TRUE; +} + +/** + * gclue_min_uint_new + * + * Returns: A new #GClueMinUINT instance. + **/ +GClueMinUINT * +gclue_min_uint_new (void) +{ + return g_object_new (GCLUE_TYPE_MIN_UINT, NULL); +} + +/** + * gclue_min_uint_get_value + * @muint: a #GClueMinUINT + * + * Returns: The current mininum value from the list. + **/ +guint +gclue_min_uint_get_value (GClueMinUINT *muint) +{ + guint value; + GList *keys, *l; + + g_return_val_if_fail (GCLUE_IS_MIN_UINT(muint), 0); + + if (g_hash_table_size (muint->priv->all_values) == 0) + return 0; + + keys = g_hash_table_get_keys (muint->priv->all_values); + value = GPOINTER_TO_UINT (keys->data); + + for (l = keys->next; l; l = l->next) { + guint i = GPOINTER_TO_UINT (l->data); + + if (value > i) { + value = i; + } + } + + return value; +} + +/** + * gclue_min_uint_add_value + * @muint: a #GClueMinUINT + * @value: A value to add to the list + **/ +void +gclue_min_uint_add_value (GClueMinUINT *muint, + guint value) +{ + gpointer key, hash_value; + guint cur_value, new_value; + guint num_users = 1; + + g_return_if_fail (GCLUE_IS_MIN_UINT(muint)); + + key = GUINT_TO_POINTER (value); + hash_value = g_hash_table_lookup (muint->priv->all_values, key); + if (hash_value != NULL) { + num_users = GPOINTER_TO_UINT (hash_value) + 1; + } + + cur_value = gclue_min_uint_get_value (muint); + g_hash_table_replace (muint->priv->all_values, + key, + GUINT_TO_POINTER (num_users)); + new_value = gclue_min_uint_get_value (muint); + + if (cur_value != new_value && muint->priv->notify_value) { + g_object_notify_by_pspec (G_OBJECT (muint), + gParamSpecs[PROP_VALUE]); + } +} + +/** + * gclue_min_uint_drop_value + * @muint: a #GClueMinUINT + * @value: A value to drop from the list + **/ +void +gclue_min_uint_drop_value (GClueMinUINT *muint, + guint value) +{ + gpointer key, hash_value; + guint cur_value, new_value; + guint num_users; + + g_return_if_fail (GCLUE_IS_MIN_UINT(muint)); + + key = GUINT_TO_POINTER (value); + hash_value = g_hash_table_lookup (muint->priv->all_values, key); + if (hash_value == NULL) { + return; + } + + cur_value = gclue_min_uint_get_value (muint); + num_users = GPOINTER_TO_UINT (hash_value) - 1; + if (num_users == 0) { + g_hash_table_remove (muint->priv->all_values, key); + } else { + g_hash_table_replace (muint->priv->all_values, + key, + GUINT_TO_POINTER (num_users)); + } + new_value = gclue_min_uint_get_value (muint); + + if (cur_value != new_value && muint->priv->notify_value) { + g_object_notify_by_pspec (G_OBJECT (muint), + gParamSpecs[PROP_VALUE]); + } +} + +/** + * gclue_min_uint_exchange_value + * @muint: a #GClueMinUINT + * @to_drop: A value to drop from the list + * @to_add: A value to add to the list + * + * Use this method instead of #gclue_min_uint_drop_value and + * #gclue_min_uint_add_value to ensure #GClueMinUINT:value property is only + * notified once. + **/ +void +gclue_min_uint_exchage_value (GClueMinUINT *muint, + guint to_drop, + guint to_add) +{ + g_return_if_fail (GCLUE_IS_MIN_UINT(muint)); + + muint->priv->notify_value = FALSE; + gclue_min_uint_drop_value (muint, to_drop); + muint->priv->notify_value = TRUE; + + gclue_min_uint_add_value (muint, to_add); +} diff --git a/src/gclue-min-uint.h b/src/gclue-min-uint.h new file mode 100644 index 0000000..041b1a7 --- /dev/null +++ b/src/gclue-min-uint.h @@ -0,0 +1,68 @@ +/* vim: set et ts=8 sw=8: */ +/* gclue-service-client.h + * + * Copyright (C) 2018 Collabora Ltd. + * + * Geoclue is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * Geoclue is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License along + * with Geoclue; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Author: Zeeshan Ali (Khattak) <zeeshanak@gnome.org> + */ + +#ifndef GCLUE_MIN_UINT_H +#define GCLUE_MIN_UINT_H + +#include <glib-object.h> + +G_BEGIN_DECLS + +#define GCLUE_TYPE_MIN_UINT (gclue_min_uint_get_type()) +#define GCLUE_MIN_UINT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GCLUE_TYPE_MIN_UINT, GClueMinUINT)) +#define GCLUE_MIN_UINT_CONST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GCLUE_TYPE_MIN_UINT, GClueMinUINT const)) +#define GCLUE_MIN_UINT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GCLUE_TYPE_MIN_UINT, GClueMinUINTClass)) +#define GCLUE_IS_MIN_UINT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GCLUE_TYPE_MIN_UINT)) +#define GCLUE_IS_MIN_UINT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GCLUE_TYPE_MIN_UINT)) +#define GCLUE_MIN_UINT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GCLUE_TYPE_MIN_UINT, GClueMinUINTClass)) + +typedef struct _GClueMinUINT GClueMinUINT; +typedef struct _GClueMinUINTClass GClueMinUINTClass; +typedef struct _GClueMinUINTPrivate GClueMinUINTPrivate; + +struct _GClueMinUINT +{ + GObject parent; + + /*< private >*/ + GClueMinUINTPrivate *priv; +}; + +struct _GClueMinUINTClass +{ + GObjectClass parent_class; +}; + +GType gclue_min_uint_get_type (void) G_GNUC_CONST; + +GClueMinUINT * gclue_min_uint_new (void); +guint gclue_min_uint_get_value (GClueMinUINT *muint); +void gclue_min_uint_add_value (GClueMinUINT *muint, + guint value); +void gclue_min_uint_drop_value (GClueMinUINT *muint, + guint value); +void gclue_min_uint_exchage_value (GClueMinUINT *muint, + guint to_drop, + guint to_add); +G_END_DECLS + +#endif /* GCLUE_MIN_UINT_H */ |