mutter/clutter/clutter-frame-source.c
Emmanuele Bassi 816aa93135 2008-04-17 Emmanuele Bassi <ebassi@openedhand.com>
* clutter/clutter-frame-source.c: Small coding style fixes.
2008-04-17 20:53:37 +00:00

157 lines
4.1 KiB
C

/*
* Clutter.
*
* An OpenGL based 'interactive canvas' library.
*
* Authored By Matthew Allum <mallum@openedhand.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, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "clutter-frame-source.h"
typedef struct _ClutterFrameSource ClutterFrameSource;
struct _ClutterFrameSource
{
GSource source;
GTimeVal start_time;
guint last_time, frame_time;
};
static gboolean clutter_frame_source_prepare (GSource *source, gint *timeout);
static gboolean clutter_frame_source_check (GSource *source);
static gboolean clutter_frame_source_dispatch (GSource *source,
GSourceFunc callback,
gpointer user_data);
static GSourceFuncs clutter_frame_source_funcs =
{
clutter_frame_source_prepare,
clutter_frame_source_check,
clutter_frame_source_dispatch,
NULL
};
guint
clutter_frame_source_add_full (gint priority,
guint interval,
GSourceFunc function,
gpointer data,
GDestroyNotify notify)
{
guint ret;
GSource *source = g_source_new (&clutter_frame_source_funcs,
sizeof (ClutterFrameSource));
ClutterFrameSource *frame_source = (ClutterFrameSource *) source;
frame_source->last_time = 0;
frame_source->frame_time = interval;
g_get_current_time (&frame_source->start_time);
if (priority != G_PRIORITY_DEFAULT)
g_source_set_priority (source, priority);
g_source_set_callback (source, function, data, notify);
ret = g_source_attach (source, NULL);
g_source_unref (source);
return ret;
}
guint
clutter_frame_source_add (guint interval,
GSourceFunc function,
gpointer data)
{
return clutter_frame_source_add_full (G_PRIORITY_DEFAULT,
interval, function, data, NULL);
}
static guint
clutter_frame_source_get_ticks (ClutterFrameSource *frame_source)
{
GTimeVal time_now;
g_source_get_current_time ((GSource *) frame_source, &time_now);
return (time_now.tv_sec - frame_source->start_time.tv_sec) * 1000
+ (time_now.tv_usec - frame_source->start_time.tv_usec) / 1000;
}
static gboolean
clutter_frame_source_prepare (GSource *source, gint *timeout)
{
ClutterFrameSource *frame_source = (ClutterFrameSource *) source;
guint now = clutter_frame_source_get_ticks (frame_source);
/* If time has gone backwards or the time since the last frame is
greater than the two frames worth then reset the time and do a
frame now */
if (frame_source->last_time > now ||
(now - frame_source->last_time) > frame_source->frame_time * 2)
{
frame_source->last_time = now - frame_source->frame_time;
if (timeout)
*timeout = 0;
return TRUE;
}
else if (now - frame_source->last_time >= frame_source->frame_time)
{
if (timeout)
*timeout = 0;
return TRUE;
}
else
{
if (timeout)
*timeout = frame_source->frame_time + frame_source->last_time - now;
return FALSE;
}
}
static gboolean
clutter_frame_source_check (GSource *source)
{
return clutter_frame_source_prepare (source, NULL);
}
static gboolean
clutter_frame_source_dispatch (GSource *source,
GSourceFunc callback,
gpointer user_data)
{
ClutterFrameSource *frame_source = (ClutterFrameSource *) source;
if ((* callback) (user_data))
{
frame_source->last_time += frame_source->frame_time;
return TRUE;
}
else
return FALSE;
}