From 5f2d1654a5085fb64af96310e297db4a7c4a39c2 Mon Sep 17 00:00:00 2001 From: "Owen W. Taylor" Date: Tue, 12 Feb 2013 15:02:21 -0500 Subject: [PATCH] Change GdkFrameClock from an interface to a class It's unlikely that anyone will want to have, say, a GtkWidget that also acts as a GdkFrameClock, so an abstract base class is as flexible as making GdkFrameClock an interface, but has advantages: - If we decide to never make implementing your own frame clock possible, we can remove the virtualization. - We can put functionality like history into the base class. - Avoids the oddity of a interface without a public interface VTable, which may cause problems for language bindings. --- gdk/Makefile.am | 1 + gdk/gdkframeclock.c | 72 +++++++++++++++++++++++++------------- gdk/gdkframeclock.h | 44 +++++------------------ gdk/gdkframeclockidle.c | 60 ++++++++++++------------------- gdk/gdkframeclockidle.h | 6 ++-- gdk/gdkframeclockprivate.h | 72 ++++++++++++++++++++++++++++++++++++++ 6 files changed, 154 insertions(+), 101 deletions(-) create mode 100644 gdk/gdkframeclockprivate.h diff --git a/gdk/Makefile.am b/gdk/Makefile.am index 61aeb4bc7..4ef63c02f 100644 --- a/gdk/Makefile.am +++ b/gdk/Makefile.am @@ -105,6 +105,7 @@ gdk_private_headers = \ gdkdisplayprivate.h \ gdkdndprivate.h \ gdkframeclockidle.h \ + gdkframeclockprivate.h \ gdkscreenprivate.h \ gdkinternals.h \ gdkintl.h \ diff --git a/gdk/gdkframeclock.c b/gdk/gdkframeclock.c index 08789ebb0..8cdc1d109 100644 --- a/gdk/gdkframeclock.c +++ b/gdk/gdkframeclock.c @@ -26,7 +26,7 @@ #include "config.h" -#include "gdkframeclock.h" +#include "gdkframeclockprivate.h" /** * SECTION:frameclock @@ -74,7 +74,7 @@ * time that doesn't have a lot to do with wall clock time. */ -G_DEFINE_INTERFACE (GdkFrameClock, gdk_frame_clock, G_TYPE_OBJECT) +G_DEFINE_ABSTRACT_TYPE (GdkFrameClock, gdk_frame_clock, G_TYPE_OBJECT) enum { FRAME_REQUESTED, @@ -90,9 +90,28 @@ enum { static guint signals[LAST_SIGNAL]; +struct _GdkFrameClockPrivate +{ + GdkFrameHistory *history; +}; + +static void +gdk_frame_clock_finalize (GObject *object) +{ + GdkFrameClockPrivate *priv = GDK_FRAME_CLOCK (object)->priv; + + g_object_unref (priv->history); + + G_OBJECT_CLASS (gdk_frame_clock_parent_class)->finalize (object); +} + static void -gdk_frame_clock_default_init (GdkFrameClockInterface *iface) +gdk_frame_clock_class_init (GdkFrameClockClass *klass) { + GObjectClass *gobject_class = (GObjectClass*) klass; + + gobject_class->finalize = gdk_frame_clock_finalize; + /** * GdkFrameClock::frame-requested: * @clock: the frame clock emitting the signal @@ -221,6 +240,21 @@ gdk_frame_clock_default_init (GdkFrameClockInterface *iface) NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); + + g_type_class_add_private (klass, sizeof (GdkFrameClockPrivate)); +} + +static void +gdk_frame_clock_init (GdkFrameClock *clock) +{ + GdkFrameClockPrivate *priv; + + clock->priv = G_TYPE_INSTANCE_GET_PRIVATE (clock, + GDK_TYPE_FRAME_CLOCK, + GdkFrameClockPrivate); + priv = clock->priv; + + priv->history = gdk_frame_history_new (); } /** @@ -247,7 +281,7 @@ gdk_frame_clock_get_frame_time (GdkFrameClock *clock) { g_return_val_if_fail (GDK_IS_FRAME_CLOCK (clock), 0); - return GDK_FRAME_CLOCK_GET_IFACE (clock)->get_frame_time (clock); + return GDK_FRAME_CLOCK_GET_CLASS (clock)->get_frame_time (clock); } /** @@ -270,7 +304,7 @@ gdk_frame_clock_request_phase (GdkFrameClock *clock, { g_return_if_fail (GDK_IS_FRAME_CLOCK (clock)); - GDK_FRAME_CLOCK_GET_IFACE (clock)->request_phase (clock, phase); + GDK_FRAME_CLOCK_GET_CLASS (clock)->request_phase (clock, phase); } @@ -279,7 +313,7 @@ gdk_frame_clock_freeze (GdkFrameClock *clock) { g_return_if_fail (GDK_IS_FRAME_CLOCK (clock)); - GDK_FRAME_CLOCK_GET_IFACE (clock)->freeze (clock); + GDK_FRAME_CLOCK_GET_CLASS (clock)->freeze (clock); } @@ -288,7 +322,7 @@ gdk_frame_clock_thaw (GdkFrameClock *clock) { g_return_if_fail (GDK_IS_FRAME_CLOCK (clock)); - GDK_FRAME_CLOCK_GET_IFACE (clock)->thaw (clock); + GDK_FRAME_CLOCK_GET_CLASS (clock)->thaw (clock); } /** @@ -303,9 +337,13 @@ gdk_frame_clock_thaw (GdkFrameClock *clock) GdkFrameHistory * gdk_frame_clock_get_history (GdkFrameClock *clock) { + GdkFrameClockPrivate *priv; + g_return_val_if_fail (GDK_IS_FRAME_CLOCK (clock), NULL); - return GDK_FRAME_CLOCK_GET_IFACE (clock)->get_history (clock); + priv = clock->priv; + + return priv->history; } /** @@ -324,7 +362,7 @@ gdk_frame_clock_get_requested (GdkFrameClock *clock) { g_return_val_if_fail (GDK_IS_FRAME_CLOCK (clock), FALSE); - return GDK_FRAME_CLOCK_GET_IFACE (clock)->get_requested (clock); + return GDK_FRAME_CLOCK_GET_CLASS (clock)->get_requested (clock); } /** @@ -350,22 +388,6 @@ gdk_frame_clock_get_frame_time_val (GdkFrameClock *clock, timeval->tv_usec = (time_ms % 1000) * 1000; } -/** - * gdk_frame_clock_frame_requested: - * @clock: the clock - * - * Emits the frame-requested signal. Used in implementations of the - * #GdkFrameClock interface. - */ -void -gdk_frame_clock_frame_requested (GdkFrameClock *clock) -{ - g_return_if_fail (GDK_IS_FRAME_CLOCK (clock)); - - g_signal_emit (G_OBJECT (clock), - signals[FRAME_REQUESTED], 0); -} - GdkFrameTimings * gdk_frame_clock_get_current_frame_timings (GdkFrameClock *clock) { diff --git a/gdk/gdkframeclock.h b/gdk/gdkframeclock.h index ba6a59f40..608d74320 100644 --- a/gdk/gdkframeclock.h +++ b/gdk/gdkframeclock.h @@ -35,13 +35,16 @@ G_BEGIN_DECLS -typedef struct _GdkFrameClock GdkFrameClock; -typedef struct _GdkFrameClockInterface GdkFrameClockInterface; +#define GDK_TYPE_FRAME_CLOCK (gdk_frame_clock_get_type ()) +#define GDK_FRAME_CLOCK(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GDK_TYPE_FRAME_CLOCK, GdkFrameClock)) +#define GDK_FRAME_CLOCK_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GDK_TYPE_FRAME_CLOCK, GdkFrameClockClass)) +#define GDK_IS_FRAME_CLOCK(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GDK_TYPE_FRAME_CLOCK)) +#define GDK_IS_FRAME_CLOCK_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GDK_TYPE_FRAME_CLOCK)) +#define GDK_FRAME_CLOCK_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GDK_TYPE_FRAME_CLOCK, GdkFrameClockClass)) -#define GDK_TYPE_FRAME_CLOCK (gdk_frame_clock_get_type ()) -#define GDK_FRAME_CLOCK(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GDK_TYPE_FRAME_CLOCK, GdkFrameClock)) -#define GDK_IS_FRAME_CLOCK(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GDK_TYPE_FRAME_CLOCK)) -#define GDK_FRAME_CLOCK_GET_IFACE(inst) (G_TYPE_INSTANCE_GET_INTERFACE ((inst), GDK_TYPE_FRAME_CLOCK, GdkFrameClockInterface)) +typedef struct _GdkFrameClock GdkFrameClock; +typedef struct _GdkFrameClockPrivate GdkFrameClockPrivate; +typedef struct _GdkFrameClockClass GdkFrameClockClass; typedef enum { GDK_FRAME_CLOCK_PHASE_NONE = 0, @@ -54,32 +57,6 @@ typedef enum { GDK_FRAME_CLOCK_PHASE_AFTER_PAINT = 1 << 6 } GdkFrameClockPhase; -struct _GdkFrameClockInterface -{ - GTypeInterface base_iface; - - guint64 (* get_frame_time) (GdkFrameClock *clock); - - void (* request_phase) (GdkFrameClock *clock, - GdkFrameClockPhase phase); - GdkFrameClockPhase (* get_requested) (GdkFrameClock *clock); - - void (* freeze) (GdkFrameClock *clock); - void (* thaw) (GdkFrameClock *clock); - - GdkFrameHistory * (* get_history) (GdkFrameClock *clock); - - /* signals */ - /* void (* frame_requested) (GdkFrameClock *clock); */ - /* void (* flush_events) (GdkFrameClock *clock); */ - /* void (* before_paint) (GdkFrameClock *clock); */ - /* void (* update) (GdkFrameClock *clock); */ - /* void (* layout) (GdkFrameClock *clock); */ - /* void (* paint) (GdkFrameClock *clock); */ - /* void (* after_paint) (GdkFrameClock *clock); */ - /* void (* resume_events) (GdkFrameClock *clock); */ -}; - GType gdk_frame_clock_get_type (void) G_GNUC_CONST; guint64 gdk_frame_clock_get_frame_time (GdkFrameClock *clock); @@ -104,9 +81,6 @@ void gdk_frame_clock_get_refresh_info (GdkFrameClock *clock, GdkFrameTimings *gdk_frame_clock_get_current_frame_timings (GdkFrameClock *clock); -/* Signal emitters (used in frame clock implementations) */ -void gdk_frame_clock_frame_requested (GdkFrameClock *clock); - G_END_DECLS #endif /* __GDK_FRAME_CLOCK_H__ */ diff --git a/gdk/gdkframeclockidle.c b/gdk/gdkframeclockidle.c index 47103703c..6a35daacd 100644 --- a/gdk/gdkframeclockidle.c +++ b/gdk/gdkframeclockidle.c @@ -27,6 +27,7 @@ #include "config.h" #include "gdkinternals.h" +#include "gdkframeclockprivate.h" #include "gdkframeclockidle.h" #include "gdk.h" @@ -34,7 +35,6 @@ struct _GdkFrameClockIdlePrivate { - GdkFrameHistory *history; GTimer *timer; /* timer_base is used to avoid ever going backward */ guint64 timer_base; @@ -56,11 +56,8 @@ static gboolean gdk_frame_clock_flush_idle (void *data); static gboolean gdk_frame_clock_paint_idle (void *data); static void gdk_frame_clock_idle_finalize (GObject *object); -static void gdk_frame_clock_idle_interface_init (GdkFrameClockInterface *iface); -G_DEFINE_TYPE_WITH_CODE (GdkFrameClockIdle, gdk_frame_clock_idle, G_TYPE_OBJECT, - G_IMPLEMENT_INTERFACE (GDK_TYPE_FRAME_CLOCK, - gdk_frame_clock_idle_interface_init)) +G_DEFINE_TYPE (GdkFrameClockIdle, gdk_frame_clock_idle, GDK_TYPE_FRAME_CLOCK) static gint64 sleep_serial; static gint64 sleep_source_prepare_time; @@ -114,16 +111,6 @@ get_sleep_serial (void) return sleep_serial; } -static void -gdk_frame_clock_idle_class_init (GdkFrameClockIdleClass *klass) -{ - GObjectClass *gobject_class = (GObjectClass*) klass; - - gobject_class->finalize = gdk_frame_clock_idle_finalize; - - g_type_class_add_private (klass, sizeof (GdkFrameClockIdlePrivate)); -} - static void gdk_frame_clock_idle_init (GdkFrameClockIdle *frame_clock_idle) { @@ -134,7 +121,6 @@ gdk_frame_clock_idle_init (GdkFrameClockIdle *frame_clock_idle) GdkFrameClockIdlePrivate); priv = frame_clock_idle->priv; - priv->history = gdk_frame_history_new (); priv->timer = g_timer_new (); priv->freeze_count = 0; } @@ -235,7 +221,7 @@ maybe_start_idle (GdkFrameClockIdle *clock_idle) g_object_ref (clock_idle), (GDestroyNotify) g_object_unref); - gdk_frame_clock_frame_requested (GDK_FRAME_CLOCK (clock_idle)); + g_signal_emit_by_name (clock_idle, "frame-requested"); } } } @@ -288,6 +274,7 @@ gdk_frame_clock_paint_idle (void *data) GdkFrameClock *clock = GDK_FRAME_CLOCK (data); GdkFrameClockIdle *clock_idle = GDK_FRAME_CLOCK_IDLE (clock); GdkFrameClockIdlePrivate *priv = clock_idle->priv; + GdkFrameHistory *history = gdk_frame_clock_get_history (clock); gboolean skip_to_resume_events; GdkFrameTimings *timings = NULL; gint64 frame_counter = 0; @@ -301,8 +288,8 @@ gdk_frame_clock_paint_idle (void *data) if (priv->phase > GDK_FRAME_CLOCK_PHASE_BEFORE_PAINT) { - frame_counter = gdk_frame_history_get_frame_counter (priv->history); - timings = gdk_frame_history_get_timings (priv->history, frame_counter); + frame_counter = gdk_frame_history_get_frame_counter (history); + timings = gdk_frame_history_get_timings (history, frame_counter); } if (!skip_to_resume_events) @@ -317,9 +304,9 @@ gdk_frame_clock_paint_idle (void *data) { priv->frame_time = compute_frame_time (clock_idle); - gdk_frame_history_begin_frame (priv->history); - frame_counter = gdk_frame_history_get_frame_counter (priv->history); - timings = gdk_frame_history_get_timings (priv->history, frame_counter); + gdk_frame_history_begin_frame (history); + frame_counter = gdk_frame_history_get_frame_counter (history); + timings = gdk_frame_history_get_timings (history, frame_counter); gdk_frame_timings_set_frame_time (timings, priv->frame_time); @@ -406,7 +393,7 @@ gdk_frame_clock_paint_idle (void *data) if ((_gdk_debug_flags & GDK_DEBUG_FRAMES) != 0) { if (gdk_frame_timings_get_complete (timings)) - _gdk_frame_history_debug_print (priv->history, timings); + _gdk_frame_history_debug_print (history, timings); } #endif /* G_ENABLE_DEBUG */ @@ -501,24 +488,21 @@ gdk_frame_clock_idle_thaw (GdkFrameClock *clock) } } -static GdkFrameHistory * -gdk_frame_clock_idle_get_history (GdkFrameClock *clock) +static void +gdk_frame_clock_idle_class_init (GdkFrameClockIdleClass *klass) { - GdkFrameClockIdle *clock_idle = GDK_FRAME_CLOCK_IDLE (clock); - GdkFrameClockIdlePrivate *priv = clock_idle->priv; + GObjectClass *gobject_class = (GObjectClass*) klass; + GdkFrameClockClass *frame_clock_class = (GdkFrameClockClass *)klass; - return priv->history; -} + gobject_class->finalize = gdk_frame_clock_idle_finalize; -static void -gdk_frame_clock_idle_interface_init (GdkFrameClockInterface *iface) -{ - iface->get_frame_time = gdk_frame_clock_idle_get_frame_time; - iface->request_phase = gdk_frame_clock_idle_request_phase; - iface->get_requested = gdk_frame_clock_idle_get_requested; - iface->freeze = gdk_frame_clock_idle_freeze; - iface->thaw = gdk_frame_clock_idle_thaw; - iface->get_history = gdk_frame_clock_idle_get_history; + frame_clock_class->get_frame_time = gdk_frame_clock_idle_get_frame_time; + frame_clock_class->request_phase = gdk_frame_clock_idle_request_phase; + frame_clock_class->get_requested = gdk_frame_clock_idle_get_requested; + frame_clock_class->freeze = gdk_frame_clock_idle_freeze; + frame_clock_class->thaw = gdk_frame_clock_idle_thaw; + + g_type_class_add_private (klass, sizeof (GdkFrameClockIdlePrivate)); } GdkFrameClock * diff --git a/gdk/gdkframeclockidle.h b/gdk/gdkframeclockidle.h index f4815a949..b76dd6677 100644 --- a/gdk/gdkframeclockidle.h +++ b/gdk/gdkframeclockidle.h @@ -29,7 +29,7 @@ #ifndef __GDK_FRAME_CLOCK_IDLE_H__ #define __GDK_FRAME_CLOCK_IDLE_H__ -#include +#include "gdkframeclockprivate.h" G_BEGIN_DECLS @@ -47,7 +47,7 @@ typedef struct _GdkFrameClockIdleClass GdkFrameClockIdleClass; struct _GdkFrameClockIdle { - GObject parent_instance; + GdkFrameClock parent_instance; /*< private >*/ GdkFrameClockIdlePrivate *priv; @@ -55,7 +55,7 @@ struct _GdkFrameClockIdle struct _GdkFrameClockIdleClass { - GObjectClass parent_class; + GdkFrameClockClass parent_class; }; GType gdk_frame_clock_idle_get_type (void) G_GNUC_CONST; diff --git a/gdk/gdkframeclockprivate.h b/gdk/gdkframeclockprivate.h new file mode 100644 index 000000000..6c01dd2c4 --- /dev/null +++ b/gdk/gdkframeclockprivate.h @@ -0,0 +1,72 @@ +/* GDK - The GIMP Drawing Kit + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * + * 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. + */ + +/* + * Modified by the GTK+ Team and others 1997-2010. See the AUTHORS + * file for a list of people on the GTK+ Team. See the ChangeLog + * files for a list of changes. These files are distributed with + * GTK+ at ftp://ftp.gtk.org/pub/gtk/. + */ + +/* Uninstalled header, internal to GDK */ + +#ifndef __GDK_FRAME_CLOCK_PRIVATE_H__ +#define __GDK_FRAME_CLOCK_PRIVATE_H__ + +#include + +G_BEGIN_DECLS + +typedef struct _GdkFrameClockIdlePrivate GdkFrameClockIdlePrivate; + +struct _GdkFrameClock +{ + GObject parent_instance; + + /*< private >*/ + GdkFrameClockPrivate *priv; +}; + +struct _GdkFrameClockClass +{ + GObjectClass parent_class; + + guint64 (* get_frame_time) (GdkFrameClock *clock); + + void (* request_phase) (GdkFrameClock *clock, + GdkFrameClockPhase phase); + GdkFrameClockPhase (* get_requested) (GdkFrameClock *clock); + + void (* freeze) (GdkFrameClock *clock); + void (* thaw) (GdkFrameClock *clock); + + /* signals */ + /* void (* frame_requested) (GdkFrameClock *clock); */ + /* void (* flush_events) (GdkFrameClock *clock); */ + /* void (* before_paint) (GdkFrameClock *clock); */ + /* void (* update) (GdkFrameClock *clock); */ + /* void (* layout) (GdkFrameClock *clock); */ + /* void (* paint) (GdkFrameClock *clock); */ + /* void (* after_paint) (GdkFrameClock *clock); */ + /* void (* resume_events) (GdkFrameClock *clock); */ +}; + +G_END_DECLS + +#endif /* __GDK_FRAME_CLOCK_PRIVATE_H__ */ -- 2.43.2