[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

gEDA-cvs: gaf.git: branch: master updated (1.6.1-20100214-118-gf8ddb85)



The branch, master has been updated
       via  f8ddb85e74bbf05a6901365527d27d3e2914ccec (commit)
      from  d4908a377f6a1ebcc80d12a08d96d85e8d0473c1 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.


=========
 Summary
=========

 libgeda/include/libgeda/prototype.h |   12 +++
 libgeda/include/libgeda/struct.h    |    4 +
 libgeda/include/prototype_priv.h    |    7 ++
 libgeda/src/Makefile.am             |    1 +
 libgeda/src/s_basic.c               |   85 +++++++++++++++++++
 libgeda/src/s_page.c                |   86 ++++++++++++++++++++
 libgeda/src/s_toplevel.c            |   87 ++++++++++++++++++++
 libgeda/src/s_weakref.c             |  153 +++++++++++++++++++++++++++++++++++
 8 files changed, 435 insertions(+), 0 deletions(-)
 create mode 100644 libgeda/src/s_weakref.c


=================
 Commit Messages
=================

commit f8ddb85e74bbf05a6901365527d27d3e2914ccec
Author: Peter TB Brett <peter@xxxxxxxxxxxxx>
Commit: Peter TB Brett <peter@xxxxxxxxxxxxx>

    libgeda: Add weak refs to OBJECT/PAGE/TOPLEVEL.
    
    Weak references are useful when you want to keep an eye on an object
    but not necessarily hang on to it when it comes to its useful life.
    
    This patch adds an internal libgeda API for using weak references.
    There are two types of weak references implemented by this patch:
    
    * full-powered weak references, where an arbitrary callback function
      can be registered on an object to be notified when an object is
      destroyed
    
    * weak pointers, which are set to NULL when the object is destroyed.
    
    This functionality will hopefully allow several pieces of housekeeping
    code in libgeda to be simplified.
    
    The API is designed to be as close as possible to the GObject weak ref
    API. See e.g. g_object_weak_ref().

:100644 100644 4e9cb0e... ad9608a... M	libgeda/include/libgeda/prototype.h
:100644 100644 03e70e6... 2abfbe2... M	libgeda/include/libgeda/struct.h
:100644 100644 531afa9... 9f6df1d... M	libgeda/include/prototype_priv.h
:100644 100644 04ee412... ba66781... M	libgeda/src/Makefile.am
:100644 100644 6af349c... 84c40d5... M	libgeda/src/s_basic.c
:100644 100644 ff21ac2... 7a973ad... M	libgeda/src/s_page.c
:100644 100644 94a3857... beb9d72... M	libgeda/src/s_toplevel.c
:000000 100644 0000000... f78671a... A	libgeda/src/s_weakref.c

=========
 Changes
=========

commit f8ddb85e74bbf05a6901365527d27d3e2914ccec
Author: Peter TB Brett <peter@xxxxxxxxxxxxx>
Commit: Peter TB Brett <peter@xxxxxxxxxxxxx>

    libgeda: Add weak refs to OBJECT/PAGE/TOPLEVEL.
    
    Weak references are useful when you want to keep an eye on an object
    but not necessarily hang on to it when it comes to its useful life.
    
    This patch adds an internal libgeda API for using weak references.
    There are two types of weak references implemented by this patch:
    
    * full-powered weak references, where an arbitrary callback function
      can be registered on an object to be notified when an object is
      destroyed
    
    * weak pointers, which are set to NULL when the object is destroyed.
    
    This functionality will hopefully allow several pieces of housekeeping
    code in libgeda to be simplified.
    
    The API is designed to be as close as possible to the GObject weak ref
    API. See e.g. g_object_weak_ref().

diff --git a/libgeda/include/libgeda/prototype.h b/libgeda/include/libgeda/prototype.h
index 4e9cb0e..ad9608a 100644
--- a/libgeda/include/libgeda/prototype.h
+++ b/libgeda/include/libgeda/prototype.h
@@ -272,6 +272,10 @@ void print_struct_forw(GList *list);
 void print_struct(OBJECT *ptr);
 void s_delete_object(TOPLEVEL *toplevel, OBJECT *o_current);
 void s_delete_object_glist(TOPLEVEL *toplevel, GList *list);
+void s_object_weak_ref (OBJECT *object, void (*notify_func)(void *, void *), void *user_data);
+void s_object_weak_unref (OBJECT *object, void (*notify_func)(void *, void *), void *user_data);
+void s_object_add_weak_ptr (OBJECT *object, void *weak_pointer_loc);
+void s_object_remove_weak_ptr (OBJECT *object, void *weak_pointer_loc);
 char *remove_nl(char *string);
 char *remove_last_nl(char *string);
 gchar *s_expand_env_variables (const gchar *string);
@@ -352,6 +356,10 @@ void s_menu_init(void);
 PAGE *s_page_new (TOPLEVEL *toplevel, const gchar *filename);
 void s_page_delete (TOPLEVEL *toplevel, PAGE *page);
 void s_page_delete_list(TOPLEVEL *toplevel);
+void s_page_weak_ref (PAGE *page, void (*notify_func)(void *, void *), void *user_data);
+void s_page_weak_unref (PAGE *page, void (*notify_func)(void *, void *), void *user_data);
+void s_page_add_weak_ptr (PAGE *page, void *weak_pointer_loc);
+void s_page_remove_weak_ptr (PAGE *page, void *weak_pointer_loc);
 void s_page_goto (TOPLEVEL *toplevel, PAGE *p_new);
 PAGE *s_page_search (TOPLEVEL *toplevel, const gchar *filename);
 PAGE *s_page_search_by_page_id (GedaPageList *list, int pid);
@@ -386,6 +394,10 @@ char *s_path_string_from_path (const PATH *path);
 /* s_project.c */
 TOPLEVEL *s_toplevel_new (void);
 void s_toplevel_delete (TOPLEVEL *toplevel);
+void s_toplevel_weak_ref (TOPLEVEL *toplevel, void (*notify_func)(void *, void *), void *user_data);
+void s_toplevel_weak_unref (TOPLEVEL *toplevel, void (*notify_func)(void *, void *), void *user_data);
+void s_toplevel_add_weak_ptr (TOPLEVEL *toplevel, void *weak_pointer_loc);
+void s_toplevel_remove_weak_ptr (TOPLEVEL *toplevel, void *weak_pointer_loc);
 
 /* s_slib.c */
 int s_slib_add_entry(char *new_path);
diff --git a/libgeda/include/libgeda/struct.h b/libgeda/include/libgeda/struct.h
index 03e70e6..2abfbe2 100644
--- a/libgeda/include/libgeda/struct.h
+++ b/libgeda/include/libgeda/struct.h
@@ -290,6 +290,7 @@ struct st_object {
   OBJECT *attached_to;  /* when object is an attribute */
   OBJECT *copied_to;    /* used when copying attributes */
 
+  GList *weak_refs; /* Weak references */
 }; 
 
 
@@ -426,6 +427,7 @@ struct st_page {
   gint ops_since_last_backup;
   gchar do_autosave_backup;
 
+  GList *weak_refs; /* Weak references */
 };
 
 /*! \brief Type of callback function for calculating text bounds */
@@ -566,6 +568,8 @@ struct st_toplevel {
   /* Callback function for deciding whether to load a backup file. */
   LoadBackupQueryFunc load_newer_backup_func;
   void *load_newer_backup_data;
+
+  GList *weak_refs; /* Weak references */
 };
 
 /* structures below are for gnetlist */
diff --git a/libgeda/include/prototype_priv.h b/libgeda/include/prototype_priv.h
index 531afa9..9f6df1d 100644
--- a/libgeda/include/prototype_priv.h
+++ b/libgeda/include/prototype_priv.h
@@ -260,3 +260,10 @@ void s_tile_add_object(TOPLEVEL *toplevel, OBJECT *object);
 void s_tile_remove_object(OBJECT *object);
 void s_tile_print(TOPLEVEL *toplevel);
 void s_tile_free_all(PAGE *p_current);
+
+/* s_weakref.c */
+void s_weakref_notify (void *dead_ptr, GList *weak_refs);
+GList *s_weakref_add (GList *weak_refs, void (*notify_func)(void *, void *), void *user_data);
+GList *s_weakref_remove (GList *weak_refs, void (*notify_func)(void *, void *), void *user_data);
+GList *s_weakref_add_ptr (GList *weak_refs, void **weak_pointer_loc);
+GList *s_weakref_remove_ptr (GList *weak_refs, void **weak_pointer_loc);
diff --git a/libgeda/src/Makefile.am b/libgeda/src/Makefile.am
index 04ee412..ba66781 100644
--- a/libgeda/src/Makefile.am
+++ b/libgeda/src/Makefile.am
@@ -57,6 +57,7 @@ libgeda_la_SOURCES = \
 	s_tile.c \
 	s_toplevel.c \
 	s_undo.c \
+	s_weakref.c \
 	u_basic.c
 
 libgeda_la_CPPFLAGS = -DLOCALEDIR=\"$(localedir)\"  $(DATADIR_DEFS) \
diff --git a/libgeda/src/s_basic.c b/libgeda/src/s_basic.c
index 6af349c..84c40d5 100644
--- a/libgeda/src/s_basic.c
+++ b/libgeda/src/s_basic.c
@@ -140,6 +140,8 @@ OBJECT *s_basic_init_object(OBJECT *new_node, int type, char const *name)
   new_node->pin_type = PIN_TYPE_NET;
   new_node->whichend = -1;
 
+  new_node->weak_refs = NULL;
+
   return(new_node);
 }
 
