[sysprof] replay: add stubs and plumbing to implement a re-record



commit 19f8c6b39fb08242fc6cb7c0616c30716d134313
Author: Christian Hergert <chergert redhat com>
Date:   Thu May 23 16:17:54 2019 -0700

    replay: add stubs and plumbing to implement a re-record
    
    The goal here is to be able to do a duplicate recording to the previous
    with a quick key-combination like Ctrl+R.
    
    We still need to extract the metadata from the capture file and setup
    a new profiler, but this gets the mechanics in place.

 src/libsysprof-ui/sysprof-capture-view.c | 24 +++++++++++-
 src/libsysprof-ui/sysprof-capture-view.h |  2 +
 src/libsysprof-ui/sysprof-display.c      | 33 +++++++++++++++++
 src/libsysprof-ui/sysprof-display.h      |  4 ++
 src/libsysprof-ui/sysprof-notebook.c     | 63 ++++++++++++++++++++++++++++++++
 src/libsysprof-ui/sysprof-notebook.h     | 18 +++++----
 src/sysprof/gtk/menus.ui                 |  7 ++++
 src/sysprof/sysprof-application.c        |  1 +
 src/sysprof/sysprof-window.c             | 35 +++++++++++++++++-
 9 files changed, 177 insertions(+), 10 deletions(-)
---
diff --git a/src/libsysprof-ui/sysprof-capture-view.c b/src/libsysprof-ui/sysprof-capture-view.c
index dd7e477..2d36e79 100644
--- a/src/libsysprof-ui/sysprof-capture-view.c
+++ b/src/libsysprof-ui/sysprof-capture-view.c
@@ -41,6 +41,7 @@ typedef struct
   guint has_samples : 1;
   guint has_counters : 1;
   guint has_marks : 1;
+  guint can_replay : 1;
 } SysprofCaptureFeatures;
 
 typedef struct
@@ -64,6 +65,7 @@ typedef struct
 
   guint                   busy;
 
+  guint                   can_replay : 1;
   guint                   needs_fit : 1;
 } SysprofCaptureViewPrivate;
 
@@ -318,7 +320,17 @@ sysprof_capture_view_scan_worker (GTask        *task,
 
       st_buf.frame_count[frame.type]++;
 
-      if (frame.type == SYSPROF_CAPTURE_FRAME_MARK)
+      if (frame.type == SYSPROF_CAPTURE_FRAME_METADATA)
+        {
+          const SysprofCaptureMetadata *meta;
+
+          if ((meta = sysprof_capture_reader_read_metadata (reader)))
+            {
+              if (g_strcmp0 (meta->id, "local-profiler") == 0)
+                features.can_replay = TRUE;
+            }
+        }
+      else if (frame.type == SYSPROF_CAPTURE_FRAME_MARK)
         {
           const SysprofCaptureMark *mark;
 
@@ -997,3 +1009,13 @@ sysprof_capture_view_get_reader (SysprofCaptureView *self)
 
   return priv->reader;
 }
+
+gboolean
+sysprof_capture_view_get_can_replay (SysprofCaptureView *self)
+{
+  SysprofCaptureViewPrivate *priv = sysprof_capture_view_get_instance_private (self);
+
+  g_return_val_if_fail (SYSPROF_IS_CAPTURE_VIEW (self), FALSE);
+
+  return priv->features.can_replay;
+}
diff --git a/src/libsysprof-ui/sysprof-capture-view.h b/src/libsysprof-ui/sysprof-capture-view.h
index 3dad57d..dac9b10 100644
--- a/src/libsysprof-ui/sysprof-capture-view.h
+++ b/src/libsysprof-ui/sysprof-capture-view.h
@@ -69,5 +69,7 @@ SYSPROF_AVAILABLE_IN_ALL
 gboolean              sysprof_capture_view_get_busy         (SysprofCaptureView    *self);
 SYSPROF_AVAILABLE_IN_ALL
 void                  sysprof_capture_view_fit_to_width     (SysprofCaptureView    *self);
+SYSPROF_AVAILABLE_IN_ALL
+gboolean              sysprof_capture_view_get_can_replay   (SysprofCaptureView    *self);
 
 G_END_DECLS
diff --git a/src/libsysprof-ui/sysprof-display.c b/src/libsysprof-ui/sysprof-display.c
index 1b7b235..328d6ff 100644
--- a/src/libsysprof-ui/sysprof-display.c
+++ b/src/libsysprof-ui/sysprof-display.c
@@ -53,6 +53,7 @@ G_DEFINE_TYPE_WITH_PRIVATE (SysprofDisplay, sysprof_display, GTK_TYPE_BIN)
 
 enum {
   PROP_0,
+  PROP_CAN_REPLAY,
   PROP_CAN_SAVE,
   PROP_RECORDING,
   PROP_TITLE,
@@ -91,6 +92,7 @@ sysprof_display_load_cb (SysprofCaptureView *view,
   if (!sysprof_capture_view_load_finish (view, result, &error))
     g_warning ("Failed to load capture: %s", error->message);
 
+  g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_CAN_REPLAY]);
   g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_CAN_SAVE]);
 }
 
