gobject-introspection r543 - in trunk: girepository tools



Author: walters
Date: Sat Aug 30 20:31:12 2008
New Revision: 543
URL: http://svn.gnome.org/viewvc/gobject-introspection?rev=543&view=rev

Log:
Remove g_irepository_unregister, add GIRepositoryLoadFlags


Modified:
   trunk/girepository/girepository.c
   trunk/girepository/girepository.h
   trunk/tools/compiler.c
   trunk/tools/generate.c

Modified: trunk/girepository/girepository.c
==============================================================================
--- trunk/girepository/girepository.c	(original)
+++ trunk/girepository/girepository.c	Sat Aug 30 20:31:12 2008
@@ -35,6 +35,7 @@
 struct _GIRepositoryPrivate 
 {
   GHashTable *typelibs; /* (string) namespace -> GTypelib */
+  GHashTable *lazy_typelibs; /* (string) namespace -> GTypelib */
 };
 
 G_DEFINE_TYPE (GIRepository, g_irepository, G_TYPE_OBJECT);
@@ -44,6 +45,12 @@
 {
   repository->priv = G_TYPE_INSTANCE_GET_PRIVATE (repository, G_TYPE_IREPOSITORY,
 						  GIRepositoryPrivate);
+  repository->priv->typelibs 
+    = g_hash_table_new_full (g_str_hash, g_str_equal,
+			     (GDestroyNotify) NULL,
+			     (GDestroyNotify) g_typelib_free);
+  repository->priv->lazy_typelibs 
+    = g_hash_table_new (g_str_hash, g_str_equal);
 }
 
 static void
@@ -76,10 +83,6 @@
   if (default_repository == NULL) 
     { 
       default_repository = g_object_new (G_TYPE_IREPOSITORY, NULL);
-      default_repository->priv->typelibs 
-	= g_hash_table_new_full (g_str_hash, g_str_equal,
-				 (GDestroyNotify) NULL,
-				 (GDestroyNotify) g_typelib_free);
     }
 
   if (search_path == NULL)
@@ -135,13 +138,7 @@
 get_repository (GIRepository *repository)
 {
   if (repository != NULL)
-    {
-      if (repository->priv->typelibs == NULL)
-	repository->priv->typelibs = g_hash_table_new_full (g_str_hash, g_str_equal,
-                                                            (GDestroyNotify) NULL,
-                                                            (GDestroyNotify) g_typelib_free);
-      return repository;
-    }
+    return repository;
   else 
     {
       init_globals ();
@@ -149,51 +146,116 @@
     }
 }
 
-static const char *
-register_internal (GIRepository *repository,
-		   const char   *source,
-		   GTypelib     *typelib,
-		   GError      **error)
+static GTypelib *
+get_registered_status (GIRepository *repository,
+		       const char   *namespace,
+		       gboolean      allow_lazy,
+		       gboolean     *lazy_status)
 {
-  Header *header;
-  const gchar *name;
-  const char *dependencies_glob;
-  char **dependencies;
-
-  g_return_val_if_fail (typelib != NULL, FALSE);
-  
-  header = (Header *)typelib->data;
+  GTypelib *typelib;
+  repository = get_repository (repository);
+  if (lazy_status)
+    *lazy_status = FALSE;
+  typelib = g_hash_table_lookup (repository->priv->typelibs, namespace);
+  if (typelib)
+    return typelib;
+  typelib = g_hash_table_lookup (repository->priv->lazy_typelibs, namespace);
+  if (!typelib)
+    return NULL;
+  if (lazy_status)
+    *lazy_status = TRUE;
+  if (!allow_lazy)
+    return NULL;
+  return typelib;
+}
 
-  g_return_val_if_fail (header != NULL, FALSE);
+static GTypelib *
+get_registered (GIRepository *repository,
+		const char   *namespace)
+{
+  return get_registered_status (repository, namespace, TRUE, NULL);
+}
 
