summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZeeshan Ali <zeeshanak@gnome.org>2018-04-12 18:51:39 +0200
committerZeeshan Ali <zeeshanak@gnome.org>2018-04-17 12:30:20 +0200
commitda29f99d2cd292174d6d785cdb531455d141eda0 (patch)
treea2705c944a8fdee2adb0381f12938c538b78bd13
parent10d346e95892cc12e0155a8087f14a979a182392 (diff)
downloadgeoclue-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.am2
-rw-r--r--src/gclue-min-uint.c251
-rw-r--r--src/gclue-min-uint.h68
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 */