gEDA-dev: [PATCH 1/2] Added new GedaList class derived from GObject
Peter Clifton
pcjc2 at cam.ac.uk
Mon Jul 16 08:22:54 EDT 2007
This abstracts a GList with API for write access. Its main use is in list
change notification, as it emits a "changed" g_signal when modified.
Read only access to the underlying GList is provided by an accessor,
currenly implemented as a macro.
---
libgeda/include/Makefile.am | 3 +-
libgeda/include/geda_list.h | 61 ++++++++++++
libgeda/include/libgeda.h | 1 +
libgeda/src/Makefile.am | 3 +-
libgeda/src/geda_list.c | 213 +++++++++++++++++++++++++++++++++++++++++++
5 files changed, 279 insertions(+), 2 deletions(-)
diff --git a/libgeda/include/Makefile.am b/libgeda/include/Makefile.am
index eb5420f..8357985 100644
--- a/libgeda/include/Makefile.am
+++ b/libgeda/include/Makefile.am
@@ -3,7 +3,8 @@
libgedaincludedir = $(includedir)/libgeda
libgedainclude_HEADERS = \
colors.h defines.h funcs.h globals.h o_types.h \
- prototype.h struct.h libgeda.h i_vars.h papersizes.h
+ prototype.h struct.h libgeda.h i_vars.h papersizes.h \
+ geda_list.h
MOSTLYCLEANFILES = *.log core FILE *~
CLEANFILES = *.log core FILE *~
diff --git a/libgeda/include/geda_list.h b/libgeda/include/geda_list.h
new file mode 100644
index 0000000..492c78c
--- /dev/null
+++ b/libgeda/include/geda_list.h
@@ -0,0 +1,61 @@
+/* gEDA - GPL Electronic Design Automation
+ * gschem - gEDA Schematic Capture
+ * Copyright (C) 1998-2004 Ales V. Hvezda
+ * Copyright (C) 2007 Peter Clifton
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+#ifndef __GEDA_LIST_H__
+#define __GEDA_LIST_H__
+
+
+#define GEDA_TYPE_LIST (geda_list_get_type())
+#define GEDA_LIST(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GEDA_TYPE_LIST, GedaList))
+#define GEDA_LIST_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), GEDA_TYPE_LIST, GedaListClass))
+#define GEDA_IS_LIST(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), GEDA_TYPE_LIST))
+#define GEDA_IS_LIST_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), GEDA_TYPE_LIST))
+#define GEDA_LIST_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GEDA_TYPE_LIST, GedaListClass))
+
+
+typedef struct _GedaList GedaList;
+typedef struct _GedaListClass GedaListClass;
+
+struct _GedaList {
+ GObject parent;
+ GList *glist;
+};
+
+struct _GedaListClass {
+ GObjectClass parent;
+};
+
+GType geda_list_get_type (void);
+
+/* It would be nice to add const qualifiers to some of these, but GLib
+ * is buggy in this respect, and doesn't have const where necessary. */
+GedaList *geda_list_new( void );
+void geda_list_add( GedaList *list, gpointer item );
+void geda_list_add_glist( GedaList *list, GList *items );
+void geda_list_remove( GedaList *list, gpointer item );
+/*void geda_list_remove_glist( GedaList *list, GList *items ); */ /* Undemanded as yet */
+void geda_list_remove_all( GedaList *list );
+
+/*const GList *geda_list_get_glist( GedaList *list ); */
+#define geda_list_get_glist(list) (list->glist)
+
+#endif /* __GEDA_LIST_H__ */
+
diff --git a/libgeda/include/libgeda.h b/libgeda/include/libgeda.h
index e458a7a..074fe0a 100644
--- a/libgeda/include/libgeda.h
+++ b/libgeda/include/libgeda.h
@@ -36,6 +36,7 @@
#include <libgeda/papersizes.h>
#include <libgeda/i_vars.h>
#include <libgeda/prototype.h>
+#include <libgeda/geda_list.h>
#include <gdk-pixbuf/gdk-pixbuf.h>
diff --git a/libgeda/src/Makefile.am b/libgeda/src/Makefile.am
index 8d7495b..3015c90 100644
--- a/libgeda/src/Makefile.am
+++ b/libgeda/src/Makefile.am
@@ -23,7 +23,8 @@ libgeda_la_SOURCES = \
s_log.c s_textbuffer.c \
s_page.c s_slib.c s_color.c s_undo.c s_conn.c \
s_cue.c s_tile.c s_menu.c s_toplevel.c g_smob.c libgeda.c \
- g_register.c g_rc.c i_vars.c o_picture.c gdk-pixbuf-hacks.c
+ g_register.c g_rc.c i_vars.c o_picture.c gdk-pixbuf-hacks.c \
+ geda_list.c
INCLUDES = -I$(top_srcdir)/include @LIBGEDA_CFLAGS@
libgeda_la_LDFLAGS = @LIBTOOL_FLAGS@ @LIBGEDA_LDFLAGS@
diff --git a/libgeda/src/geda_list.c b/libgeda/src/geda_list.c
new file mode 100644
index 0000000..b6792c6
--- /dev/null
+++ b/libgeda/src/geda_list.c
@@ -0,0 +1,213 @@
+/* gEDA - GPL Electronic Design Automation
+ * libgeda - gEDA's library
+ * Copyright (C) 1998-2000 Ales V. Hvezda
+ * Copyright (C) 2007 Peter Clifton
+ *
+ * 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 USA
+ */
+
+
+#include <config.h>
+
+#include <glib-object.h>
+
+#include "geda_list.h"
+
+#ifdef HAVE_LIBDMALLOC
+#include <dmalloc.h>
+#endif
+
+
+enum {
+ CHANGED,
+ LAST_SIGNAL
+};
+
+static guint geda_list_signals[ LAST_SIGNAL ] = { 0 };
+static GObjectClass *geda_list_parent_class = NULL;
+
+
+/*! \brief GType instance initialiser for GedaList
+ *
+ * \par Function Description
+ * GType instance initialiser for GedaList.
+ *
+ * \param [in] instance The GedaList we are initialising.
+ * \param [in] g_class The class of the type the instance is created for.
+ */
+static void geda_list_instance_init( GTypeInstance *instance, gpointer g_class )
+{
+ GedaList *list = (GedaList *)instance;
+
+ /* Strictly un-necessary, as the memory is zero'd after allocation */
+ list->glist = NULL;
+}
+
+
+/*! \brief GObject finalise handler
+ *
+ * \par Function Description
+ * Just before the GedaList GObject is finalized, free our
+ * allocated data, and then chain up to the parent's finalize handler.
+ *
+ * \param [in] widget The GObject being finalized.
+ */
+static void geda_list_finalize( GObject *object )
+{
+ GedaList *list = GEDA_LIST( object );
+ g_list_free( list->glist );
+
+ G_OBJECT_CLASS( geda_list_parent_class )->finalize( object );
+}
+
+
+/*! \brief GType class initialiser for GedaList
+ *
+ * \par Function Description
+ * GType class initialiser for GedaList. We override our parents
+ * virtual class methods as needed and register our GObject signals.
+ *
+ * \param [in] klass The GedaList we are initialising
+ */
+static void geda_list_class_init( gpointer g_class, gpointer g_class_data )
+{
+ GedaListClass *klass = GEDA_LIST_CLASS( g_class );
+ GObjectClass *gobject_class = G_OBJECT_CLASS( klass );
+ geda_list_parent_class = g_type_class_peek_parent( klass );
+
+ gobject_class->finalize = geda_list_finalize;
+
+ geda_list_signals[ CHANGED ] =
+ g_signal_new ("changed",
+ G_OBJECT_CLASS_TYPE( gobject_class ),
+ 0 /*signal_flags */,
+ 0 /*class_offset */,
+ NULL, /* accumulator */
+ NULL, /* accu_data */
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE,
+ 0 /* n_params */
+ );
+}
+
+
+/*! \brief Function to retrieve GedaList's GType identifier.
+ *
+ * \par Function Description
+ * Function to retrieve GedaList's GType identifier.
+ * Upon first call, this registers the GedaList in the GType system.
+ * Subsequently it returns the saved value from its first execution.
+ *
+ * \return the GType identifier associated with GedaList.
+ */
+GType geda_list_get_type(void)
+{
+ static GType type = 0;
+ if (type == 0) {
+ static const GTypeInfo info = {
+ sizeof (GedaListClass),
+ NULL, /* base_init */
+ NULL, /* base_finalize */
+ geda_list_class_init, /* class_init */
+ NULL, /* class_finalize */
+ NULL, /* class_data */
+ sizeof (GedaList),
+ 0, /* n_preallocs */
+ geda_list_instance_init /* instance_init */
+ };
+ type = g_type_register_static (G_TYPE_OBJECT, "GedaList", &info, 0);
+ }
+ return type;
+}
+
+
+/*! \brief Returns a pointer to a new GedaList object.
+ *
+ * \par Function Description
+ * Returns a pointer to a new GedaList object.
+ *
+ * \return pointer to the new GedaList object.
+ */
+GedaList *geda_list_new( void ) {
+ return g_object_new( GEDA_TYPE_LIST, NULL );
+}
+
+
+/*! \brief Adds the given item to the GedaList
+ *
+ * \par Function Description
+ * Adds the given item to the GedaList
+ *
+ * \param [in] list Pointer to the GedaList
+ * \param [in] item item to add to the GedaList.
+ */
+void geda_list_add( GedaList *list, gpointer item )
+{
+ list->glist = g_list_append(list->glist, item );
+ g_signal_emit( list, geda_list_signals[ CHANGED ], 0 );
+}
+
+
+/*! \brief Adds the given glist of items to the GedaList
+ *
+ * \par Function Description
+ * Adds the given glist of items to the GedaList
+ * A copy is made, so the original GList is not modified.
+ *
+ * \param [in] list Pointer to the GedaList
+ * \param [in] items GList of items to add to the GedaList.
+ */
+void geda_list_add_glist( GedaList *list, GList *items )
+{
+ GList *glist_copy = g_list_copy( items );
+ list->glist = g_list_concat(list->glist, glist_copy );
+ g_signal_emit( list, geda_list_signals[ CHANGED ], 0 );
+}
+
+
+/*! \brief Removes the given item from the GedaList
+ *
+ * \par Function Description
+ * Removes the given item from the GedaList.
+ * It's ok to call this function with an item which
+ * is not necessarily in the list.
+ *
+ * \param [in] list Pointer to the GedaList
+ * \param [in] item to remove from the GedaList.
+ */
+void geda_list_remove( GedaList *list, gpointer item )
+{
+ if (g_list_find(list->glist, item) == NULL)
+ return;
+
+ list->glist = g_list_remove(list->glist, item);
+ g_signal_emit( list, geda_list_signals[ CHANGED ], 0 );
+}
+
+
+/*! \brief Removes all the items in the given GedaList.
+ *
+ * \par Function Description
+ * Removes all items in the given GedaList.
+ *
+ * \param [in] list Pointer to the GedaList
+ */
+void geda_list_remove_all( GedaList *list )
+{
+ g_list_free(list->glist);
+ list->glist = NULL;
+ g_signal_emit( list, geda_list_signals[ CHANGED ], 0 );
+}
+
--
1.5.2.3
More information about the geda-dev
mailing list