diff --git a/src/libsysprof-gtk/meson.build b/src/libsysprof-gtk/meson.build index 0efc2504..4649152b 100644 --- a/src/libsysprof-gtk/meson.build +++ b/src/libsysprof-gtk/meson.build @@ -11,6 +11,8 @@ libsysprof_gtk_public_sources = [ 'sysprof-normalized-series-item.c', 'sysprof-series.c', 'sysprof-session.c', + 'sysprof-session-model.c', + 'sysprof-session-model-item.c', 'sysprof-split-layer.c', 'sysprof-time-span-layer.c', 'sysprof-time-series.c', @@ -37,6 +39,8 @@ libsysprof_gtk_public_headers = [ 'sysprof-normalized-series-item.h', 'sysprof-series.h', 'sysprof-session.h', + 'sysprof-session-model.h', + 'sysprof-session-model-item.h', 'sysprof-split-layer.h', 'sysprof-time-series.h', 'sysprof-time-series-item.h', diff --git a/src/libsysprof-gtk/sysprof-gtk.h b/src/libsysprof-gtk/sysprof-gtk.h index 5b557304..f021e9db 100644 --- a/src/libsysprof-gtk/sysprof-gtk.h +++ b/src/libsysprof-gtk/sysprof-gtk.h @@ -35,6 +35,8 @@ G_BEGIN_DECLS # include "sysprof-normalized-series-item.h" # include "sysprof-series.h" # include "sysprof-session.h" +# include "sysprof-session-model.h" +# include "sysprof-session-model-item.h" # include "sysprof-split-layer.h" # include "sysprof-time-series.h" # include "sysprof-time-series-item.h" diff --git a/src/libsysprof-gtk/sysprof-session-model-item.c b/src/libsysprof-gtk/sysprof-session-model-item.c new file mode 100644 index 00000000..3c09107e --- /dev/null +++ b/src/libsysprof-gtk/sysprof-session-model-item.c @@ -0,0 +1,155 @@ +/* sysprof-session-model-item.c + * + * Copyright 2023 Christian Hergert + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +#include "config.h" + +#include "sysprof-session-model-item.h" + +struct _SysprofSessionModelItem +{ + GObject parent_instance; + SysprofSession *session; + GObject *item; +}; + +enum { + PROP_0, + PROP_SESSION, + PROP_ITEM, + N_PROPS +}; + +G_DEFINE_FINAL_TYPE (SysprofSessionModelItem, sysprof_session_model_item, G_TYPE_OBJECT) + +static GParamSpec *properties [N_PROPS]; + +static void +sysprof_session_model_item_dispose (GObject *object) +{ + SysprofSessionModelItem *self = (SysprofSessionModelItem *)object; + + g_clear_weak_pointer (&self->session); + g_clear_object (&self->item); + + G_OBJECT_CLASS (sysprof_session_model_item_parent_class)->dispose (object); +} + +static void +sysprof_session_model_item_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + SysprofSessionModelItem *self = SYSPROF_SESSION_MODEL_ITEM (object); + + switch (prop_id) + { + case PROP_SESSION: + g_value_set_object (value, sysprof_session_model_item_get_session (self)); + break; + + case PROP_ITEM: + g_value_set_object (value, sysprof_session_model_item_get_item (self)); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static void +sysprof_session_model_item_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + SysprofSessionModelItem *self = SYSPROF_SESSION_MODEL_ITEM (object); + + switch (prop_id) + { + case PROP_SESSION: + g_set_weak_pointer (&self->session, g_value_get_object (value)); + break; + + case PROP_ITEM: + self->item = g_value_dup_object (value); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static void +sysprof_session_model_item_class_init (SysprofSessionModelItemClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->dispose = sysprof_session_model_item_dispose; + object_class->get_property = sysprof_session_model_item_get_property; + object_class->set_property = sysprof_session_model_item_set_property; + + properties[PROP_SESSION] = + g_param_spec_object ("session", NULL, NULL, + SYSPROF_TYPE_SESSION, + (G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS)); + + properties[PROP_ITEM] = + g_param_spec_object ("item", NULL, NULL, + G_TYPE_OBJECT, + (G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS)); + + g_object_class_install_properties (object_class, N_PROPS, properties); +} + +static void +sysprof_session_model_item_init (SysprofSessionModelItem *self) +{ +} + +/** + * sysprof_session_model_item_get_session: + * @self: a #SysprofSessionModelItem + * + * Returns: (transfer none) (nullable): a #SysprofSession or %NULL + */ +SysprofSession * +sysprof_session_model_item_get_session (SysprofSessionModelItem *self) +{ + g_return_val_if_fail (SYSPROF_IS_SESSION_MODEL_ITEM (self), NULL); + + return self->session; +} + +/** + * sysprof_session_model_item_get_item: + * @self: a #SysprofSessionModelItem + * + * Gets the underlying item. + * + * Returns: (transfer none) (nullable) (type GObject): a #GObject or %NULL + */ +gpointer +sysprof_session_model_item_get_item (SysprofSessionModelItem *self) +{ + g_return_val_if_fail (SYSPROF_IS_SESSION_MODEL_ITEM (self), NULL); + + return self->item; +} diff --git a/src/libsysprof-gtk/sysprof-session-model-item.h b/src/libsysprof-gtk/sysprof-session-model-item.h new file mode 100644 index 00000000..e35bd588 --- /dev/null +++ b/src/libsysprof-gtk/sysprof-session-model-item.h @@ -0,0 +1,39 @@ +/* sysprof-session-model-item.h + * + * Copyright 2023 Christian Hergert + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +#pragma once + +#include + +#include "sysprof-session.h" + +G_BEGIN_DECLS + +#define SYSPROF_TYPE_SESSION_MODEL_ITEM (sysprof_session_model_item_get_type()) + +SYSPROF_AVAILABLE_IN_ALL +G_DECLARE_FINAL_TYPE (SysprofSessionModelItem, sysprof_session_model_item, SYSPROF, SESSION_MODEL_ITEM, GObject) + +SYSPROF_AVAILABLE_IN_ALL +SysprofSession *sysprof_session_model_item_get_session (SysprofSessionModelItem *self); +SYSPROF_AVAILABLE_IN_ALL +gpointer sysprof_session_model_item_get_item (SysprofSessionModelItem *self); + +G_END_DECLS diff --git a/src/libsysprof-gtk/sysprof-session-model.c b/src/libsysprof-gtk/sysprof-session-model.c new file mode 100644 index 00000000..12fa915a --- /dev/null +++ b/src/libsysprof-gtk/sysprof-session-model.c @@ -0,0 +1,254 @@ +/* sysprof-session-model.c + * + * Copyright 2023 Christian Hergert + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +#include "config.h" + +#include "sysprof-session-model.h" +#include "sysprof-session-model-item.h" + +struct _SysprofSessionModel +{ + GObject parent_instance; + GListModel *model; + SysprofSession *session; +}; + +enum { + PROP_0, + PROP_MODEL, + PROP_SESSION, + N_PROPS +}; + +static GType +sysprof_session_model_get_item_type (GListModel *model) +{ + return G_TYPE_OBJECT; +} + +static gpointer +sysprof_session_model_get_item (GListModel *model, + guint position) +{ + SysprofSessionModel *self = SYSPROF_SESSION_MODEL (model); + g_autoptr(GObject) item = NULL; + + if (self->model == NULL) + return NULL; + + if ((item = g_list_model_get_item (self->model, position))) + return g_object_new (SYSPROF_TYPE_SESSION_MODEL_ITEM, + "session", self->session, + "item", item, + NULL); + + return NULL; +} + +static guint +sysprof_session_model_get_n_items (GListModel *model) +{ + SysprofSessionModel *self = SYSPROF_SESSION_MODEL (model); + + if (self->model == NULL) + return 0; + + return g_list_model_get_n_items (self->model); +} + +static void +list_model_iface_init (GListModelInterface *iface) +{ + iface->get_item_type = sysprof_session_model_get_item_type; + iface->get_n_items = sysprof_session_model_get_n_items; + iface->get_item = sysprof_session_model_get_item; +} + +G_DEFINE_FINAL_TYPE_WITH_CODE (SysprofSessionModel, sysprof_session_model, G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE (G_TYPE_LIST_MODEL, list_model_iface_init)) + +static GParamSpec *properties [N_PROPS]; + +static void +sysprof_session_model_dispose (GObject *object) +{ + SysprofSessionModel *self = (SysprofSessionModel *)object; + + g_clear_object (&self->session); + g_clear_object (&self->model); + + G_OBJECT_CLASS (sysprof_session_model_parent_class)->dispose (object); +} + +static void +sysprof_session_model_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + SysprofSessionModel *self = SYSPROF_SESSION_MODEL (object); + + switch (prop_id) + { + case PROP_SESSION: + g_value_set_object (value, sysprof_session_model_get_session (self)); + break; + + case PROP_MODEL: + g_value_set_object (value, sysprof_session_model_get_model (self)); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static void +sysprof_session_model_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + SysprofSessionModel *self = SYSPROF_SESSION_MODEL (object); + + switch (prop_id) + { + case PROP_MODEL: + sysprof_session_model_set_model (self, g_value_get_object (value)); + break; + + case PROP_SESSION: + sysprof_session_model_set_session (self, g_value_get_object (value)); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static void +sysprof_session_model_class_init (SysprofSessionModelClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->dispose = sysprof_session_model_dispose; + object_class->get_property = sysprof_session_model_get_property; + object_class->set_property = sysprof_session_model_set_property; + + properties [PROP_MODEL] = + g_param_spec_object ("model", NULL, NULL, + G_TYPE_LIST_MODEL, + (G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS)); + + properties [PROP_SESSION] = + g_param_spec_object ("session", NULL, NULL, + SYSPROF_TYPE_SESSION, + (G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS)); + + g_object_class_install_properties (object_class, N_PROPS, properties); +} + +static void +sysprof_session_model_init (SysprofSessionModel *self) +{ +} + +SysprofSessionModel * +sysprof_session_model_new (SysprofSession *session, + GListModel *model) +{ + g_return_val_if_fail (!session || SYSPROF_IS_SESSION (session), NULL); + g_return_val_if_fail (!model || G_IS_LIST_MODEL (model), NULL); + + return g_object_new (SYSPROF_TYPE_SESSION_MODEL, + "session", session, + "model", model, + NULL); +} + +/** + * sysprof_model_model_get_model: + * @self: a #SysprofSessionModel + * + * Returns: (transfer none) (nullable): a #GListModel or %NULL + */ +GListModel * +sysprof_session_model_get_model (SysprofSessionModel *self) +{ + g_return_val_if_fail (SYSPROF_IS_SESSION_MODEL (self), NULL); + + return self->model; +} + +void +sysprof_session_model_set_model (SysprofSessionModel *self, + GListModel *model) +{ + guint old_len = 0; + guint new_len = 0; + + g_return_if_fail (SYSPROF_IS_SESSION_MODEL (self)); + g_return_if_fail (!model || G_IS_LIST_MODEL (model)); + + if (self->model == model) + return; + + if (self->model) + { + old_len = g_list_model_get_n_items (G_LIST_MODEL (self->model)); + g_clear_object (&self->model); + } + + if (model) + { + self->model = g_object_ref (model); + new_len = g_list_model_get_n_items (model); + } + + g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_MODEL]); + + if (old_len || new_len) + g_list_model_items_changed (G_LIST_MODEL (self), 0, old_len, new_len); +} + +/** + * sysprof_session_model_get_session: + * @self: a #SysprofSessionModel + * + * Returns: (transfer none) (nullable): a #SysprofSession or %NULL + */ +SysprofSession * +sysprof_session_model_get_session (SysprofSessionModel *self) +{ + g_return_val_if_fail (SYSPROF_IS_SESSION_MODEL (self), NULL); + + return self->session; +} + +void +sysprof_session_model_set_session (SysprofSessionModel *self, + SysprofSession *session) +{ + g_return_if_fail (SYSPROF_IS_SESSION_MODEL (self)); + g_return_if_fail (!session || SYSPROF_IS_SESSION (session)); + + if (g_set_object (&self->session, session)) + g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_SESSION]); +} diff --git a/src/libsysprof-gtk/sysprof-session-model.h b/src/libsysprof-gtk/sysprof-session-model.h new file mode 100644 index 00000000..108b4478 --- /dev/null +++ b/src/libsysprof-gtk/sysprof-session-model.h @@ -0,0 +1,48 @@ +/* sysprof-session-model.h + * + * Copyright 2023 Christian Hergert + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +#pragma once + +#include + +#include "sysprof-session.h" + +G_BEGIN_DECLS + +#define SYSPROF_TYPE_SESSION_MODEL (sysprof_session_model_get_type()) + +SYSPROF_AVAILABLE_IN_ALL +G_DECLARE_FINAL_TYPE (SysprofSessionModel, sysprof_session_model, SYSPROF, SESSION_MODEL, GObject) + +SYSPROF_AVAILABLE_IN_ALL +SysprofSessionModel *sysprof_session_model_new (SysprofSession *session, + GListModel *model); +SYSPROF_AVAILABLE_IN_ALL +GListModel *sysprof_session_model_get_model (SysprofSessionModel *self); +SYSPROF_AVAILABLE_IN_ALL +void sysprof_session_model_set_model (SysprofSessionModel *self, + GListModel *model); +SYSPROF_AVAILABLE_IN_ALL +SysprofSession *sysprof_session_model_get_session (SysprofSessionModel *self); +SYSPROF_AVAILABLE_IN_ALL +void sysprof_session_model_set_session (SysprofSessionModel *self, + SysprofSession *session); + +G_END_DECLS