diff options
Diffstat (limited to 'deps/uber-graph/uber-frame-source.c')
-rw-r--r-- | deps/uber-graph/uber-frame-source.c | 177 |
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); +} |