@@ -305,6 +307,8 @@ s_delete_object(TOPLEVEL *toplevel, OBJECT *o_current)
 
     o_attrib_detach_all (toplevel, o_current);
 
+    s_weakref_notify (o_current, o_current->weak_refs);
+
     g_free(o_current);	/* assuming it is not null */
 
     o_current=NULL;		/* misc clean up */
@@ -334,6 +338,87 @@ s_delete_object_glist(TOPLEVEL *toplevel, GList *list)
   g_list_free(list);
 }
 
+/*! \brief Add a weak reference watcher to an OBJECT.
+ * \par Function Description
+ * Adds the weak reference callback \a notify_func to \a object.  When
+ * \a object is destroyed, \a notify_func will be called with two
+ * arguments: the \a object, and the \a user_data.
+ *
+ * \sa s_object_weak_unref
+ *
+ * \param [in] toplevel       The #TOPLEVEL structure.
+ * \param [in,out] object     Object to weak-reference.
+ * \param [in] notify_func    Weak reference notify function.
+ * \param [in] user_data      Data to be passed to \a notify_func.
+ */
+void
+s_object_weak_ref (OBJECT *object,
+                   void (*notify_func)(void *, void *),
+                   void *user_data)
+{
+  g_return_if_fail (object != NULL);
+  object->weak_refs = s_weakref_add (object->weak_refs, notify_func, user_data);
+}
+
+/*! \brief Remove a weak reference watcher from an OBJECT.
+ * \par Function Description
+ * Removes the weak reference callback \a notify_func from \a object.
+ *
+ * \sa s_object_weak_ref()
+ *
+ * \param [in] toplevel       The #TOPLEVEL structure.
+ * \param [in,out] object     Object to weak-reference.
+ * \param [in] notify_func    Notify function to search for.
+ * \param [in] user_data      Data to to search for.
+ */
+void
+s_object_weak_unref (OBJECT *object,
+                     void (*notify_func)(void *, void *),
+                     void *user_data)
+{
+  g_return_if_fail (object != NULL);
+  object->weak_refs = s_weakref_remove (object->weak_refs,
+                                        notify_func, user_data);
+}
+
+/*! \brief Add a weak pointer to an OBJECT.
+ * \par Function Description
+ * Adds the weak pointer at \a weak_pointer_loc to \a object. The
+ * value of \a weak_pointer_loc will be set to NULL when \a object is
+ * destroyed.
+ *
+ * \sa s_object_remove_weak_ptr
+ *
+ * \param [in] toplevel          The #TOPLEVEL structure.
+ * \param [in,out] object        Object to weak-reference.
+ * \param [in] weak_pointer_loc  Memory address of a pointer.
+ */
+void
+s_object_add_weak_ptr (OBJECT *object,
+                       void *weak_pointer_loc)
+{
+  g_return_if_fail (object != NULL);
+  object->weak_refs = s_weakref_add_ptr (object->weak_refs, weak_pointer_loc);
+}
+
+/*! \brief Remove a weak pointer from an OBJECT.
+ * \par Function Description
+ * Removes the weak pointer at \a weak_pointer_loc from \a object.
+ *
+ * \sa s_object_add_weak_ptr()
+ *
+ * \param [in] toplevel          The #TOPLEVEL structure.
+ * \param [in,out] object        Object to weak-reference.
+ * \param [in] weak_pointer_loc  Memory address of a pointer.
+ */
+void
+s_object_remove_weak_ptr (OBJECT *object,
+                          void *weak_pointer_loc)
+{
+  g_return_if_fail (object != NULL);
+  object->weak_refs = s_weakref_remove_ptr (object->weak_refs,
+                                            weak_pointer_loc);
+}
 
 /*! \todo Finish function documentation!!!
  *  \brief
diff --git a/libgeda/src/s_page.c b/libgeda/src/s_page.c
index ff21ac2..7a973ad 100644
--- a/libgeda/src/s_page.c
+++ b/libgeda/src/s_page.c
@@ -158,6 +158,8 @@ PAGE *s_page_new (TOPLEVEL *toplevel, const gchar *filename)
   s_undo_init(page);
   
   page->object_lastplace = NULL;
+
+  page->weak_refs = NULL;
   
   set_window (toplevel, page,
               toplevel->init_left, toplevel->init_right,
@@ -261,6 +263,8 @@ void s_page_delete (TOPLEVEL *toplevel, PAGE *page)
   s_tile_print (toplevel);
 #endif
 
+  s_weakref_notify (page, page->weak_refs);
+
   g_free (page);
 
   /* restore page_current */