-  name = g_typelib_get_string (typelib, header->namespace);
+static gboolean
+load_dependencies_recurse (GIRepository *repository,
+			   GTypelib     *typelib,
+			   GError      **error)
+{
+  char **dependencies;
 
   dependencies = get_typelib_dependencies (typelib);
+
   if (dependencies != NULL)
     {
       int i;
-	
+	  
       for (i = 0; dependencies[i]; i++)
 	{
 	  char *dependency = dependencies[i];
-	  
-	  if (!g_irepository_require (repository, dependency, error))
+	      
+	  if (!g_irepository_require (repository, dependency, 
+				      0, error))
 	    {
 	      g_strfreev (dependencies);
-	      return NULL;
+	      return FALSE;
 	    }
 	}
       g_strfreev (dependencies);
     }
+  return TRUE;
+}
+			   
+static const char *
+register_internal (GIRepository *repository,
+		   const char   *source,
+		   gboolean      lazy,
+		   GTypelib     *typelib,
+		   GError      **error)
+{
+  Header *header;
+  const gchar *namespace;
+  gboolean was_loaded;
+  gboolean currently_lazy;
+
+  g_return_val_if_fail (typelib != NULL, FALSE);
+  
+  header = (Header *)typelib->data;
 
-  g_assert (g_hash_table_lookup (repository->priv->typelibs, name) == NULL);
-  g_hash_table_insert (repository->priv->typelibs, 
-		       build_typelib_key (name, source), (void *)typelib);
+  g_return_val_if_fail (header != NULL, FALSE);
+
+  namespace = g_typelib_get_string (typelib, header->namespace);
+
+  if (lazy)
+    {
+      g_assert (!g_hash_table_lookup (repository->priv->lazy_typelibs, 
+				      namespace));
+      g_hash_table_insert (repository->priv->lazy_typelibs, 
+			   build_typelib_key (namespace, source), (void *)typelib);
+    }
+  else
+    {
+      gpointer value;
+      char *key;
+
+      /* First, try loading all the dependencies */
+      if (!load_dependencies_recurse (repository, typelib, error))
+	return NULL;
+      
+      /* Check if we are transitioning from lazily loaded state */
+      if (g_hash_table_lookup_extended (repository->priv->lazy_typelibs, 
+					namespace,
+					(gpointer)&key, &value))
+	g_hash_table_remove (repository->priv->lazy_typelibs, key);
+      else
+	key = build_typelib_key (namespace, source);
+
+      g_hash_table_insert (repository->priv->typelibs, key, (void *)typelib);
+    }
 
   if (typelib->module == NULL)
       typelib->module = g_module_open (NULL, 0); 
 
-  return name;
+  return namespace;
 }
 
 char **
@@ -206,7 +268,7 @@
 
   repository = get_repository (repository);
 
-  typelib = g_hash_table_lookup (repository->priv->typelibs, namespace);
+  typelib = get_registered (repository, namespace);
   g_return_val_if_fail (typelib != NULL, NULL);
 
   return get_typelib_dependencies (typelib);
@@ -215,31 +277,23 @@
 const char *
 g_irepository_load_typelib (GIRepository *repository,
 			    GTypelib     *typelib,
+			    GIRepositoryLoadFlags flags,
 			    GError      **error)
 {
   Header *header;
   const char *namespace;
+  gboolean allow_lazy = flags & G_IREPOSITORY_LOAD_FLAG_LAZY;
+  gboolean is_lazy;
 
   repository = get_repository (repository);
 
   header = (Header *) typelib->data;
   namespace = g_typelib_get_string (typelib, header->namespace);
 
-  if (g_hash_table_lookup (repository->priv->typelibs, namespace))
+  if (get_registered_status (repository, namespace, allow_lazy, &is_lazy))
     return namespace;
-  return register_internal (repository, "<builtin>", typelib, error);
-}
-
-void
-g_irepository_unregister (GIRepository *repository,
-                          const gchar  *namespace)
-{
-  repository = get_repository (repository);
-
-  if (!g_hash_table_remove (repository->priv->typelibs, namespace))
-    {
-      g_printerr ("namespace '%s' not registered\n", namespace);
-    }
+  return register_internal (repository, "<builtin>", 
+			    allow_lazy, typelib, error);
 }
 
 gboolean
