[gnome-builder/wip/chergert/bug1] debugger: more breakpoints plumbing for gutter/debug-manager
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-builder/wip/chergert/bug1] debugger: more breakpoints plumbing for gutter/debug-manager
- Date: Thu, 31 Aug 2017 00:45:58 +0000 (UTC)
commit c1d5f124f88a1f50b4790560adc3f95778ad9240
Author: Christian Hergert <chergert redhat com>
Date: Wed Aug 30 17:45:45 2017 -0700
debugger: more breakpoints plumbing for gutter/debug-manager
libide/debugger/ide-debug-manager.c | 150 ++++++++++++++++++++--
libide/debugger/ide-debug-manager.h | 2 +-
libide/debugger/ide-debugger-breakpoint.c | 3 +
libide/debugger/ide-debugger-breakpoints.c | 118 ++++++++++++++++-
libide/debugger/ide-debugger-breakpoints.h | 11 +-
libide/debugger/ide-debugger-editor-view-addin.c | 33 +++++-
libide/debugger/ide-debugger-gutter-renderer.c | 144 +++++++++++++++++----
libide/debugger/ide-debugger-gutter-renderer.h | 3 +-
libide/debugger/ide-debugger-private.h | 10 +-
libide/ide.h | 1 +
libide/meson.build | 4 +-
11 files changed, 423 insertions(+), 56 deletions(-)
---
diff --git a/libide/debugger/ide-debug-manager.c b/libide/debugger/ide-debug-manager.c
index adcd68a..94f079f 100644
--- a/libide/debugger/ide-debug-manager.c
+++ b/libide/debugger/ide-debug-manager.c
@@ -131,10 +131,8 @@ ide_debug_manager_breakpoint_added (IdeDebugManager *self,
IdeDebugger *debugger)
{
IdeDebuggerBreakpoints *breakpoints;
- IdeDebuggerBreakMode mode;
g_autoptr(GFile) file = NULL;
const gchar *path;
- guint line;
g_assert (IDE_IS_DEBUG_MANAGER (self));
g_assert (IDE_IS_DEBUGGER_BREAKPOINT (breakpoint));
@@ -146,9 +144,7 @@ ide_debug_manager_breakpoint_added (IdeDebugManager *self,
return;
file = g_file_new_for_path (path);
-
breakpoints = g_hash_table_lookup (self->breakpoints, file);
-
if (breakpoints == NULL)
{
breakpoints = g_object_new (IDE_TYPE_DEBUGGER_BREAKPOINTS,
@@ -157,10 +153,7 @@ ide_debug_manager_breakpoint_added (IdeDebugManager *self,
g_hash_table_insert (self->breakpoints, g_steal_pointer (&file), breakpoints);
}
- mode = ide_debugger_breakpoint_get_mode (breakpoint);
- line = ide_debugger_breakpoint_get_line (breakpoint);
-
- ide_debugger_breakpoints_set_line (breakpoints, line, mode);
+ _ide_debugger_breakpoints_add (breakpoints, breakpoint);
}
static void
@@ -171,7 +164,6 @@ ide_debug_manager_breakpoint_removed (IdeDebugManager *self,
IdeDebuggerBreakpoints *breakpoints;
g_autoptr(GFile) file = NULL;
const gchar *path;
- guint line;
g_assert (IDE_IS_DEBUG_MANAGER (self));
g_assert (IDE_IS_DEBUGGER_BREAKPOINT (breakpoint));
@@ -181,12 +173,12 @@ ide_debug_manager_breakpoint_removed (IdeDebugManager *self,
if (path == NULL)
return;
- line = ide_debugger_breakpoint_get_line (breakpoint);
file = g_file_new_for_path (path);
-
breakpoints = g_hash_table_lookup (self->breakpoints, file);
- if (breakpoints != NULL)
- ide_debugger_breakpoints_set_line (breakpoints, line, IDE_DEBUGGER_BREAK_NONE);
+ if (breakpoints == NULL)
+ return;
+
+ _ide_debugger_breakpoints_remove (breakpoints, breakpoint);
}
static void
@@ -488,3 +480,135 @@ ide_debug_manager_get_debugger (IdeDebugManager *self)
return self->debugger;
}
+
+/**
+ * ide_debug_manager_get_breakpoints_for_file:
+ *
+ * This returns an #IdeDebuggerBreakpoints that represents the breakpoints
+ * within a given file.
+ *
+ * This inderect breakpoints container provides a very fast way to check if
+ * a line has a breakpoint set. You want to use this when performance really
+ * matters such as from the gutter of the source editor.
+ *
+ * Breakpoints contained in the resulting structure will automatically
+ * propagate to the debugger when the debugger has been successfully spawned.
+ *
+ * Returns: (transfer full): An #IdeDebuggerBreakpoints
+ */
+IdeDebuggerBreakpoints *
+ide_debug_manager_get_breakpoints_for_file (IdeDebugManager *self,
+ GFile *file)
+{
+ IdeDebuggerBreakpoints *breakpoints;
+
+ g_return_val_if_fail (IDE_IS_DEBUG_MANAGER (self), NULL);
+ g_return_val_if_fail (G_IS_FILE (file), NULL);
+
+ breakpoints = g_hash_table_lookup (self->breakpoints, file);
+
+ if (breakpoints == NULL)
+ {
+ breakpoints = g_object_new (IDE_TYPE_DEBUGGER_BREAKPOINTS,
+ "file", file,
+ NULL);
+ g_hash_table_insert (self->breakpoints, g_object_ref (file), breakpoints);
+ }
+
+ return g_object_ref (breakpoints);
+}
+
+/**
+ * _ide_debug_manager_add_breakpoint:
+ * @self: An #IdeDebugManager
+ * @breakpoint: An #IdeDebuggerBreakpoint
+ *
+ * This adds a new breakpoint. If the debugger has been started, it
+ * is done by notifying the debugger to add the breakpoint. If there is
+ * not an active debugger, then it is done by caching the breakpoint
+ * until the debugger is next started.
+ *
+ * Since: 3.26
+ */
+void
+_ide_debug_manager_add_breakpoint (IdeDebugManager *self,
+ IdeDebuggerBreakpoint *breakpoint)
+{
+ g_autoptr(IdeDebuggerBreakpoints) breakpoints = NULL;
+ g_autoptr(GFile) file = NULL;
+ const gchar *path;
+
+ IDE_ENTRY;
+
+ g_return_if_fail (IDE_IS_DEBUG_MANAGER (self));
+ g_return_if_fail (IDE_IS_DEBUGGER_BREAKPOINT (breakpoint));
+
+ if (self->debugger != NULL)
+ {
+ ide_debugger_insert_breakpoint_async (self->debugger, breakpoint, NULL, NULL, NULL);
+ IDE_EXIT;
+ }
+
+ path = ide_debugger_breakpoint_get_file (breakpoint);
+
+ if (path == NULL)
+ {
+ /* We don't know where this breakpoint is because it's either an
+ * address, function, expression, etc. So we just need to queue
+ * it until the debugger starts.
+ */
+TODO:
+ IDE_EXIT;
+ }
+
+ file = g_file_new_for_path (path);
+ breakpoints = ide_debug_manager_get_breakpoints_for_file (self, file);
+ _ide_debugger_breakpoints_add (breakpoints, breakpoint);
+
+ IDE_EXIT;
+}
+
+/**
+ * _ide_debug_manager_remove_breakpoint:
+ * @self: An #IdeDebugManager
+ * @breakpoint: An #IdeDebuggerBreakpoint
+ *
+ * This removes an exiting breakpoint. If the debugger has been started, it
+ * is done by notifying the debugger to remove the breakpoint. If there is
+ * not an active debugger, then it is done by removing the cached breakpoint.
+ *
+ * Since: 3.26
+ */
+void
+_ide_debug_manager_remove_breakpoint (IdeDebugManager *self,
+ IdeDebuggerBreakpoint *breakpoint)
+{
+ g_autoptr(GFile) file = NULL;
+ IdeDebuggerBreakpoints *breakpoints;
+ const gchar *path;
+
+ IDE_ENTRY;
+
+ g_return_if_fail (IDE_IS_DEBUG_MANAGER (self));
+ g_return_if_fail (IDE_IS_DEBUGGER_BREAKPOINT (breakpoint));
+
+ if (self->debugger != NULL)
+ {
+ /* Just ask the debugger to remove it, we'll update the breakpoints
+ * list when we get the #IdeDebugger::breakpoint-removed signal.
+ */
+ ide_debugger_remove_breakpoint_async (self->debugger, breakpoint, NULL, NULL, NULL);
+ IDE_EXIT;
+ }
+
+ /* Nothing we can do if this is a memory address-based breakpoint */
+ if (NULL == (path = ide_debugger_breakpoint_get_file (breakpoint)))
+ IDE_EXIT;
+
+ file = g_file_new_for_path (path);
+ breakpoints = g_hash_table_lookup (self->breakpoints, file);
+ if (breakpoints != NULL)
+ _ide_debugger_breakpoints_remove (breakpoints, breakpoint);
+
+ IDE_EXIT;
+}
diff --git a/libide/debugger/ide-debug-manager.h b/libide/debugger/ide-debug-manager.h
index 076d4df..be7e0ec 100644
--- a/libide/debugger/ide-debug-manager.h
+++ b/libide/debugger/ide-debug-manager.h
@@ -20,7 +20,7 @@
#include "ide-object.h"
-#include "ide-debugger-breakpoints.h"
+#include "debugger/ide-debugger-breakpoints.h"
G_BEGIN_DECLS
diff --git a/libide/debugger/ide-debugger-breakpoint.c b/libide/debugger/ide-debugger-breakpoint.c
index bbe57ea..27cbdbf 100644
--- a/libide/debugger/ide-debugger-breakpoint.c
+++ b/libide/debugger/ide-debugger-breakpoint.c
@@ -386,6 +386,9 @@ ide_debugger_breakpoint_class_init (IdeDebuggerBreakpointClass *klass)
static void
ide_debugger_breakpoint_init (IdeDebuggerBreakpoint *self)
{
+ IdeDebuggerBreakpointPrivate *priv = ide_debugger_breakpoint_get_instance_private (self);
+
+ priv->mode = IDE_DEBUGGER_BREAK_BREAKPOINT;
}
IdeDebuggerBreakpoint *
diff --git a/libide/debugger/ide-debugger-breakpoints.c b/libide/debugger/ide-debugger-breakpoints.c
index 07a7e91..74f3021 100644
--- a/libide/debugger/ide-debugger-breakpoints.c
+++ b/libide/debugger/ide-debugger-breakpoints.c
@@ -23,6 +23,7 @@
#include "ide-debug.h"
#include "debugger/ide-debugger-breakpoints.h"
+#include "debugger/ide-debugger-private.h"
/**
* SECTION:ide-debugger-breakpoints
@@ -184,10 +185,44 @@ ide_debugger_breakpoints_init (IdeDebuggerBreakpoints *self)
{
}
-IdeDebuggerBreakMode
+/**
+ * ide_debugger_breakpoints_get_line:
+ * @self: An #IdeDebuggerBreakpoints
+ * @line: The line number
+ *
+ * Gets the breakpoint that has been registered at a given line, or %NULL
+ * if no breakpoint is registered there.
+ *
+ * Returns: (nullable) (transfer none): An #IdeDebuggerBreakpoint or %NULL
+ *
+ * Since: 3.26
+ */
+IdeDebuggerBreakpoint *
ide_debugger_breakpoints_get_line (IdeDebuggerBreakpoints *self,
guint line)
{
+ g_return_val_if_fail (IDE_IS_DEBUGGER_BREAKPOINTS (self), NULL);
+
+ if (self->lines != NULL)
+ {
+ LineInfo info = { line, 0 };
+ LineInfo *ret;
+
+ ret = bsearch (&info, (gpointer)self->lines->data,
+ self->lines->len, sizeof (LineInfo),
+ line_info_compare);
+
+ if (ret)
+ return ret->breakpoint;
+ }
+
+ return NULL;
+}
+
+IdeDebuggerBreakMode
+ide_debugger_breakpoints_get_line_mode (IdeDebuggerBreakpoints *self,
+ guint line)
+{
g_return_val_if_fail (IDE_IS_DEBUGGER_BREAKPOINTS (self), 0);
if (self->lines != NULL)
@@ -206,14 +241,18 @@ ide_debugger_breakpoints_get_line (IdeDebuggerBreakpoints *self,
return 0;
}
-void
+static void
ide_debugger_breakpoints_set_line (IdeDebuggerBreakpoints *self,
guint line,
- IdeDebuggerBreakMode mode)
+ IdeDebuggerBreakMode mode,
+ IdeDebuggerBreakpoint *breakpoint)
{
LineInfo info;
- g_return_if_fail (IDE_IS_DEBUGGER_BREAKPOINTS (self));
+ g_assert (IDE_IS_DEBUGGER_BREAKPOINTS (self));
+ g_assert (IDE_IS_DEBUGGER_BREAK_MODE (mode));
+ g_assert (!breakpoint || IDE_IS_DEBUGGER_BREAKPOINT (breakpoint));
+ g_assert (mode == IDE_DEBUGGER_BREAK_NONE || breakpoint != NULL);
if (self->lines != NULL)
{
@@ -223,15 +262,20 @@ ide_debugger_breakpoints_set_line (IdeDebuggerBreakpoints *self,
if (ele->line == line)
{
- if (mode != 0)
- ele->mode = mode;
+ if (mode != IDE_DEBUGGER_BREAK_NONE)
+ {
+ ele->mode = mode;
+ g_set_object (&ele->breakpoint, breakpoint);
+ }
else
g_array_remove_index (self->lines, i);
+
goto emit_signal;
}
}
}
+ /* Nothing to do here */
if (mode == IDE_DEBUGGER_BREAK_NONE)
return;
@@ -243,6 +287,7 @@ ide_debugger_breakpoints_set_line (IdeDebuggerBreakpoints *self,
info.line = line;
info.mode = mode;
+ info.breakpoint = g_object_ref (breakpoint);
g_array_append_val (self->lines, info);
g_array_sort (self->lines, line_info_compare);
@@ -250,3 +295,64 @@ ide_debugger_breakpoints_set_line (IdeDebuggerBreakpoints *self,
emit_signal:
g_signal_emit (self, signals [CHANGED], 0);
}
+
+void
+_ide_debugger_breakpoints_add (IdeDebuggerBreakpoints *self,
+ IdeDebuggerBreakpoint *breakpoint)
+{
+ IdeDebuggerBreakMode mode;
+ guint line;
+
+ IDE_ENTRY;
+
+ g_return_if_fail (IDE_IS_DEBUGGER_BREAKPOINTS (self));
+ g_return_if_fail (IDE_IS_DEBUGGER_BREAKPOINT (breakpoint));
+
+ line = ide_debugger_breakpoint_get_line (breakpoint);
+ mode = ide_debugger_breakpoint_get_mode (breakpoint);
+
+ IDE_TRACE_MSG ("tracking breakpoint at line %d [breakpoints=%p]",
+ line, self);
+
+ ide_debugger_breakpoints_set_line (self, line, mode, breakpoint);
+
+ IDE_EXIT;
+}
+
+void
+_ide_debugger_breakpoints_remove (IdeDebuggerBreakpoints *self,
+ IdeDebuggerBreakpoint *breakpoint)
+{
+ guint line;
+
+ IDE_ENTRY;
+
+ g_return_if_fail (IDE_IS_DEBUGGER_BREAKPOINTS (self));
+ g_return_if_fail (IDE_IS_DEBUGGER_BREAKPOINT (breakpoint));
+
+ line = ide_debugger_breakpoint_get_line (breakpoint);
+
+ IDE_TRACE_MSG ("removing breakpoint at line %d [breakpoints=%p]",
+ line, self);
+
+ ide_debugger_breakpoints_set_line (self, line, IDE_DEBUGGER_BREAK_NONE, NULL);
+
+ IDE_EXIT;
+}
+
+/**
+ * ide_debugger_breakpoints_get_file:
+ * @self: An #IdeDebuggerBreakpoints
+ *
+ * Gets the "file" property, which is the file that breakpoints within
+ * this container belong to.
+ *
+ * Returns: (transfer none): A #GFile
+ */
+GFile *
+ide_debugger_breakpoints_get_file (IdeDebuggerBreakpoints *self)
+{
+ g_return_val_if_fail (IDE_IS_DEBUGGER_BREAKPOINTS (self), NULL);
+
+ return self->file;
+}
diff --git a/libide/debugger/ide-debugger-breakpoints.h b/libide/debugger/ide-debugger-breakpoints.h
index 1db82c4..d15bb03 100644
--- a/libide/debugger/ide-debugger-breakpoints.h
+++ b/libide/debugger/ide-debugger-breakpoints.h
@@ -20,6 +20,7 @@
#include <glib-object.h>
+#include "ide-debugger-breakpoint.h"
#include "ide-debugger-types.h"
G_BEGIN_DECLS
@@ -28,10 +29,10 @@ G_BEGIN_DECLS
G_DECLARE_FINAL_TYPE (IdeDebuggerBreakpoints, ide_debugger_breakpoints, IDE, DEBUGGER_BREAKPOINTS, GObject)
-IdeDebuggerBreakMode ide_debugger_breakpoints_get_line (IdeDebuggerBreakpoints *self,
- guint line);
-void ide_debugger_breakpoints_set_line (IdeDebuggerBreakpoints *self,
- guint line,
- IdeDebuggerBreakMode mode);
+GFile *ide_debugger_breakpoints_get_file (IdeDebuggerBreakpoints *self);
+IdeDebuggerBreakMode ide_debugger_breakpoints_get_line_mode (IdeDebuggerBreakpoints *self,
+ guint line);
+IdeDebuggerBreakpoint *ide_debugger_breakpoints_get_line (IdeDebuggerBreakpoints *self,
+ guint line);
G_END_DECLS
diff --git a/libide/debugger/ide-debugger-editor-view-addin.c
b/libide/debugger/ide-debugger-editor-view-addin.c
index 38762b0..da21d5d 100644
--- a/libide/debugger/ide-debugger-editor-view-addin.c
+++ b/libide/debugger/ide-debugger-editor-view-addin.c
@@ -18,8 +18,14 @@
#define G_LOG_DOMAIN "ide-debugger-editor-view-addin"
+#include "ide-context.h"
+#include "ide-debug.h"
+
+#include "debugger/ide-debug-manager.h"
#include "debugger/ide-debugger-editor-view-addin.h"
#include "debugger/ide-debugger-gutter-renderer.h"
+#include "files/ide-file.h"
+#include "util/ide-gtk.h"
struct _IdeDebuggerEditorViewAddin
{
@@ -35,25 +41,42 @@ ide_debugger_editor_view_addin_load (IdeEditorViewAddin *addin,
{
IdeDebuggerEditorViewAddin *self = (IdeDebuggerEditorViewAddin *)addin;
g_autoptr(IdeDebuggerBreakpoints) breakpoints = NULL;
+ IdeDebugManager *debug_manager;
IdeSourceView *source_view;
GtkSourceGutter *gutter;
+ IdeContext *context;
+ IdeBuffer *buffer;
+ IdeFile *file;
+ GFile *gfile;
+
+ IDE_ENTRY;
g_assert (IDE_IS_DEBUGGER_EDITOR_VIEW_ADDIN (self));
g_assert (IDE_IS_EDITOR_VIEW (view));
self->view = view;
- /* TODO: Wire up breakpoints to debugger instance for this file */
- breakpoints = g_object_new (IDE_TYPE_DEBUGGER_BREAKPOINTS, NULL);
+ context = ide_widget_get_context (GTK_WIDGET (view));
+ debug_manager = ide_context_get_debug_manager (context);
+
+ buffer = ide_editor_view_get_buffer (view);
+ file = ide_buffer_get_file (buffer);
+ gfile = ide_file_get_file (file);
/* Install the breakpoints gutter */
+ breakpoints = ide_debug_manager_get_breakpoints_for_file (debug_manager, gfile);
source_view = ide_editor_view_get_view (view);
gutter = gtk_source_view_get_gutter (GTK_SOURCE_VIEW (source_view), GTK_TEXT_WINDOW_LEFT);
self->renderer = g_object_new (IDE_TYPE_DEBUGGER_GUTTER_RENDERER,
+ "debug-manager", debug_manager,
+ "breakpoints", breakpoints,
"size", 16,
NULL);
- ide_debugger_gutter_renderer_set_breakpoints (self->renderer, breakpoints);
gtk_source_gutter_insert (gutter, GTK_SOURCE_GUTTER_RENDERER (self->renderer), -100);
+
+ /* TODO: Monitor IdeBuffer:file? */
+
+ IDE_EXIT;
}
static void
@@ -64,6 +87,8 @@ ide_debugger_editor_view_addin_unload (IdeEditorViewAddin *addin,
IdeSourceView *source_view;
GtkSourceGutter *gutter;
+ IDE_ENTRY;
+
g_assert (IDE_IS_DEBUGGER_EDITOR_VIEW_ADDIN (self));
g_assert (IDE_IS_EDITOR_VIEW (view));
@@ -73,6 +98,8 @@ ide_debugger_editor_view_addin_unload (IdeEditorViewAddin *addin,
self->renderer = NULL;
self->view = NULL;
+
+ IDE_EXIT;
}
static void
diff --git a/libide/debugger/ide-debugger-gutter-renderer.c b/libide/debugger/ide-debugger-gutter-renderer.c
index 89d3aac..ae1aa27 100644
--- a/libide/debugger/ide-debugger-gutter-renderer.c
+++ b/libide/debugger/ide-debugger-gutter-renderer.c
@@ -22,13 +22,28 @@
#include "ide-debug.h"
-#include "debugger/ide-debugger-gutter-renderer.h"
+#include "debugger/ide-debug-manager.h"
#include "debugger/ide-debugger-breakpoints.h"
+#include "debugger/ide-debugger-gutter-renderer.h"
+#include "debugger/ide-debugger-private.h"
+
+/**
+ * SECTION:ide-debugger-gutter-renderer
+ * @title: IdeDebuggerGutterRenderer
+ * @short_description: A gutter for debugger breakpoints
+ *
+ * The #IdeDebuggerGutterRenderer is used to show the breakpoints
+ * within the gutter of a source editor. When clicking on a row, you
+ * can set a breakpoint on the line as well.
+ *
+ * Since: 3.26
+ */
struct _IdeDebuggerGutterRenderer
{
GtkSourceGutterRendererPixbuf parent_instance;
IdeDebuggerBreakpoints *breakpoints;
+ IdeDebugManager *debug_manager;
gulong breakpoints_changed_handler;
};
@@ -37,6 +52,7 @@ G_DEFINE_TYPE (IdeDebuggerGutterRenderer, ide_debugger_gutter_renderer, GTK_SOUR
enum {
PROP_0,
PROP_BREAKPOINTS,
+ PROP_DEBUG_MANAGER,
N_PROPS
};
@@ -48,40 +64,65 @@ ide_debugger_gutter_renderer_activate (IdeDebuggerGutterRenderer *self,
GdkRectangle *area,
GdkEvent *event)
{
- IdeDebuggerBreakMode break_type;
+ IdeDebuggerBreakpoint *breakpoint;
+ IdeDebuggerBreakMode break_type = IDE_DEBUGGER_BREAK_NONE;
+ g_autofree gchar *path = NULL;
+ GFile *file;
guint line;
IDE_ENTRY;
g_assert (IDE_IS_DEBUGGER_GUTTER_RENDERER (self));
+ g_assert (self->breakpoints != NULL);
+ g_assert (self->debug_manager != NULL);
g_assert (iter != NULL);
g_assert (area != NULL);
g_assert (event != NULL);
line = gtk_text_iter_get_line (iter) + 1;
+ file = ide_debugger_breakpoints_get_file (self->breakpoints);
+ path = g_file_get_path (file);
- IDE_TRACE_MSG ("Toggle breakpoint on line %u", line);
+ /* TODO: Should we show a Popover here to select the type? */
+ IDE_TRACE_MSG ("Toggle breakpoint on line %u [breakpoints=%p]",
+ line, self->breakpoints);
- break_type = ide_debugger_breakpoints_get_line (self->breakpoints, line);
+ breakpoint = ide_debugger_breakpoints_get_line (self->breakpoints, line);
+ if (breakpoint != NULL)
+ break_type = ide_debugger_breakpoint_get_mode (breakpoint);
switch (break_type)
{
case IDE_DEBUGGER_BREAK_NONE:
- /* TOOD: Register with real debug manager */
- ide_debugger_breakpoints_set_line (self->breakpoints, line, IDE_DEBUGGER_BREAK_BREAKPOINT);
+ {
+ g_autoptr(IdeDebuggerBreakpoint) to_insert = NULL;
+
+ to_insert = ide_debugger_breakpoint_new (NULL);
+ ide_debugger_breakpoint_set_line (to_insert, line);
+ ide_debugger_breakpoint_set_file (to_insert, path);
+ ide_debugger_breakpoint_set_mode (to_insert, IDE_DEBUGGER_BREAK_BREAKPOINT);
+
+ _ide_debug_manager_add_breakpoint (self->debug_manager, to_insert);
+ }
break;
case IDE_DEBUGGER_BREAK_BREAKPOINT:
case IDE_DEBUGGER_BREAK_COUNTPOINT:
case IDE_DEBUGGER_BREAK_WATCHPOINT:
- /* TOOD: Register with real debug manager */
- ide_debugger_breakpoints_set_line (self->breakpoints, line, 0);
+ if (breakpoint != NULL)
+ _ide_debug_manager_remove_breakpoint (self->debug_manager, breakpoint);
break;
default:
- break;
+ g_return_if_reached ();
}
+ /*
+ * We will wait for changes to be applied to the #IdeDebuggerBreakpoints
+ * by the #IdeDebugManager. That will cause the gutter to be invalidated
+ * and redrawn.
+ */
+
IDE_EXIT;
}
@@ -96,7 +137,7 @@ ide_debugger_gutter_renderer_query_activatable (IdeDebuggerGutterRenderer *self,
g_assert (area != NULL);
g_assert (event != NULL);
- return TRUE;
+ return self->breakpoints != NULL && self->debug_manager != NULL;
}
static void
@@ -116,7 +157,7 @@ ide_debugger_gutter_renderer_query_data (IdeDebuggerGutterRenderer *self,
return;
line = gtk_text_iter_get_line (begin) + 1;
- break_type = ide_debugger_breakpoints_get_line (self->breakpoints, line);
+ break_type = ide_debugger_breakpoints_get_line_mode (self->breakpoints, line);
/*
* These are very much a miss-appropriation of the icon, but it works
@@ -129,24 +170,29 @@ ide_debugger_gutter_renderer_query_data (IdeDebuggerGutterRenderer *self,
switch (break_type)
{
case IDE_DEBUGGER_BREAK_BREAKPOINT:
- gtk_source_gutter_renderer_pixbuf_set_icon_name (GTK_SOURCE_GUTTER_RENDERER_PIXBUF (self),
BREAKPOINT_ICON_NAME);
+ gtk_source_gutter_renderer_pixbuf_set_icon_name (GTK_SOURCE_GUTTER_RENDERER_PIXBUF (self),
+ BREAKPOINT_ICON_NAME);
break;
case IDE_DEBUGGER_BREAK_COUNTPOINT:
- gtk_source_gutter_renderer_pixbuf_set_icon_name (GTK_SOURCE_GUTTER_RENDERER_PIXBUF (self),
COUNTPOINT_ICON_NAME);
+ gtk_source_gutter_renderer_pixbuf_set_icon_name (GTK_SOURCE_GUTTER_RENDERER_PIXBUF (self),
+ COUNTPOINT_ICON_NAME);
break;
case IDE_DEBUGGER_BREAK_WATCHPOINT:
- gtk_source_gutter_renderer_pixbuf_set_icon_name (GTK_SOURCE_GUTTER_RENDERER_PIXBUF (self),
WATCHPOINT_ICON_NAME);
+ gtk_source_gutter_renderer_pixbuf_set_icon_name (GTK_SOURCE_GUTTER_RENDERER_PIXBUF (self),
+ WATCHPOINT_ICON_NAME);
break;
case IDE_DEBUGGER_BREAK_NONE:
- default:
/* Setting pixbuf to NULL via g_object_set() seems to be
* the only way to clear this without g_warning()s.
*/
g_object_set (self, "pixbuf", NULL, NULL);
break;
+
+ default:
+ g_return_if_reached ();
}
#undef BREAKPOINT_ICON_NAME
@@ -168,8 +214,8 @@ void
ide_debugger_gutter_renderer_set_breakpoints (IdeDebuggerGutterRenderer *self,
IdeDebuggerBreakpoints *breakpoints)
{
- g_return_if_fail (IDE_IS_DEBUGGER_GUTTER_RENDERER (self));
- g_return_if_fail (!breakpoints || IDE_IS_DEBUGGER_BREAKPOINTS (breakpoints));
+ g_assert (IDE_IS_DEBUGGER_GUTTER_RENDERER (self));
+ g_assert (!breakpoints || IDE_IS_DEBUGGER_BREAKPOINTS (breakpoints));
if (self->breakpoints != breakpoints)
{
@@ -196,13 +242,14 @@ ide_debugger_gutter_renderer_set_breakpoints (IdeDebuggerGutterRenderer *self,
}
static void
-ide_debugger_gutter_renderer_finalize (GObject *object)
+ide_debugger_gutter_renderer_dispose (GObject *object)
{
IdeDebuggerGutterRenderer *self = (IdeDebuggerGutterRenderer *)object;
- g_clear_object (&self->breakpoints);
+ ide_debugger_gutter_renderer_set_breakpoints (self, NULL);
+ g_clear_object (&self->debug_manager);
- G_OBJECT_CLASS (ide_debugger_gutter_renderer_parent_class)->finalize (object);
+ G_OBJECT_CLASS (ide_debugger_gutter_renderer_parent_class)->dispose (object);
}
static void
@@ -219,6 +266,10 @@ ide_debugger_gutter_renderer_get_property (GObject *object,
g_value_set_object (value, self->breakpoints);
break;
+ case PROP_DEBUG_MANAGER:
+ g_value_set_object (value, self->debug_manager);
+ break;
+
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
@@ -238,6 +289,10 @@ ide_debugger_gutter_renderer_set_property (GObject *object,
ide_debugger_gutter_renderer_set_breakpoints (self, g_value_get_object (value));
break;
+ case PROP_DEBUG_MANAGER:
+ self->debug_manager = g_value_dup_object (value);
+ break;
+
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
@@ -248,10 +303,19 @@ ide_debugger_gutter_renderer_class_init (IdeDebuggerGutterRendererClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
- object_class->finalize = ide_debugger_gutter_renderer_finalize;
+ object_class->dispose = ide_debugger_gutter_renderer_dispose;
object_class->get_property = ide_debugger_gutter_renderer_get_property;
object_class->set_property = ide_debugger_gutter_renderer_set_property;
+ /**
+ * IdeDebuggerGutterRenderer:breakpoints:
+ *
+ * The "breakpoints" property is an #IdeDebuggerBreakpoints that can be
+ * used to quickly determine if a row has a breakpoint set, and what
+ * type of breakpoint that is.
+ *
+ * Since: 3.26
+ */
properties [PROP_BREAKPOINTS] =
g_param_spec_object ("breakpoints",
"Breakpoints",
@@ -259,6 +323,21 @@ ide_debugger_gutter_renderer_class_init (IdeDebuggerGutterRendererClass *klass)
IDE_TYPE_DEBUGGER_BREAKPOINTS,
(G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+ /**
+ * IdeDebuggerGutterRenderer:debug-manager:
+ *
+ * The "debug-manager" property is the #IdeDebugManager that can be
+ * used to alter breakpoints in the debugger.
+ *
+ * Since: 3.26
+ */
+ properties [PROP_DEBUG_MANAGER] =
+ g_param_spec_object ("debug-manager",
+ "Debug Manager",
+ "Debug Manager",
+ IDE_TYPE_DEBUG_MANAGER,
+ (G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
+
g_object_class_install_properties (object_class, N_PROPS, properties);
}
@@ -281,8 +360,27 @@ ide_debugger_gutter_renderer_init (IdeDebuggerGutterRenderer *self)
NULL);
}
+/**
+ * ide_debugger_gutter_renderer_new:
+ * @debug_manager: An #IdeDebugManager
+ *
+ * Creates a new #IdeDebuggerGutterRenderer.
+ *
+ * @debug_manager should be the #IdeDebugManager for the #IdeContext of the
+ * current project. This is used to manipulate breakpoints whether or not
+ * the debugger is currently active. This allows for breakpoints to be synced
+ * after the debugger instance is spawned.
+ *
+ * Returns: (transfer full): A new #IdeDebuggerGutterRenderer.
+ *
+ * Since: 3.26
+ */
GtkSourceGutterRenderer *
-ide_debugger_gutter_renderer_new (void)
+ide_debugger_gutter_renderer_new (IdeDebugManager *debug_manager)
{
- return g_object_new (IDE_TYPE_DEBUGGER_GUTTER_RENDERER, NULL);
+ g_return_val_if_fail (IDE_IS_DEBUG_MANAGER (debug_manager), NULL);
+
+ return g_object_new (IDE_TYPE_DEBUGGER_GUTTER_RENDERER,
+ "debug-manager", debug_manager,
+ NULL);
}
diff --git a/libide/debugger/ide-debugger-gutter-renderer.h b/libide/debugger/ide-debugger-gutter-renderer.h
index dd11d35..07c0bcf 100644
--- a/libide/debugger/ide-debugger-gutter-renderer.h
+++ b/libide/debugger/ide-debugger-gutter-renderer.h
@@ -22,6 +22,7 @@
#include "ide-types.h"
+#include "debugger/ide-debug-manager.h"
#include "debugger/ide-debugger-breakpoints.h"
G_BEGIN_DECLS
@@ -30,7 +31,7 @@ G_BEGIN_DECLS
G_DECLARE_FINAL_TYPE (IdeDebuggerGutterRenderer, ide_debugger_gutter_renderer, IDE,
DEBUGGER_GUTTER_RENDERER, GtkSourceGutterRendererPixbuf)
-GtkSourceGutterRenderer *ide_debugger_gutter_renderer_new (void);
+GtkSourceGutterRenderer *ide_debugger_gutter_renderer_new (IdeDebugManager
*debug_manager);
void ide_debugger_gutter_renderer_set_breakpoints (IdeDebuggerGutterRenderer *self,
IdeDebuggerBreakpoints
*breakpoints);
diff --git a/libide/debugger/ide-debugger-private.h b/libide/debugger/ide-debugger-private.h
index fd20f5b..bc2a39b 100644
--- a/libide/debugger/ide-debugger-private.h
+++ b/libide/debugger/ide-debugger-private.h
@@ -24,8 +24,14 @@
G_BEGIN_DECLS
-IdeDebuggerBreakpoints *_ide_debug_manager_get_breakpoints (IdeDebugManager *self,
- GFile *file);
+void _ide_debug_manager_add_breakpoint (IdeDebugManager *self,
+ IdeDebuggerBreakpoint
*breakpoint);
+void _ide_debug_manager_remove_breakpoint (IdeDebugManager *self,
+ IdeDebuggerBreakpoint
*breakpoint);
+void _ide_debugger_breakpoints_add (IdeDebuggerBreakpoints *self,
+ IdeDebuggerBreakpoint
*breakpoint);
+void _ide_debugger_breakpoints_remove (IdeDebuggerBreakpoints *self,
+ IdeDebuggerBreakpoint
*breakpoint);
void _ide_debugger_class_init_actions (GActionGroupInterface *iface);
void _ide_debugger_update_actions (IdeDebugger *self);
gboolean _ide_debugger_get_has_started (IdeDebugger *self);
diff --git a/libide/ide.h b/libide/ide.h
index aa13aab..6bd8190 100644
--- a/libide/ide.h
+++ b/libide/ide.h
@@ -64,6 +64,7 @@ G_BEGIN_DECLS
#include "buildsystem/ide-environment.h"
#include "debugger/ide-debug-manager.h"
#include "debugger/ide-debugger-breakpoint.h"
+#include "debugger/ide-debugger-breakpoints.h"
#include "debugger/ide-debugger-frame.h"
#include "debugger/ide-debugger-instruction.h"
#include "debugger/ide-debugger-library.h"
diff --git a/libide/meson.build b/libide/meson.build
index 2205120..3b77ff2 100644
--- a/libide/meson.build
+++ b/libide/meson.build
@@ -87,6 +87,7 @@ libide_public_headers = [
'buildsystem/ide-environment.h',
'debugger/ide-debug-manager.h',
'debugger/ide-debugger-breakpoint.h',
+ 'debugger/ide-debugger-breakpoints.h',
'debugger/ide-debugger-frame.h',
'debugger/ide-debugger-instruction.h',
'debugger/ide-debugger-library.h',
@@ -300,6 +301,7 @@ libide_public_sources = [
'buildsystem/ide-environment.c',
'debugger/ide-debug-manager.c',
'debugger/ide-debugger-breakpoint.c',
+ 'debugger/ide-debugger-breakpoints.c',
'debugger/ide-debugger-frame.c',
'debugger/ide-debugger-instruction.c',
'debugger/ide-debugger-library.c',
@@ -518,8 +520,6 @@ libide_sources = libide_generated_headers + libide_public_sources + [
'debugger/ide-debugger-editor-view-addin.c',
'debugger/ide-debugger-editor-view-addin.h',
'debugger/ide-debugger-fallbacks.c',
- 'debugger/ide-debugger-breakpoints.c',
- 'debugger/ide-debugger-breakpoints.h',
'debugger/ide-debugger-gutter-renderer.c',
'debugger/ide-debugger-gutter-renderer.h',
'debugger/ide-debugger-libraries-view.c',
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]