[dia/zbrown/object-change: 2/16] change: DiaObjectChange type to replace ObjectChange
- From: Zander Brown <zbrown src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [dia/zbrown/object-change: 2/16] change: DiaObjectChange type to replace ObjectChange
- Date: Sat, 10 Oct 2020 22:05:56 +0000 (UTC)
commit 4b87cfe5599b71aa705fa74f91e1de01a56f1f77
Author: Zander Brown <zbrown gnome org>
Date: Thu Oct 1 13:45:42 2020 +0100
change: DiaObjectChange type to replace ObjectChange
As ObjectChange works on objects vs diagrams we can't outright merge
them but we can adopt a very similar architecture
docs/dia/dia-docs.xml | 1 +
lib/dia-change.c | 60 ++++++++-
lib/dia-object-change.c | 344 ++++++++++++++++++++++++++++++++++++++++++++++++
lib/dia-object-change.h | 141 ++++++++++++++++++++
lib/meson.build | 2 +
5 files changed, 546 insertions(+), 2 deletions(-)
---
diff --git a/docs/dia/dia-docs.xml b/docs/dia/dia-docs.xml
index 7c89ac316..fafb731ee 100644
--- a/docs/dia/dia-docs.xml
+++ b/docs/dia/dia-docs.xml
@@ -71,6 +71,7 @@
<xi:include href="xml/dia_svg.xml"/>
<xi:include href="xml/objchange.xml"/>
<xi:include href="xml/dia-change.xml" />
+ <xi:include href="xml/dia-object-change.xml" />
<xi:include href="xml/object-alias.xml"/>
<xi:include href="xml/create.xml"/>
<xi:include href="xml/diatransform.xml"/>
diff --git a/lib/dia-change.c b/lib/dia-change.c
index b216a7074..006f26d62 100644
--- a/lib/dia-change.c
+++ b/lib/dia-change.c
@@ -26,6 +26,7 @@
#include "dia-change.h"
#include "diagramdata.h"
+
static void
dia_change_real_apply (DiaChange *self,
DiagramData *diagram)
@@ -113,7 +114,7 @@ g_value_change_peek_pointer (const GValue *value)
}
-static gchar*
+static char *
g_value_change_collect_value (GValue *value,
guint n_collect_values,
GTypeCValue *collect_values,
@@ -145,7 +146,7 @@ g_value_change_collect_value (GValue *value,
}
-static gchar*
+static char *
g_value_change_lcopy_value (const GValue *value,
guint n_collect_values,
GTypeCValue *collect_values,
@@ -233,6 +234,16 @@ dia_change_get_type (void)
}
+/**
+ * dia_change_ref:
+ * @self: the #DiaChange
+ *
+ * Returns: (transfer full): a new reference
+ *
+ * Since: 0.98
+ *
+ * Stability: Stable
+ */
gpointer
dia_change_ref (gpointer self)
{
@@ -244,6 +255,16 @@ dia_change_ref (gpointer self)
}
+/**
+ * dia_change_unref:
+ * @self: (transfer full): the #DiaChange
+ *
+ * Decrease the ref count of @self potentially freeing it
+ *
+ * Since: 0.98
+ *
+ * Stability: Stable
+ */
void
dia_change_unref (gpointer self)
{
@@ -257,6 +278,19 @@ dia_change_unref (gpointer self)
}
+/**
+ * dia_change_new:
+ * @type: the #DiaChange derrived #GType to instantiate
+ *
+ * Create an instance of @type, it's epected this will be used inside a
+ * constructor for @type rather than in general code
+ *
+ * Returns: (transfer full): A new #DiaChange instance
+ *
+ * Since: 0.98
+ *
+ * Stability: Stable
+ */
gpointer
dia_change_new (GType type)
{
@@ -266,6 +300,17 @@ dia_change_new (GType type)
}
+/**
+ * dia_change_apply:
+ * @self: a #DiaChange
+ * @diagram: the #DiagramData to apply @self to
+ *
+ * Do a change
+ *
+ * Since: 0.98
+ *
+ * Stability: Stable
+ */
void
dia_change_apply (DiaChange *self,
DiagramData *diagram)
@@ -277,6 +322,17 @@ dia_change_apply (DiaChange *self,
}
+/**
+ * dia_change_revert:
+ * @self: a #DiaChange
+ * @diagram: the #DiagramData to revert @self from
+ *
+ * Undo a change
+ *
+ * Since: 0.98
+ *
+ * Stability: Stable
+ */
void
dia_change_revert (DiaChange *self,
DiagramData *diagram)
diff --git a/lib/dia-object-change.c b/lib/dia-object-change.c
new file mode 100644
index 000000000..f14ce6714
--- /dev/null
+++ b/lib/dia-object-change.c
@@ -0,0 +1,344 @@
+/* Dia -- an diagram creation/manipulation program
+ * Copyright (C) 1999 Alexander Larsson
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ *
+ * Copyright © 2020 Zander Brown <zbrown gnome org>
+ */
+
+#include <glib-object.h>
+#include <gobject/gvaluecollector.h>
+
+#include "dia-object-change.h"
+#include "object.h"
+
+
+static void
+dia_object_change_real_apply (DiaObjectChange *self,
+ DiaObject *object)
+{
+ g_critical ("%s doesn't implement apply", DIA_OBJECT_CHANGE_TYPE_NAME (self));
+}
+
+
+static void
+dia_object_change_real_revert (DiaObjectChange *self,
+ DiaObject *object)
+{
+ g_critical ("%s doesn't implement revert", DIA_OBJECT_CHANGE_TYPE_NAME (self));
+}
+
+
+static void
+dia_object_change_real_free (DiaObjectChange *self)
+{
+}
+
+
+static void
+dia_object_change_base_class_init (DiaObjectChangeClass *klass)
+{
+ klass->apply = dia_object_change_real_apply;
+ klass->revert = dia_object_change_real_revert;
+ klass->free = dia_object_change_real_free;
+}
+
+
+static void
+dia_object_change_class_finalize (DiaObjectChangeClass *klass)
+{
+
+}
+
+
+static void
+dia_object_change_do_class_init (DiaObjectChangeClass *klass)
+{
+}
+
+
+static void
+dia_object_change_init (DiaObjectChange *self,
+ DiaObjectChangeClass *klass)
+{
+ g_ref_count_init (&self->refs);
+}
+
+
+static void
+g_value_change_init (GValue *value)
+{
+ value->data[0].v_pointer = NULL;
+}
+
+
+static void
+g_value_change_free_value (GValue *value)
+{
+ if (value->data[0].v_pointer) {
+ dia_object_change_unref (value->data[0].v_pointer);
+ }
+}
+
+
+static void
+g_value_change_copy_value (const GValue *src_value,
+ GValue *dest_value)
+{
+ if (src_value->data[0].v_pointer) {
+ dest_value->data[0].v_pointer = dia_object_change_ref (src_value->data[0].v_pointer);
+ } else {
+ dest_value->data[0].v_pointer = NULL;
+ }
+}
+
+
+static gpointer
+g_value_change_peek_pointer (const GValue *value)
+{
+ return value->data[0].v_pointer;
+}
+
+
+static char *
+g_value_change_collect_value (GValue *value,
+ guint n_collect_values,
+ GTypeCValue *collect_values,
+ guint collect_flags)
+{
+ if (collect_values[0].v_pointer) {
+ DiaObjectChange *change = collect_values[0].v_pointer;
+
+ if (change->g_type_instance.g_class == NULL) {
+ return g_strconcat ("invalid unclassed change pointer for value type '",
+ G_VALUE_TYPE_NAME (value),
+ "'",
+ NULL);
+ } else if (!g_value_type_compatible (DIA_OBJECT_CHANGE_TYPE (change), G_VALUE_TYPE (value))) {
+ return g_strconcat ("invalid change type '",
+ DIA_OBJECT_CHANGE_TYPE_NAME (change),
+ "' for value type '",
+ G_VALUE_TYPE_NAME (value),
+ "'",
+ NULL);
+ /* never honour G_VALUE_NOCOPY_CONTENTS for ref-counted types */
+ value->data[0].v_pointer = dia_object_change_ref (change);
+ }
+ } else {
+ value->data[0].v_pointer = NULL;
+ }
+
+ return NULL;
+}
+
+
+static char *
+g_value_change_lcopy_value (const GValue *value,
+ guint n_collect_values,
+ GTypeCValue *collect_values,
+ guint collect_flags)
+{
+ DiaObjectChange **change_p = collect_values[0].v_pointer;
+
+ if (!change_p) {
+ return g_strdup_printf ("value location for '%s' passed as NULL",
+ G_VALUE_TYPE_NAME (value));
+ }
+
+ if (!value->data[0].v_pointer) {
+ *change_p = NULL;
+ } else if (collect_flags & G_VALUE_NOCOPY_CONTENTS) {
+ *change_p = value->data[0].v_pointer;
+ } else {
+ *change_p = dia_object_change_ref (value->data[0].v_pointer);
+ }
+
+ return NULL;
+}
+
+
+static void
+g_value_change_transform_value (const GValue *src_value,
+ GValue *dest_value)
+{
+ if (src_value->data[0].v_pointer &&
+ g_type_is_a (DIA_OBJECT_CHANGE_TYPE (src_value->data[0].v_pointer), G_VALUE_TYPE (dest_value))) {
+ dest_value->data[0].v_pointer = dia_object_change_ref (src_value->data[0].v_pointer);
+ } else {
+ dest_value->data[0].v_pointer = NULL;
+ }
+}
+
+
+GType
+dia_object_change_get_type (void)
+{
+ static volatile GType type_id = 0;
+
+ if (g_once_init_enter (&type_id)) {
+ static const GTypeFundamentalInfo finfo = {
+ G_TYPE_FLAG_CLASSED | G_TYPE_FLAG_INSTANTIATABLE | G_TYPE_FLAG_DERIVABLE,
+ };
+ GTypeInfo info = {
+ sizeof (DiaObjectChangeClass),
+ (GBaseInitFunc) dia_object_change_base_class_init,
+ (GBaseFinalizeFunc) dia_object_change_class_finalize,
+ (GClassInitFunc) dia_object_change_do_class_init,
+ NULL, /* class_destroy */
+ NULL, /* class_data */
+ sizeof (DiaObjectChange),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) dia_object_change_init,
+ NULL, /* value_table */
+ };
+ static const GTypeValueTable value_table = {
+ g_value_change_init, /* value_init */
+ g_value_change_free_value, /* value_free */
+ g_value_change_copy_value, /* value_copy */
+ g_value_change_peek_pointer, /* value_peek_pointer */
+ "p", /* collect_format */
+ g_value_change_collect_value, /* collect_value */
+ "p", /* lcopy_format */
+ g_value_change_lcopy_value, /* lcopy_value */
+ };
+ GType type;
+
+ info.value_table = &value_table;
+ type = g_type_register_fundamental (g_type_fundamental_next (),
+ g_intern_static_string ("DiaObjectChange"),
+ &info,
+ &finfo,
+ 0);
+ g_value_register_transform_func (type,
+ type,
+ g_value_change_transform_value);
+
+ g_once_init_leave (&type_id, type);
+ }
+
+ return type_id;
+}
+
+
+/**
+ * dia_object_change_ref:
+ * @self: the #DiaObjectChange
+ *
+ * Returns: (transfer full): a new reference
+ *
+ * Since: 0.98
+ *
+ * Stability: Stable
+ */
+gpointer
+dia_object_change_ref (gpointer self)
+{
+ g_return_val_if_fail (self != NULL, NULL);
+
+ g_ref_count_inc (&((DiaObjectChange *) self)->refs);
+
+ return self;
+}
+
+
+/**
+ * dia_object_change_unref:
+ * @self: (transfer full): the #DiaObjectChange
+ *
+ * Decrease the ref count of @self potentially freeing it
+ *
+ * Since: 0.98
+ *
+ * Stability: Stable
+ */
+void
+dia_object_change_unref (gpointer self)
+{
+ g_return_if_fail (self != NULL);
+
+ if (g_ref_count_dec (&((DiaObjectChange *) self)->refs)) {
+ DIA_OBJECT_CHANGE_GET_CLASS (self)->free (self);
+
+ g_type_free_instance (self);
+ }
+}
+
+
+/**
+ * dia_object_change_new:
+ * @type: the #DiaObjectChange derrived #GType to instantiate
+ *
+ * Create an instance of @type, it's epected this will be used inside a
+ * constructor for @type rather than in general code
+ *
+ * Returns: (transfer full): A new #DiaObjectChange instance
+ *
+ * Since: 0.98
+ *
+ * Stability: Stable
+ */
+gpointer
+dia_object_change_new (GType type)
+{
+ g_return_val_if_fail (DIA_TYPE_IS_OBJECT_CHANGE (type), NULL);
+
+ return g_type_create_instance (type);
+}
+
+
+/**
+ * dia_object_change_apply:
+ * @self: a #DiaObjectChange
+ * @object: the #DiaObject to apply @self to
+ *
+ * Do a change
+ *
+ * Since: 0.98
+ *
+ * Stability: Stable
+ */
+void
+dia_object_change_apply (DiaObjectChange *self,
+ DiaObject *object)
+{
+ g_return_if_fail (self && DIA_IS_OBJECT_CHANGE (self));
+ g_return_if_fail (object && DIA_IS_DIAGRAM_DATA (object));
+
+ DIA_OBJECT_CHANGE_GET_CLASS (self)->apply (self, object);
+}
+
+
+/**
+ * dia_object_change_revert:
+ * @self: a #DiaObjectChange
+ * @object: the #DiaObject to revert @self from
+ *
+ * Undo a change
+ *
+ * Since: 0.98
+ *
+ * Stability: Stable
+ */
+void
+dia_object_change_revert (DiaObjectChange *self,
+ DiaObject *object)
+{
+ g_return_if_fail (self && DIA_IS_OBJECT_CHANGE (self));
+ g_return_if_fail (object && DIA_IS_DIAGRAM_DATA (object));
+
+ DIA_OBJECT_CHANGE_GET_CLASS (self)->revert (self, object);
+}
diff --git a/lib/dia-object-change.h b/lib/dia-object-change.h
new file mode 100644
index 000000000..c500f4271
--- /dev/null
+++ b/lib/dia-object-change.h
@@ -0,0 +1,141 @@
+/* Dia -- an diagram creation/manipulation program
+ * Copyright (C) 1999 Alexander Larsson
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ *
+ * Copyright © 2020 Zander Brown <zbrown gnome org>
+ */
+
+#pragma once
+
+#include <glib-object.h>
+
+#ifndef __GTK_DOC_IGNORE__
+// TODO: Fix the cycle
+typedef struct _DiaObject DiaObject;
+#endif
+
+G_BEGIN_DECLS
+
+GType dia_object_change_get_type (void);
+#define DIA_TYPE_OBJECT_CHANGE dia_object_change_get_type ()
+
+typedef struct _DiaObjectChange DiaObjectChange;
+typedef struct _DiaObjectChangeClass DiaObjectChangeClass;
+
+#define DIA_TYPE_IS_OBJECT_CHANGE(type) (G_TYPE_FUNDAMENTAL (type) == DIA_TYPE_OBJECT_CHANGE)
+#define DIA_OBJECT_CHANGE(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), DIA_TYPE_OBJECT_CHANGE,
DiaObjectChange))
+#define DIA_OBJECT_CHANGE_CLASS(class) (G_TYPE_CHECK_CLASS_CAST ((class), DIA_TYPE_OBJECT_CHANGE,
DiaObjectChangeClass))
+#define DIA_IS_OBJECT_CHANGE(object) (G_TYPE_CHECK_INSTANCE_FUNDAMENTAL_TYPE ((object),
DIA_TYPE_OBJECT_CHANGE))
+#define DIA_IS_OBJECT_CHANGE_CLASS(class) (G_TYPE_CHECK_CLASS_TYPE ((class), DIA_TYPE_OBJECT_CHANGE))
+#define DIA_OBJECT_CHANGE_GET_CLASS(object) (G_TYPE_INSTANCE_GET_CLASS ((object), DIA_TYPE_OBJECT_CHANGE,
DiaObjectChangeClass))
+#define DIA_OBJECT_CHANGE_TYPE(object) (G_TYPE_FROM_INSTANCE (object))
+#define DIA_OBJECT_CHANGE_TYPE_NAME(object) (g_type_name (DIA_OBJECT_CHANGE_TYPE (object)))
+#define DIA_OBJECT_CHANGE_CLASS_TYPE(class) (G_TYPE_FROM_CLASS (class))
+#define DIA_OBJECT_CHANGE_CLASS_NAME(class) (g_type_name (DIA_OBJECT_CHANGE_CLASS_TYPE (class)))
+#define G_VALUE_HOLDS_OBJECT_CHANGE(value) (G_TYPE_CHECK_VALUE_TYPE ((value), DIA_TYPE_OBJECT_CHANGE))
+
+
+/**
+ * DIA_DEFINE_CHANGE:
+ * @TypeName: CamelCase name of the type
+ * @type_name: python_case name of the type
+ *
+ * G_DEFINE_TYPE() wrapper for implementing #DiaObjectChange types, however
+ * unlike G_DEFINE_TYPE() the _init and _class_init are implemented for you.
+ * Instead you provide apply, revert & free functions
+ *
+ * |[<!-- language="C" -->
+ * DIA_DEFINE_OBJECT_CHANGE (SomeChange, some_change)
+ *
+ * static void
+ * some_change_apply (DiaObjectChange *change,
+ * DiaObject *object)
+ * {
+ * }
+ *
+ * static void
+ * some_change_revert (DiaObjectChange *change,
+ * DiaObject *object)
+ * {
+ * }
+ *
+ * static void
+ * some_change_free (DiaObjectChange *change)
+ * {
+ * }
+ * ]|
+ *
+ * Since: 0.98
+ */
+#define DIA_DEFINE_OBJECT_CHANGE(TypeName, type_name) \
+ G_DEFINE_TYPE (TypeName, type_name, DIA_TYPE_OBJECT_CHANGE) \
+ \
+ static void type_name##_apply (DiaObjectChange *change, \
+ DiaObject *object); \
+ static void type_name##_revert (DiaObjectChange *change, \
+ DiaObject *object); \
+ static void type_name##_free (DiaObjectChange *change); \
+ \
+ static void \
+ type_name##_class_init (TypeName##Class *klass) \
+ { \
+ DiaObjectChangeClass *change_class = DIA_OBJECT_CHANGE_CLASS (klass); \
+ \
+ change_class->apply = type_name##_apply; \
+ change_class->revert = type_name##_revert; \
+ change_class->free = type_name##_free; \
+ } \
+ \
+ static void \
+ type_name##_init (TypeName *klass) \
+ { \
+ }
+
+
+struct _DiaObjectChange {
+ GTypeInstance g_type_instance;
+
+ grefcount refs;
+
+ DiaObjectChange *next;
+ DiaObjectChange *prev;
+};
+
+
+struct _DiaObjectChangeClass {
+ GTypeClass parent;
+
+ void (*apply) (DiaObjectChange *change,
+ DiaObject *dia);
+ void (*revert) (DiaObjectChange *change,
+ DiaObject *dia);
+ void (*free) (DiaObjectChange *change);
+};
+
+
+void dia_object_change_unref (gpointer self);
+gpointer dia_object_change_ref (gpointer self);
+gpointer dia_object_change_new (GType type);
+void dia_object_change_apply (DiaObjectChange *self,
+ DiaObject *object);
+void dia_object_change_revert (DiaObjectChange *self,
+ DiaObject *object);
+
+G_DEFINE_AUTOPTR_CLEANUP_FUNC (DiaObjectChange, dia_object_change_unref)
+
+G_END_DECLS
diff --git a/lib/meson.build b/lib/meson.build
index 1aa23e788..9938fea1a 100644
--- a/lib/meson.build
+++ b/lib/meson.build
@@ -91,6 +91,8 @@ libdia_sources = stdprop_sources + [
'objchange.h',
'dia-change.c',
'dia-change.h',
+ 'dia-object-change.c',
+ 'dia-object-change.h',
'dialogs.c',
'dialogs.h',
'widgets.c',
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]