@@ -148,6 +150,7 @@ sysprof_display_profiler_stopped_cb (SysprofDisplay  *self,
     }
 
 notify:
+  g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_CAN_REPLAY]);
   g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_CAN_SAVE]);
   g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_RECORDING]);
   g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_TITLE]);
@@ -297,6 +300,10 @@ sysprof_display_get_property (GObject    *object,
 
   switch (prop_id)
     {
+    case PROP_CAN_REPLAY:
+      g_value_set_boolean (value, sysprof_display_get_can_replay (self));
+      break;
+
     case PROP_CAN_SAVE:
       g_value_set_boolean (value, sysprof_display_get_can_save (self));
       break;
@@ -325,6 +332,13 @@ sysprof_display_class_init (SysprofDisplayClass *klass)
 
   widget_class->parent_set = sysprof_display_parent_set;
 
+  properties [PROP_CAN_REPLAY] =
+    g_param_spec_boolean ("can-replay",
+                          "Can Replay",
+                          "If the capture contains enough information to re-run the recording",
+                          FALSE,
+                          (G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
+
   properties [PROP_CAN_SAVE] =
     g_param_spec_boolean ("can-save",
                           "Can Save",
@@ -593,3 +607,22 @@ _sysprof_display_focus_record (SysprofDisplay *self)
 
   _sysprof_profiler_assistant_focus_record (priv->assistant);
 }
+
+gboolean
+sysprof_display_get_can_replay (SysprofDisplay *self)
+{
+  SysprofDisplayPrivate *priv = sysprof_display_get_instance_private (self);
+
+  g_return_val_if_fail (SYSPROF_IS_DISPLAY (self), FALSE);
+
+  return !sysprof_display_is_empty (self) &&
+          sysprof_capture_view_get_can_replay (priv->capture_view);
+}
+
+SysprofDisplay *
+sysprof_display_replay (SysprofDisplay *self)
+{
+  g_return_val_if_fail (SYSPROF_IS_DISPLAY (self), NULL);
+
+  return NULL;
+}
diff --git a/src/libsysprof-ui/sysprof-display.h b/src/libsysprof-ui/sysprof-display.h
index fbfc697..190f536 100644
--- a/src/libsysprof-ui/sysprof-display.h
+++ b/src/libsysprof-ui/sysprof-display.h
@@ -57,5 +57,9 @@ SYSPROF_AVAILABLE_IN_ALL
 gboolean         sysprof_display_get_can_save   (SysprofDisplay *self);
 SYSPROF_AVAILABLE_IN_ALL
 void             sysprof_display_stop_recording (SysprofDisplay *self);
+SYSPROF_AVAILABLE_IN_ALL
+gboolean         sysprof_display_get_can_replay (SysprofDisplay *self);
+SYSPROF_AVAILABLE_IN_ALL
+SysprofDisplay  *sysprof_display_replay         (SysprofDisplay *self);
 
 G_END_DECLS
diff --git a/src/libsysprof-ui/sysprof-notebook.c b/src/libsysprof-ui/sysprof-notebook.c
index d1267b9..038bd3c 100644
--- a/src/libsysprof-ui/sysprof-notebook.c
+++ b/src/libsysprof-ui/sysprof-notebook.c
@@ -31,6 +31,7 @@ G_DEFINE_TYPE (SysprofNotebook, sysprof_notebook, GTK_TYPE_NOTEBOOK)
 
 enum {
   PROP_0,
+  PROP_CAN_REPLAY,
   PROP_CAN_SAVE,
   PROP_CURRENT,
   N_PROPS
@@ -64,6 +65,17 @@ sysprof_notebook_notify_can_save_cb (SysprofNotebook *self,
   g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_CAN_SAVE]);
 }
 
+static void
+sysprof_notebook_notify_can_replay_cb (SysprofNotebook *self,
+                                       GParamSpec      *pspec,
+                                       SysprofDisplay  *display)
+{
+  g_assert (SYSPROF_IS_NOTEBOOK (self));
+  g_assert (SYSPROF_IS_DISPLAY (display));
+
+  g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_CAN_REPLAY]);
+}
+
 static void
 sysprof_notebook_page_added (GtkNotebook *notebook,
                              GtkWidget   *child,
@@ -82,12 +94,19 @@ sysprof_notebook_page_added (GtkNotebook *notebook,
       gtk_notebook_set_tab_label (notebook, child, tab);
       gtk_notebook_set_tab_reorderable (notebook, child, TRUE);
 
+      g_signal_connect_object (child,
+                               "notify::can-replay",
+                               G_CALLBACK (sysprof_notebook_notify_can_replay_cb),
+                               notebook,
+                               G_CONNECT_SWAPPED);
+
       g_signal_connect_object (child,
                                "notify::can-save",
                                G_CALLBACK (sysprof_notebook_notify_can_save_cb),
                                notebook,
                                G_CONNECT_SWAPPED);
 
+      g_object_notify_by_pspec (G_OBJECT (notebook), properties [PROP_CAN_REPLAY]);
       g_object_notify_by_pspec (G_OBJECT (notebook), properties [PROP_CAN_SAVE]);
       g_object_notify_by_pspec (G_OBJECT (notebook), properties [PROP_CURRENT]);
 
@@ -116,6 +135,7 @@ sysprof_notebook_page_removed (GtkNotebook *notebook,
                                             G_CALLBACK (sysprof_notebook_notify_can_save_cb),
                                             notebook);
 
+      g_object_notify_by_pspec (G_OBJECT (notebook), properties [PROP_CAN_REPLAY]);
       g_object_notify_by_pspec (G_OBJECT (notebook), properties [PROP_CAN_SAVE]);
       g_object_notify_by_pspec (G_OBJECT (notebook), properties [PROP_CURRENT]);
     }
@@ -134,6 +154,7 @@ sysprof_notebook_switch_page (GtkNotebook *notebook,
 
   GTK_NOTEBOOK_CLASS (sysprof_notebook_parent_class)->switch_page (notebook, widget, page);
 
+  g_object_notify_by_pspec (G_OBJECT (notebook), properties [PROP_CAN_REPLAY]);
   g_object_notify_by_pspec (G_OBJECT (notebook), properties [PROP_CAN_SAVE]);
   g_object_notify_by_pspec (G_OBJECT (notebook), properties [PROP_CURRENT]);
 }
@@ -148,6 +169,10 @@ sysprof_notebook_get_property (GObject    *object,
 
   switch (prop_id)
     {
+    case PROP_CAN_REPLAY:
+      g_value_set_boolean (value, sysprof_notebook_get_can_replay (self));
+      break;
+
     case PROP_CAN_SAVE:
       g_value_set_boolean (value, sysprof_notebook_get_can_save (self));
       break;
@@ -173,6 +198,13 @@ sysprof_notebook_class_init (SysprofNotebookClass *klass)
   notebook_class->page_removed = sysprof_notebook_page_removed;
   notebook_class->switch_page = sysprof_notebook_switch_page;
 
+  properties [PROP_CAN_REPLAY] =
+    g_param_spec_boolean ("can-replay",
+                          "Can Replay",
+                          "If the current display can replay a recording",
+                          FALSE,
+                          (G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
+
   properties [PROP_CAN_SAVE] =
     g_param_spec_boolean ("can-save",
                           "Can Save",
@@ -293,3 +325,34 @@ sysprof_notebook_get_can_save (SysprofNotebook *self)
 
   return FALSE;
 }
+
+gboolean
+sysprof_notebook_get_can_replay (SysprofNotebook *self)
+{
+  SysprofDisplay *display;
+
+  g_return_val_if_fail (SYSPROF_IS_NOTEBOOK (self), FALSE);
+
+  if ((display = sysprof_notebook_get_current (self)))
+    return sysprof_display_get_can_replay (display);
+
+  return FALSE;
+}
+
+void
+sysprof_notebook_replay (SysprofNotebook *self)
+{
+  SysprofDisplay *display;
+  SysprofDisplay *replay;
+
+  g_return_if_fail (SYSPROF_IS_NOTEBOOK (self));
+
+  if (!(display = sysprof_notebook_get_current (self)) ||
+      !sysprof_display_get_can_replay (display) ||
+      !(replay = sysprof_display_replay (display)))
+    return;
+
+  g_return_if_fail (SYSPROF_IS_DISPLAY (replay));
+
+  gtk_container_add (GTK_CONTAINER (self), GTK_WIDGET (replay));
+}
diff --git a/src/libsysprof-ui/sysprof-notebook.h b/src/libsysprof-ui/sysprof-notebook.h
index ebf68c9..36aa1fe 100644
--- a/src/libsysprof-ui/sysprof-notebook.h
+++ b/src/libsysprof-ui/sysprof-notebook.h
@@ -41,17 +41,21 @@ struct _SysprofNotebookClass
 };
 
 SYSPROF_AVAILABLE_IN_ALL
-GtkWidget      *sysprof_notebook_new           (void);
+GtkWidget      *sysprof_notebook_new            (void);
 SYSPROF_AVAILABLE_IN_ALL
-SysprofDisplay *sysprof_notebook_get_current   (SysprofNotebook *self);
+SysprofDisplay *sysprof_notebook_get_current    (SysprofNotebook *self);
 SYSPROF_AVAILABLE_IN_ALL
-void            sysprof_notebook_close_current (SysprofNotebook *self);
+void            sysprof_notebook_close_current  (SysprofNotebook *self);
 SYSPROF_AVAILABLE_IN_ALL
-void            sysprof_notebook_open          (SysprofNotebook *self,
-                                                GFile           *file);
+void            sysprof_notebook_open           (SysprofNotebook *self,
+                                                 GFile           *file);
 SYSPROF_AVAILABLE_IN_ALL
-void            sysprof_notebook_save          (SysprofNotebook *self);
+void            sysprof_notebook_save           (SysprofNotebook *self);
 SYSPROF_AVAILABLE_IN_ALL
-gboolean        sysprof_notebook_get_can_save  (SysprofNotebook *self);
+gboolean        sysprof_notebook_get_can_save   (SysprofNotebook *self);
+SYSPROF_AVAILABLE_IN_ALL
+void            sysprof_notebook_replay         (SysprofNotebook *self);
+SYSPROF_AVAILABLE_IN_ALL
+gboolean        sysprof_notebook_get_can_replay (SysprofNotebook *self);
 
 G_END_DECLS
diff --git a/src/sysprof/gtk/menus.ui b/src/sysprof/gtk/menus.ui
index d267eeb..3e0a61f 100644
--- a/src/sysprof/gtk/menus.ui
+++ b/src/sysprof/gtk/menus.ui
@@ -25,6 +25,13 @@
         <attribute name="accel">&lt;primary&gt;s</attribute>
       </item>
     </section>
+    <section id="win-menu-replay">
+      <item>
+        <attribute name="label" translatable="yes">Record Again</attribute>
+        <attribute name="action">win.replay-capture</attribute>
+        <attribute name="accel">&lt;primary&gt;r</attribute>
+      </item>
+    </section>
     <section id="win-menu-close">
       <item>
         <attribute name="label" translatable="yes">Close</attribute>
diff --git a/src/sysprof/sysprof-application.c b/src/sysprof/sysprof-application.c
index ae0f996..421961a 100644
--- a/src/sysprof/sysprof-application.c
+++ b/src/sysprof/sysprof-application.c
@@ -44,6 +44,7 @@ struct {
   { "zoom.zoom-one",      { "<Primary>0", "<Primary>KP_0", NULL } },
   { "win.new-tab",        { "<Primary>t", NULL } },
   { "win.close-tab",      { "<Primary>w", NULL } },
+  { "win.replay-capture", { "<Primary>r", NULL } },
   { "win.save-capture",   { "<Primary>s", NULL } },
   { "win.switch-tab(1)",  { "<Alt>1", NULL } },
   { "win.switch-tab(2)",  { "<Alt>2", NULL } },
diff --git a/src/sysprof/sysprof-window.c b/src/sysprof/sysprof-window.c
index 85cf4be..a861acf 100644
--- a/src/sysprof/sysprof-window.c
+++ b/src/sysprof/sysprof-window.c
@@ -54,6 +54,19 @@ sysprof_window_new (SysprofApplication *application)
                        NULL);
 }
 
+static void
+sysprof_window_notify_can_replay_cb (SysprofWindow   *self,
+                                     GParamSpec      *pspec,
+                                     SysprofNotebook *notebook)
+{
+  g_assert (SYSPROF_IS_WINDOW (self));
+  g_assert (SYSPROF_IS_NOTEBOOK (notebook));
+
+  dzl_gtk_widget_action_set (GTK_WIDGET (self), "win", "replay-capture",
+                             "enabled", sysprof_notebook_get_can_replay (notebook),
+                             NULL);
+}
+
 static void
 sysprof_window_notify_can_save_cb (SysprofWindow   *self,
                                    GParamSpec      *pspec,
@@ -121,15 +134,23 @@ close_tab_cb (GSimpleAction *action,
   sysprof_notebook_close_current (self->notebook);
 }
 
+static void
+replay_capture_cb (GSimpleAction *action,
+                   GVariant      *param,
+                   gpointer       user_data)
+{
+  SysprofWindow *self = user_data;
+  g_return_if_fail (SYSPROF_IS_WINDOW (self));
+  sysprof_notebook_replay (self->notebook);
+}
+
 static void
 save_capture_cb (GSimpleAction *action,
                  GVariant      *param,
                  gpointer       user_data)
 {
   SysprofWindow *self = user_data;
-
   g_return_if_fail (SYSPROF_IS_WINDOW (self));
-
   sysprof_notebook_save (self->notebook);
 }
 
@@ -184,6 +205,7 @@ sysprof_window_init (SysprofWindow *self)
     { "close-tab", close_tab_cb },
     { "new-tab", new_tab_cb },
     { "switch-tab", switch_tab_cb, "i" },
+    { "replay-capture", replay_capture_cb },
     { "save-capture", save_capture_cb },
     { "stop-recording", stop_recording_cb },
   };
@@ -195,6 +217,12 @@ sysprof_window_init (SysprofWindow *self)
                                    G_N_ELEMENTS (actions),
                                    self);
 
+  g_signal_connect_object (self->notebook,
+                           "notify::can-replay",
+                           G_CALLBACK (sysprof_window_notify_can_replay_cb),
+                           self,
+                           G_CONNECT_SWAPPED);
+
   g_signal_connect_object (self->notebook,
                            "notify::can-save",
                            G_CALLBACK (sysprof_window_notify_can_save_cb),
@@ -216,6 +244,9 @@ sysprof_window_init (SysprofWindow *self)
   dzl_gtk_widget_action_set (GTK_WIDGET (self), "win", "save-capture",
                              "enabled", FALSE,
                              NULL);
+  dzl_gtk_widget_action_set (GTK_WIDGET (self), "win", "replay-capture",
+                             "enabled", FALSE,
+                             NULL);
 }
 
 void


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]