summaryrefslogtreecommitdiff
path: root/deps/uber-graph/uber-frame-source.c
diff options
context:
space:
mode:
Diffstat (limited to 'deps/uber-graph/uber-frame-source.c')
-rw-r--r--deps/uber-graph/uber-frame-source.c177
1 files changed, 177 insertions, 0 deletions
diff --git a/deps/uber-graph/uber-frame-source.c b/deps/uber-graph/uber-frame-source.c
new file mode 100644
index 00000000..3de4d537
--- /dev/null
+++ b/deps/uber-graph/uber-frame-source.c
@@ -0,0 +1,177 @@
+/*
+ * Clutter.
+ *
+ * An OpenGL based 'interactive canvas' library.
+ *
+ * Authored By Neil Roberts <neil@linux.intel.com>
+ *
+ * Copyright (C) 2008 OpenedHand
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ *
+ */
+
+/* Modified by Christian Hergert for use in Uber Graph. */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "uber-frame-source.h"
+#include "uber-timeout-interval.h"
+
+typedef struct _UberFrameSource UberFrameSource;
+
+struct _UberFrameSource
+{
+ GSource source;
+
+ UberTimeoutInterval timeout;
+};
+
+static gboolean uber_frame_source_prepare (GSource *source,
+ gint *timeout);
+static gboolean uber_frame_source_check (GSource *source);
+static gboolean uber_frame_source_dispatch (GSource *source,
+ GSourceFunc callback,
+ gpointer user_data);
+
+static GSourceFuncs uber_frame_source_funcs =
+{
+ uber_frame_source_prepare,
+ uber_frame_source_check,
+ uber_frame_source_dispatch,
+ NULL
+};
+
+/**
+ * uber_frame_source_add_full:
+ * @priority: the priority of the frame source. Typically this will be in the
+ * range between %G_PRIORITY_DEFAULT and %G_PRIORITY_HIGH.
+ * @fps: the number of times per second to call the function
+ * @func: function to call
+ * @data: data to pass to the function
+ * @notify: function to call when the timeout source is removed
+ *
+ * Sets a function to be called at regular intervals with the given
+ * priority. The function is called repeatedly until it returns
+ * %FALSE, at which point the timeout is automatically destroyed and
+ * the function will not be called again. The @notify function is
+ * called when the timeout is destroyed. The first call to the
+ * function will be at the end of the first @interval.
+ *
+ * This function is similar to g_timeout_add_full() except that it
+ * will try to compensate for delays. For example, if @func takes half
+ * the interval time to execute then the function will be called again
+ * half the interval time after it finished. In contrast
+ * g_timeout_add_full() would not fire until a full interval after the
+ * function completes so the delay between calls would be 1.0 / @fps *
+ * 1.5. This function does not however try to invoke the function
+ * multiple times to catch up missing frames if @func takes more than
+ * @interval ms to execute.
+ *
+ * Return value: the ID (greater than 0) of the event source.
+ *
+ * Since: 0.8
+ */
+guint
+uber_frame_source_add_full (gint priority,
+ guint fps,
+ GSourceFunc func,
+ gpointer data,
+ GDestroyNotify notify)
+{
+ guint ret;
+ GSource *source = g_source_new (&uber_frame_source_funcs,
+ sizeof (UberFrameSource));
+ UberFrameSource *frame_source = (UberFrameSource *) source;
+
+ _uber_timeout_interval_init (&frame_source->timeout, fps);
+
+ if (priority != G_PRIORITY_DEFAULT)
+ g_source_set_priority (source, priority);
+
+#if GLIB_CHECK_VERSION (2, 25, 8)
+ g_source_set_name (source, "Uber frame timeout");
+#endif
+
+ g_source_set_callback (source, func, data, notify);
+
+ ret = g_source_attach (source, NULL);
+
+ g_source_unref (source);
+
+ return ret;
+}
+
+/**
+ * uber_frame_source_add:
+ * @fps: the number of times per second to call the function
+ * @func: function to call
+ * @data: data to pass to the function
+ *
+ * Simple wrapper around uber_frame_source_add_full().
+ *
+ * Return value: the ID (greater than 0) of the event source.
+ *
+ * Since: 0.8
+ */
+guint
+uber_frame_source_add (guint fps,
+ GSourceFunc func,
+ gpointer data)
+{
+ return uber_frame_source_add_full (G_PRIORITY_DEFAULT,
+ fps, func, data, NULL);
+}
+
+static gboolean
+uber_frame_source_prepare (GSource *source,
+ gint *delay)
+{
+ UberFrameSource *frame_source = (UberFrameSource *) source;
+ gint64 current_time;
+
+#if GLIB_CHECK_VERSION (2, 27, 3)
+ current_time = g_source_get_time (source) / 1000;
+#else
+ {
+ GTimeVal source_time;
+ g_source_get_current_time (source, &source_time);
+ current_time = source_time.tv_sec * 1000 + source_time.tv_usec / 1000;
+ }
+#endif
+
+ return _uber_timeout_interval_prepare (current_time,
+ &frame_source->timeout,
+ delay);
+}
+
+static gboolean
+uber_frame_source_check (GSource *source)
+{
+ return uber_frame_source_prepare (source, NULL);
+}
+
+static gboolean
+uber_frame_source_dispatch (GSource *source,
+ GSourceFunc callback,
+ gpointer user_data)
+{
+ UberFrameSource *frame_source = (UberFrameSource *) source;
+
+ return _uber_timeout_interval_dispatch (&frame_source->timeout,
+ callback, user_data);
+}