@@ -302,6 +306,88 @@ void s_page_delete_list(TOPLEVEL *toplevel)
   toplevel->page_current = NULL;
 }
 
+/*! \brief Add a weak reference watcher to an PAGE.
+ * \par Function Description
+ * Adds the weak reference callback \a notify_func to \a page.  When
+ * \a page is destroyed, \a notify_func will be called with two
+ * arguments: the \a page, and the \a user_data.
+ *
+ * \sa s_page_weak_unref
+ *
+ * \param [in] toplevel       The #TOPLEVEL structure.
+ * \param [in,out] page       Page to weak-reference.
+ * \param [in] notify_func    Weak reference notify function.
+ * \param [in] user_data      Data to be passed to \a notify_func.
+ */
+void
+s_page_weak_ref (PAGE *page,
+                 void (*notify_func)(void *, void *),
+                 void *user_data)
+{
+  g_return_if_fail (page != NULL);
+  page->weak_refs = s_weakref_add (page->weak_refs, notify_func, user_data);
+}
+
+/*! \brief Remove a weak reference watcher from an PAGE.
+ * \par Function Description
+ * Removes the weak reference callback \a notify_func from \a page.
+ *
+ * \sa s_page_weak_ref()
+ *
+ * \param [in] toplevel       The #TOPLEVEL structure.
+ * \param [in,out] page       Page to weak-reference.
+ * \param [in] notify_func    Notify function to search for.
+ * \param [in] user_data      Data to to search for.
+ */
+void
+s_page_weak_unref (PAGE *page,
+                   void (*notify_func)(void *, void *),
+                   void *user_data)
+{
+  g_return_if_fail (page != NULL);
+  page->weak_refs = s_weakref_remove (page->weak_refs,
+                                      notify_func, user_data);
+}
+
+/*! \brief Add a weak pointer to an PAGE.
+ * \par Function Description
+ * Adds the weak pointer at \a weak_pointer_loc to \a page. The
+ * value of \a weak_pointer_loc will be set to NULL when \a page is
+ * destroyed.
+ *
+ * \sa s_page_remove_weak_ptr
+ *
+ * \param [in] toplevel          The #TOPLEVEL structure.
+ * \param [in,out] page          Page to weak-reference.
+ * \param [in] weak_pointer_loc  Memory address of a pointer.
+ */
+void
+s_page_add_weak_ptr (PAGE *page,
+                     void *weak_pointer_loc)
+{
+  g_return_if_fail (page != NULL);
+  page->weak_refs = s_weakref_add_ptr (page->weak_refs, weak_pointer_loc);
+}
+
+/*! \brief Remove a weak pointer from an PAGE.
+ * \par Function Description
+ * Removes the weak pointer at \a weak_pointer_loc from \a page.
+ *
+ * \sa s_page_add_weak_ptr()
+ *
+ * \param [in] toplevel          The #TOPLEVEL structure.
+ * \param [in,out] page          Page to weak-reference.
+ * \param [in] weak_pointer_loc  Memory address of a pointer.
+ */
+void
+s_page_remove_weak_ptr (PAGE *page,
+                        void *weak_pointer_loc)
+{
+  g_return_if_fail (page != NULL);
+  page->weak_refs = s_weakref_remove_ptr (page->weak_refs,
+                                          weak_pointer_loc);
+}
+
 /*! \brief changes the current page in toplevel
  *  \par Function Description
  *  Changes the current page in \a toplevel to the page \a p_new.
diff --git a/libgeda/src/s_toplevel.c b/libgeda/src/s_toplevel.c
index 94a3857..beb9d72 100644
--- a/libgeda/src/s_toplevel.c
+++ b/libgeda/src/s_toplevel.c
@@ -148,6 +148,7 @@ TOPLEVEL *s_toplevel_new (void)
   /* disable the events */
   toplevel->DONT_REDRAW = 1;
 