@@ -247,8 +301,7 @@
 			     const gchar *namespace)
 {
   repository = get_repository (repository);
-
-  return g_hash_table_lookup (repository->priv->typelibs, namespace) != NULL;
+  return get_registered (repository, namespace) != NULL;
 }
 
 GIRepository * 
@@ -280,7 +333,7 @@
     {
       GTypelib *typelib;
 
-      typelib = g_hash_table_lookup (repository->priv->typelibs, namespace);
+      typelib = get_registered (repository, namespace);
 
       if (typelib)
 	n_interfaces = ((Header *)typelib->data)->n_local_entries;
@@ -289,6 +342,8 @@
     {
       g_hash_table_foreach (repository->priv->typelibs, 
 			    count_interfaces, &n_interfaces);
+      g_hash_table_foreach (repository->priv->lazy_typelibs, 
+			    count_interfaces, &n_interfaces);
     }
 
   return n_interfaces;
@@ -384,13 +439,16 @@
     {
       GTypelib *typelib;
       
-      typelib = g_hash_table_lookup (repository->priv->typelibs, namespace);
+      typelib = get_registered (repository, namespace);
       
       if (typelib)
 	find_interface ((void *)namespace, typelib, &data);
     }
   else
-    g_hash_table_foreach (repository->priv->typelibs, find_interface, &data);
+    {
+      g_hash_table_foreach (repository->priv->typelibs, find_interface, &data);
+      g_hash_table_foreach (repository->priv->lazy_typelibs, find_interface, &data);
+    }
 
   return data.iface;  
 }
@@ -409,6 +467,7 @@
   data.iface = NULL;
 
   g_hash_table_foreach (repository->priv->typelibs, find_interface, &data);
+  g_hash_table_foreach (repository->priv->lazy_typelibs, find_interface, &data);
 
   return data.iface;
 }
@@ -442,13 +501,16 @@
     {
       GTypelib *typelib;
       
-      typelib = g_hash_table_lookup (repository->priv->typelibs, namespace);
+      typelib = get_registered (repository, namespace);
       
       if (typelib)
 	find_interface ((void *)namespace, typelib, &data);
     }
   else
-    g_hash_table_foreach (repository->priv->typelibs, find_interface, &data);
+    {
+      g_hash_table_foreach (repository->priv->typelibs, find_interface, &data);
+      g_hash_table_foreach (repository->priv->lazy_typelibs, find_interface, &data);
+    }
 
   return data.iface;
 }
@@ -483,6 +545,7 @@
   repository = get_repository (repository);
 
   g_hash_table_foreach (repository->priv->typelibs, collect_namespaces, &list);
+  g_hash_table_foreach (repository->priv->lazy_typelibs, collect_namespaces, &list);
 
   names = g_malloc0 (sizeof (gchar *) * (g_list_length (list) + 1));
   i = 0;
@@ -502,7 +565,7 @@
 
   repository = get_repository (repository);
 
-  typelib = g_hash_table_lookup (repository->priv->typelibs, namespace);
+  typelib = get_registered (repository, namespace);
   if (!typelib)
     return NULL;
   header = (Header *) typelib->data;
@@ -535,7 +598,12 @@
 
   if (!g_hash_table_lookup_extended (repository->priv->typelibs, namespace,
 				     &orig_key, &value))
-    return NULL;
+    {
+      if (!g_hash_table_lookup_extended (repository->priv->lazy_typelibs, namespace,
+					 &orig_key, &value))
+	
+	return NULL;
+    }
   return ((char*)orig_key) + strlen ((char *) orig_key) + 1;
 }
 
@@ -543,6 +611,7 @@
  * g_irepository_require
  * @repository: Repository, may be %NULL for the default
  * @namespace: GI namespace to use, e.g. "Gtk"
+ * @flags: Set of %GIRepositoryLoadFlags, may be %0
  * @error: a #GError.
  *
  * Force the namespace @namespace to be loaded if it isn't
