libsysprof-analyze: make mark catalog work with sections

This allows us more flexibility with creating sections usin the flatten
list model as the rows need to contain the data for the headers.
This commit is contained in:
Christian Hergert
2023-06-15 13:19:18 -07:00
parent 2fb3815af3
commit 1455876835
8 changed files with 64 additions and 110 deletions

View File

@ -1456,11 +1456,13 @@ sysprof_document_list_symbols_in_traceable (SysprofDocument *self,
* sysprof_document_catalog_marks:
* @self: a #SysprofDocument
*
* Generates a catalog of marks which can be used to sort marks by
* group, then another catalog by name, which is then itself a #GListModel
* of #SysprofDocumentMark.
* Get's a #GListModel of #GListModel of #SysprofMarkCatalog.
*
* Returns: (transfer full): a #GListModel of #SysprofMarkCatalog
* You can use this to display sections in #GtkListView and similar
* using #GtkFlattenListModel.
*
* Returns: (transfer full): a #GListModel of #GListModel of
* #SysprofMarkCatalog grouped by mark group.
*/
GListModel *
sysprof_document_catalog_marks (SysprofDocument *self)
@ -1471,34 +1473,31 @@ sysprof_document_catalog_marks (SysprofDocument *self)
g_return_val_if_fail (SYSPROF_IS_DOCUMENT (self), NULL);
store = g_list_store_new (SYSPROF_TYPE_MARK_CATALOG);
store = g_list_store_new (G_TYPE_LIST_MODEL);
g_hash_table_iter_init (&iter, self->mark_groups);
while (g_hash_table_iter_next (&iter, &key, &value))
{
g_autoptr(SysprofMarkCatalog) group = NULL;
g_autoptr(GListStore) names_store = NULL;
g_autoptr(GListStore) group = NULL;
const char *group_name = key;
GHashTable *names = value;
GHashTableIter name_iter;
const char *name;
EggBitset *marks;
names_store = g_list_store_new (SYSPROF_TYPE_MARK_CATALOG);
group = g_list_store_new (SYSPROF_TYPE_MARK_CATALOG);
g_hash_table_iter_init (&name_iter, names);
while (g_hash_table_iter_next (&name_iter, (gpointer *)&name, (gpointer *)&marks))
{
g_autoptr(GListModel) model = _sysprof_document_bitset_index_new (G_LIST_MODEL (self), marks);
g_autoptr(SysprofMarkCatalog) names_catalog = _sysprof_mark_catalog_new (name, model, SYSPROF_MARK_CATALOG_KIND_NAME);
g_autoptr(SysprofMarkCatalog) names_catalog = _sysprof_mark_catalog_new (group_name, name, model);
g_list_store_append (names_store, names_catalog);
g_list_store_append (group, names_catalog);
}
group = _sysprof_mark_catalog_new (group_name, G_LIST_MODEL (names_store), SYSPROF_MARK_CATALOG_KIND_GROUP);
g_list_store_append (store, group);
}

View File

@ -26,8 +26,8 @@
G_BEGIN_DECLS
SysprofMarkCatalog *_sysprof_mark_catalog_new (const char *name,
GListModel *items,
SysprofMarkCatalogKind kind);
SysprofMarkCatalog *_sysprof_mark_catalog_new (const char *group,
const char *name,
GListModel *items);
G_END_DECLS

View File

@ -26,14 +26,14 @@ struct _SysprofMarkCatalog
{
GObject parent_instance;
GListModel *items;
char *group;
char *name;
SysprofMarkCatalogKind kind : 1;
} SysprofMarkCatalogPrivate;
enum {
PROP_0,
PROP_GROUP,
PROP_NAME,
PROP_KIND,
N_PROPS
};
@ -74,6 +74,7 @@ sysprof_mark_catalog_dispose (GObject *object)
{
SysprofMarkCatalog *self = (SysprofMarkCatalog *)object;
g_clear_pointer (&self->group, g_free);
g_clear_pointer (&self->name, g_free);
g_clear_object (&self->items);
@ -90,8 +91,8 @@ sysprof_mark_catalog_get_property (GObject *object,
switch (prop_id)
{
case PROP_KIND:
g_value_set_enum (value, sysprof_mark_catalog_get_kind (self));
case PROP_GROUP:
g_value_set_string (value, sysprof_mark_catalog_get_group (self));
break;
case PROP_NAME:
@ -111,11 +112,10 @@ sysprof_mark_catalog_class_init (SysprofMarkCatalogClass *klass)
object_class->dispose = sysprof_mark_catalog_dispose;
object_class->get_property = sysprof_mark_catalog_get_property;
properties[PROP_KIND] =
g_param_spec_enum ("kind", NULL, NULL,
SYSPROF_TYPE_MARK_CATALOG_KIND,
SYSPROF_MARK_CATALOG_KIND_GROUP,
(G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
properties[PROP_GROUP] =
g_param_spec_string ("group", NULL, NULL,
NULL,
(G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
properties[PROP_NAME] =
g_param_spec_string ("name", NULL, NULL,
@ -130,6 +130,14 @@ sysprof_mark_catalog_init (SysprofMarkCatalog *self)
{
}
const char *
sysprof_mark_catalog_get_group (SysprofMarkCatalog *self)
{
g_return_val_if_fail (SYSPROF_IS_MARK_CATALOG (self), NULL);
return self->group;
}
const char *
sysprof_mark_catalog_get_name (SysprofMarkCatalog *self)
{
@ -139,9 +147,9 @@ sysprof_mark_catalog_get_name (SysprofMarkCatalog *self)
}
SysprofMarkCatalog *
_sysprof_mark_catalog_new (const char *name,
GListModel *items,
SysprofMarkCatalogKind kind)
_sysprof_mark_catalog_new (const char *group,
const char *name,
GListModel *items)
{
SysprofMarkCatalog *self;
@ -149,21 +157,9 @@ _sysprof_mark_catalog_new (const char *name,
g_return_val_if_fail (G_IS_LIST_MODEL (items), NULL);
self = g_object_new (SYSPROF_TYPE_MARK_CATALOG, NULL);
self->group = g_strdup (group);
self->name = g_strdup (name);
self->items = g_object_ref (items);
self->kind = kind;
return self;
}
SysprofMarkCatalogKind
sysprof_mark_catalog_get_kind (SysprofMarkCatalog *self)
{
g_return_val_if_fail (SYSPROF_IS_MARK_CATALOG (self), 0);
return self->kind;
}
G_DEFINE_ENUM_TYPE (SysprofMarkCatalogKind, sysprof_mark_catalog_kind,
G_DEFINE_ENUM_VALUE (SYSPROF_MARK_CATALOG_KIND_GROUP, "group"),
G_DEFINE_ENUM_VALUE (SYSPROF_MARK_CATALOG_KIND_NAME, "name"))

View File

@ -27,22 +27,13 @@
G_BEGIN_DECLS
#define SYSPROF_TYPE_MARK_CATALOG (sysprof_mark_catalog_get_type())
#define SYSPROF_TYPE_MARK_CATALOG_KIND (sysprof_mark_catalog_kind_get_type())
typedef enum _SysprofMarkCatalogKind
{
SYSPROF_MARK_CATALOG_KIND_GROUP,
SYSPROF_MARK_CATALOG_KIND_NAME,
} SysprofMarkCatalogKind;
SYSPROF_AVAILABLE_IN_ALL
G_DECLARE_FINAL_TYPE (SysprofMarkCatalog, sysprof_mark_catalog, SYSPROF, MARK_CATALOG, GObject)
SYSPROF_AVAILABLE_IN_ALL
GType sysprof_mark_catalog_kind_get_type (void) G_GNUC_CONST;
const char *sysprof_mark_catalog_get_group (SysprofMarkCatalog *self);
SYSPROF_AVAILABLE_IN_ALL
const char *sysprof_mark_catalog_get_name (SysprofMarkCatalog *self);
SYSPROF_AVAILABLE_IN_ALL
SysprofMarkCatalogKind sysprof_mark_catalog_get_kind (SysprofMarkCatalog *self);
const char *sysprof_mark_catalog_get_name (SysprofMarkCatalog *self);
G_END_DECLS

View File

@ -28,7 +28,7 @@ main (int argc,
{
g_autoptr(SysprofDocumentLoader) loader = NULL;
g_autoptr(SysprofDocument) document = NULL;
g_autoptr(GListModel) marks = NULL;
g_autoptr(GListModel) groups = NULL;
g_autoptr(GError) error = NULL;
guint n_groups;
@ -47,46 +47,24 @@ main (int argc,
return 1;
}
marks = sysprof_document_catalog_marks (document);
n_groups = g_list_model_get_n_items (marks);
groups = sysprof_document_catalog_marks (document);
n_groups = g_list_model_get_n_items (groups);
for (guint i = 0; i < n_groups; i++)
{
g_autoptr(SysprofMarkCatalog) catalog = g_list_model_get_item (marks, i);
const char *group = sysprof_mark_catalog_get_name (catalog);
guint n_names = g_list_model_get_n_items (G_LIST_MODEL (catalog));
g_autoptr(GListModel) catalogs = g_list_model_get_item (groups, i);
guint n_catalogs = g_list_model_get_n_items (catalogs);
g_assert (SYSPROF_IS_MARK_CATALOG (catalog));
g_assert (G_IS_LIST_MODEL (catalog));
g_assert (sysprof_mark_catalog_get_kind (catalog) == SYSPROF_MARK_CATALOG_KIND_GROUP);
g_print ("%s\n", group);
for (guint j = 0; j < n_names; j++)
for (guint j = 0; j < n_catalogs; j++)
{
g_autoptr(SysprofMarkCatalog) name_catalog = g_list_model_get_item (G_LIST_MODEL (catalog), j);
const char *name = sysprof_mark_catalog_get_name (name_catalog);
guint n_marks = g_list_model_get_n_items (G_LIST_MODEL (name_catalog));
g_autoptr(SysprofMarkCatalog) catalog = g_list_model_get_item (catalogs, j);
const char *group = sysprof_mark_catalog_get_group (catalog);
const char *name = sysprof_mark_catalog_get_name (catalog);
g_assert (SYSPROF_IS_MARK_CATALOG (name_catalog));
g_assert (G_IS_LIST_MODEL (name_catalog));
g_assert (sysprof_mark_catalog_get_kind (name_catalog) == SYSPROF_MARK_CATALOG_KIND_NAME);
if (j == 0)
g_print ("%s\n", group);
g_print (" %s\n", name);
for (guint k = 0; k < n_marks; k++)
{
g_autoptr(SysprofDocumentMark) mark = g_list_model_get_item (G_LIST_MODEL (name_catalog), k);
const char *message = sysprof_document_mark_get_message (mark);
g_assert (SYSPROF_IS_DOCUMENT_MARK (mark));
g_assert_cmpstr (sysprof_document_mark_get_group (mark), ==, group);
g_assert_cmpstr (sysprof_document_mark_get_name (mark), ==, name);
if (message && message[0])
g_print (" %s\n", message);
}
}
}

View File

@ -66,3 +66,7 @@ callgraphview row:not(:selected) treeexpander symbol.unwindable {
marktable {
font-size: .9em;
}
markchart {
font-size: .9em;
}

View File

@ -45,17 +45,6 @@ G_DEFINE_FINAL_TYPE (SysprofMarkChart, sysprof_mark_chart, GTK_TYPE_WIDGET)
static GParamSpec *properties [N_PROPS];
static GListModel *
create_model_func (gpointer item,
gpointer user_data)
{
if (SYSPROF_IS_MARK_CATALOG (item) &&
sysprof_mark_catalog_get_kind (item) == SYSPROF_MARK_CATALOG_KIND_GROUP)
return g_object_ref (item);
return NULL;
}
static void
sysprof_mark_chart_disconnect (SysprofMarkChart *self)
{
@ -70,7 +59,7 @@ sysprof_mark_chart_connect (SysprofMarkChart *self)
{
g_autoptr(GtkSingleSelection) single = NULL;
GtkFilterListModel *filtered;
GtkTreeListModel *marks_tree;
GtkFlattenListModel *flatten;
SysprofDocument *document;
GtkSortListModel *sort_model;
GtkSorter *column_sorter;
@ -81,11 +70,8 @@ sysprof_mark_chart_connect (SysprofMarkChart *self)
column_sorter = gtk_column_view_get_sorter (self->column_view);
document = sysprof_session_get_document (self->session);
marks_tree = gtk_tree_list_model_new (sysprof_document_catalog_marks (document),
FALSE, TRUE,
create_model_func,
NULL, NULL);
filtered = gtk_filter_list_model_new (G_LIST_MODEL (marks_tree), NULL);
flatten = gtk_flatten_list_model_new (sysprof_document_catalog_marks (document));
filtered = gtk_filter_list_model_new (G_LIST_MODEL (flatten), NULL);
g_object_bind_property (self->session, "filter", filtered, "filter", G_BINDING_SYNC_CREATE);
sort_model = gtk_sort_list_model_new (G_LIST_MODEL (filtered), g_object_ref (column_sorter));
single = gtk_single_selection_new (G_LIST_MODEL (sort_model));

View File

@ -19,13 +19,14 @@
<interface>
<template class="GtkListHeader">
<property name="child">
<object class="GtkLabel">
<object class="GtkInscription">
<property name="xalign">0</property>
<binding name="label">
<lookup name="name" type="SysprofMarkCatalog">
<lookup name="item" type="GtkTreeListRow">
<lookup name="item">GtkListHeader</lookup>
</lookup>
<property name="nat-chars">40</property>
<property name="min-chars">40</property>
<property name="text-overflow">clip</property>
<binding name="text">
<lookup name="group" type="SysprofMarkCatalog">
<lookup name="item">GtkListHeader</lookup>
</lookup>
</binding>
</object>
@ -38,6 +39,7 @@
</property>
<child>
<object class="GtkColumnViewColumn" id="name_column">
<property name="title" translatable="yes">Marks</property>
<property name="factory">
<object class="GtkBuilderListItemFactory">
<property name="bytes"><![CDATA[
@ -51,9 +53,7 @@
<property name="max-width-chars">40</property>
<binding name="label">
<lookup name="name" type="SysprofMarkCatalog">
<lookup name="item" type="GtkTreeListRow">
<lookup name="item">GtkListItem</lookup>
</lookup>
<lookup name="item">GtkListItem</lookup>
</lookup>
</binding>
</object>