+  toplevel->weak_refs = NULL;
   return toplevel;
 }
 
@@ -180,6 +181,92 @@ void s_toplevel_delete (TOPLEVEL *toplevel)
   /* Delete the page list */
   g_object_unref(toplevel->pages);
 
+  s_weakref_notify (toplevel, toplevel->weak_refs);
+
   g_free (toplevel);
 
 }
+
+/*! \brief Add a weak reference watcher to an TOPLEVEL.
+ * \par Function Description
+ * Adds the weak reference callback \a notify_func to \a toplevel.  When
+ * \a toplevel is destroyed, \a notify_func will be called with two
+ * arguments: the \a toplevel, and the \a user_data.
+ *
+ * \sa s_toplevel_weak_unref
+ *
+ * \param [in] toplevel       The #TOPLEVEL structure.
+ * \param [in,out] toplevel   Toplevel to weak-reference.
+ * \param [in] notify_func    Weak reference notify function.
+ * \param [in] user_data      Data to be passed to \a notify_func.
+ */
+void
+s_toplevel_weak_ref (TOPLEVEL *toplevel,
+                     void (*notify_func)(void *, void *),
+                     void *user_data)
+{
+  g_return_if_fail (toplevel != NULL);
+  toplevel->weak_refs = s_weakref_add (toplevel->weak_refs,
+                                       notify_func, user_data);
+}
+
+/*! \brief Remove a weak reference watcher from an TOPLEVEL.
+ * \par Function Description
+ * Removes the weak reference callback \a notify_func from \a toplevel.
+ *
+ * \sa s_toplevel_weak_ref()
+ *
+ * \param [in] toplevel       The #TOPLEVEL structure.
+ * \param [in,out] toplevel       Toplevel to weak-reference.
+ * \param [in] notify_func    Notify function to search for.
+ * \param [in] user_data      Data to to search for.
+ */
+void
+s_toplevel_weak_unref (TOPLEVEL *toplevel,
+                       void (*notify_func)(void *, void *),
+                       void *user_data)
+{
+  g_return_if_fail (toplevel != NULL);
+  toplevel->weak_refs = s_weakref_remove (toplevel->weak_refs,
+                                          notify_func, user_data);
+}
+
+/*! \brief Add a weak pointer to an TOPLEVEL.
+ * \par Function Description
+ * Adds the weak pointer at \a weak_pointer_loc to \a toplevel. The
+ * value of \a weak_pointer_loc will be set to NULL when \a toplevel is
+ * destroyed.
+ *
+ * \sa s_toplevel_remove_weak_ptr
+ *
+ * \param [in] toplevel          The #TOPLEVEL structure.
+ * \param [in,out] toplevel      Toplevel to weak-reference.
+ * \param [in] weak_pointer_loc  Memory address of a pointer.
+ */
+void
+s_toplevel_add_weak_ptr (TOPLEVEL *toplevel,
+                         void *weak_pointer_loc)
+{
+  g_return_if_fail (toplevel != NULL);
+  toplevel->weak_refs = s_weakref_add_ptr (toplevel->weak_refs,
+                                           weak_pointer_loc);
+}
+
+/*! \brief Remove a weak pointer from an TOPLEVEL.
+ * \par Function Description
+ * Removes the weak pointer at \a weak_pointer_loc from \a toplevel.
+ *
+ * \sa s_toplevel_add_weak_ptr()
+ *
+ * \param [in] toplevel          The #TOPLEVEL structure.
+ * \param [in,out] toplevel      Toplevel to weak-reference.
+ * \param [in] weak_pointer_loc  Memory address of a pointer.
+ */
+void
+s_toplevel_remove_weak_ptr (TOPLEVEL *toplevel,
+                            void *weak_pointer_loc)
+{
+  g_return_if_fail (toplevel != NULL);
+  toplevel->weak_refs = s_weakref_remove_ptr (toplevel->weak_refs,
+                                              weak_pointer_loc);
+}
diff --git a/libgeda/src/s_weakref.c b/libgeda/src/s_weakref.c
new file mode 100644
index 0000000..f78671a
--- /dev/null
+++ b/libgeda/src/s_weakref.c
@@ -0,0 +1,153 @@
+/* gEDA - GPL Electronic Design Automation
+ * libgeda - gEDA's library
+ * Copyright (C) 2010 gEDA Contributors (see ChangeLog for details)
+ *
+ * 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 "libgeda_priv.h"
+
+/*!
+ * \file s_weakref.c
+ * \brief Utility functions for weak references and pointers.
+ *
+ * \warning Do not write code which relies on the order in which weak
+ * reference callback functions are notified.
+ */
+
+struct WeakRef
+{
+  void (*notify_func)(void *, void *);
+  void *user_data;
+};
+
+/*! \brief Notify weak reference watchers that a structure is dead.
+ * \par Function Description
+ * For each entry in \a weak_refs, call notify function with the dead
+ * pointer \a dead_ptr and the entry's specified user data, and free
+ * \a weak_refs. Should be called during destruction of an structure
+ * that allows weak references.
+ *
+ * \param [in] dead_ptr       Pointer to structure being destroyed.
+ * \param [in,out] weak_refs  List of registered weak references.
+ */
+void
+s_weakref_notify (void *dead_ptr, GList *weak_refs)
+{
+  GList *iter;
+  struct WeakRef *entry;
+  for (iter = weak_refs; iter != NULL; iter = g_list_next (iter)) {
+    entry = (struct WeakRef *) iter->data;
+    if (entry != NULL && entry->notify_func != NULL) {
+      entry->notify_func (dead_ptr, entry->user_data);
+    }
+    g_free (entry);
+  }
+  g_list_free (weak_refs);
+}
+
+/*! \brief Add a weak reference watcher to a weak ref list.
+ * \par Function Description
+ * Adds the weak reference callback \a notify_func to the weak
+ * reference list \a weak_refs, returning the new head of \a
+ * weak_refs. \a notify_func will be called with two arguments: a
+ * pointer to the object being destroyed, and the \a user_data.
+ *
+ * \param [in,out] weak_refs  List of registered weak references.
+ * \param [in] notify_func    Weak reference notify function.
+ * \param [in] user_data      Data to be passed to \a notify_func.
+ *
+ * \return new head of \a weak_refs list.
+ */
+GList *
+s_weakref_add (GList *weak_refs, void (*notify_func)(void *, void *),
+               void *user_data)
+{
+  struct WeakRef *entry = g_malloc0 (sizeof (struct WeakRef));
+  entry->notify_func = notify_func;
+  entry->user_data = user_data;
+  return g_list_prepend (weak_refs, entry);
+}
+
+/*! \brief Remove a weak reference watcher from a weak ref list.
+ * \par Function Description
+ * Removes a weak reference callback from the weak reference list \a
+ * weak_refs, returning the new head of \a weak_refs.
+ *
+ * \param [in,out] weak_refs    List of registered weak references.
+ * \param [in] notify_func      Notify function to search for.
+ * \param [in] user_data        User data to search for.
+ *
+ * \return new head of \a weak_refs list.
+ */
+GList *
+s_weakref_remove (GList *weak_refs, void (*notify_func)(void *, void *),
+                  void *user_data)
+{
+  GList *iter;
+  struct WeakRef *entry;
+  for (iter = weak_refs; iter != NULL; iter = g_list_next (iter)) {
+    entry = iter->data;
+    if ((entry != NULL) &&
+        (entry->notify_func == notify_func) &&
+        (entry->user_data != user_data)) {
+      g_free (entry);
+      iter->data = NULL;
+    }
+  }
+  return g_list_remove_all (weak_refs, NULL);
+}
+
+static void
+weak_ptr_notify_func (void *dead_ptr, void *user_data) {
+  void **weak_pointer_loc = (void **) user_data;
+  if (weak_pointer_loc != NULL) {
+    *weak_pointer_loc = NULL;
+  }
+}
+
+/*! \brief Add a weak pointer to a weak ref list.
+ * \par Function Description
+ * Adds a weak reference for \a weak_pointer_loc to the weak reference
+ * list \a weak_refs, returning the new head of \a weak_refs.
+ *
+ * \param [in,out] weak_refs     List of registered weak references.
+ * \param [in] weak_pointer_loc  Memory address of a pointer.
+ *
+ * \return new head of \a weak_refs list.
+ */
+GList *
+s_weakref_add_ptr (GList *weak_refs, void **weak_pointer_loc)
+{
+  return s_weakref_add (weak_refs, weak_ptr_notify_func, weak_pointer_loc);
+}
+
+/*! \brief Remove a weak pointer from a weak ref list.
+ * \par Function Description
+ * Removes the weak reference for \a weak_pointer_loc from the weak
+ * reference list \a weak_refs, returning the new head of \a
+ * weak_refs.
+ *
+ * \param [in,out] weak_refs     List of registered weak references.
+ * \param [in] weak_pointer_loc  Memory address of a pointer.
+ *
+ * \return new head of \a weak_refs list.
+ */
+GList *
+s_weakref_remove_ptr (GList *weak_refs, void **weak_pointer_loc)
+{
+  return s_weakref_remove (weak_refs, weak_ptr_notify_func, weak_pointer_loc);
+}




_______________________________________________
geda-cvs mailing list
geda-cvs@xxxxxxxxxxxxxx
http://www.seul.org/cgi-bin/mailman/listinfo/geda-cvs