@@ -555,6 +624,7 @@
 gboolean
 g_irepository_require (GIRepository  *repository,
 		       const gchar   *namespace,
+		       GIRepositoryLoadFlags flags,
 		       GError       **error)
 {
   GSList *ldir;
@@ -566,13 +636,12 @@
   const gchar *typelib_namespace, *shlib_fname;
   GModule *module;
   guint32 shlib;
-  GHashTable *table;
+  gboolean allow_lazy = flags & G_IREPOSITORY_LOAD_FLAG_LAZY;
+  gboolean is_lazy;
 
   repository = get_repository (repository);
-  table = repository->priv->typelibs;
 
-  /* don't bother loading a namespace if already registered */
-  if (g_hash_table_lookup (table, namespace))
+  if (get_registered_status (repository, namespace, allow_lazy, &is_lazy))
     return TRUE;
 
   fname = g_strconcat (namespace, ".typelib", NULL);
@@ -617,7 +686,8 @@
     }
 
   g_free (fname);
-  if (!register_internal (repository, full_path, typelib, error))
+  if (!register_internal (repository, full_path, allow_lazy, 
+			  typelib, error))
     {
       g_typelib_free (typelib);
       g_free (full_path);

Modified: trunk/girepository/girepository.h
==============================================================================
--- trunk/girepository/girepository.h	(original)
+++ trunk/girepository/girepository.h	Sat Aug 30 20:31:12 2008
@@ -67,6 +67,10 @@
   GObjectClass parent; 
 };
 
+typedef enum
+{
+  G_IREPOSITORY_LOAD_FLAG_LAZY = 1 << 0
+} GIRepositoryLoadFlags;
 
 /* Repository */
 
@@ -75,9 +79,8 @@
 void          g_irepository_prepend_search_path (const char *directory);
 const char *  g_irepository_load_typelib  (GIRepository *repository,
 					   GTypelib     *typelib,
+					   GIRepositoryLoadFlags flags,
 					   GError      **error);
-void          g_irepository_unregister    (GIRepository *repository,
-					   const gchar  *namespace);
 gboolean      g_irepository_is_registered (GIRepository *repository, 
 					   const gchar  *namespace);
 GIBaseInfo *  g_irepository_find_by_name  (GIRepository *repository,
@@ -85,6 +88,7 @@
 					   const gchar  *name);
 gboolean      g_irepository_require       (GIRepository *repository,
 					   const char   *namespace,
+					   GIRepositoryLoadFlags flags,
 					   GError      **error);
 gchar      ** g_irepository_get_dependencies (GIRepository *repository,
 					      const char *namespace);

Modified: trunk/tools/compiler.c
==============================================================================
--- trunk/tools/compiler.c	(original)
+++ trunk/tools/compiler.c	Sat Aug 30 20:31:12 2008
@@ -81,16 +81,8 @@
 			      "{\n"
 			      "\tGTypelib *typelib;\n"
 			      "\ttypelib = g_typelib_new_from_const_memory (_G_TYPELIB, _G_TYPELIB_SIZE);\n"
-			      "\tg_irepository_load_typelib (NULL, typelib, NULL);\n"
+			      "\tg_irepository_load_typelib (NULL, typelib, G_IREPOSITORY_LOAD_FLAG_LAZY, NULL);\n"
 			      "}\n\n");
-
-      g_string_append_printf (result,
-			      "__attribute__((destructor)) void\n"
-			      "unregister_typelib (void)\n"
-			      "{\n"
-			      "\tg_irepository_unregister (NULL, \"%s\");\n"
-			      "}\n",
-			      g_typelib_get_namespace (typelib));
     }
 
   return g_string_free (result, FALSE);

Modified: trunk/tools/generate.c
==============================================================================
--- trunk/tools/generate.c	(original)
+++ trunk/tools/generate.c	Sat Aug 30 20:31:12 2008
@@ -1246,7 +1246,7 @@
 	  return 1;
         }
       }
-      namespace = g_irepository_load_typelib (g_irepository_get_default (), data,
+      namespace = g_irepository_load_typelib (g_irepository_get_default (), data, 0,
 					      &error);
       if (namespace == NULL)
 	{



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