Enlightenment CVS committal

Author  : onefang
Project : e17
Module  : apps/e

Dir     : e17/apps/e/src/bin


Modified Files:
        e_apps.c e_apps.h 


Log Message:
*Once an icon has been found, or found to not exist, save that info in
the E_App, update related aE_Apps, and send trigger change callbacks.

*Have all E_Apps stored in a hash of paths for faster lookup.

*Don't read in all the details of every app at startup, but do scan the
all directory so that we at least know the filenames.  Read in details
when needed.

*When searching the non path info of apps, read in data as needed.

Most app things should be faster now.  Some things may be slower, and
much more testing / tweaking will be done.

===================================================================
RCS file: /cvs/e/e17/apps/e/src/bin/e_apps.c,v
retrieving revision 1.200
retrieving revision 1.201
diff -u -3 -r1.200 -r1.201
--- e_apps.c    25 Sep 2006 15:19:09 -0000      1.200
+++ e_apps.c    29 Sep 2006 08:55:39 -0000      1.201
@@ -33,6 +33,7 @@
 };
 
 
+static Evas_Bool _e_apps_hash_cb_init(Evas_Hash *hash, const char *key, void 
*data, void *fdata);
 static void      _e_app_free               (E_App *a);
 static E_App     *_e_app_subapp_file_find  (E_App *a, const char *file);
 static int        _e_app_new_save          (E_App *a);    
@@ -42,6 +43,7 @@
 static void      _e_app_subdir_rescan      (E_App *app);
 static int       _e_app_is_eapp            (const char *path);
 static int       _e_app_copy               (E_App *dst, E_App *src);
+static void      _e_app_fields_save_others(E_App *a);
 static void      _e_app_save_order         (E_App *app);
 static int       _e_app_cb_event_border_add(void *data, int type, void *event);
 static int       _e_app_cb_expire_timer    (void *data);
@@ -66,6 +68,7 @@
 static const char  *_e_apps_path_all = NULL;
 static const char  *_e_apps_path_trash = NULL;
 static Evas_List   *_e_apps_start_pending = NULL;
+static Evas_Hash   *_e_apps_every_app = NULL;
 
 #define EAP_MIN_WIDTH 8
 #define EAP_MIN_HEIGHT 8
@@ -115,8 +118,10 @@
 EAPI int
 e_app_init(void)
 {
+   Ecore_List  *_e_apps_all_filenames = NULL;
    const char *home;
    char buf[PATH_MAX];
+   double begin;
    
    home = e_user_homedir_get();
    snprintf(buf, sizeof(buf), "%s/.e/e/applications/trash", home);
@@ -127,7 +132,25 @@
    _e_apps_exit_handler = ecore_event_handler_add(ECORE_EXE_EVENT_DEL, 
_e_apps_cb_exit, NULL);
    _e_apps_border_add_handler = ecore_event_handler_add(E_EVENT_BORDER_ADD, 
_e_app_cb_event_border_add, NULL);
    ecore_desktop_instrumentation_reset();
-   _e_apps_all = e_app_new(buf, 1);
+   begin = ecore_time_get();
+   _e_apps_all_filenames = ecore_file_ls(_e_apps_path_all);
+   if (_e_apps_all_filenames)
+     {
+        const char *file;
+
+        while ((file = ecore_list_next(_e_apps_all_filenames)))
+         {
+            E_App *app;
+
+             app = e_app_empty_new(file);
+            if ((app) && (app->path))
+                _e_apps_every_app = evas_hash_direct_add(_e_apps_every_app, 
app->path, app);
+         }
+        ecore_list_destroy(_e_apps_all_filenames);
+     }
+   _e_apps_all = e_app_new(_e_apps_path_all, 0);
+   evas_hash_foreach(_e_apps_every_app, _e_apps_hash_cb_init, NULL);
+   printf("INITIAL APP SCAN %3.3f\n", ecore_time_get() - begin);
 #if NO_APP_LIST
    /* The list already exists, and it doesn't care what order it is in. */
    if (_e_apps_all)
@@ -137,6 +160,23 @@
    return 1;
 }
 
+static Evas_Bool 
+_e_apps_hash_cb_init(Evas_Hash *hash, const char *key, void *data, void *fdata)
+{
+   E_App *a;
+
+   a = data;
+   /* Link it in to all if needed. */
+   if ((!a->parent) && (_e_apps_all) && strncmp(a->path, _e_apps_path_all, 
strlen(_e_apps_path_all)) == 0)
+     {
+        a->parent = _e_apps_all;
+        _e_apps_all->subapps = evas_list_append(_e_apps_all->subapps, a);
+        e_object_ref(E_OBJECT(a));
+     }
+   return 1;
+}
+
+
 EAPI int
 e_app_shutdown(void)
 {
@@ -172,9 +212,12 @@
             printf("BUG: References %d %s\n", E_OBJECT(a)->references, 
a->path);
          }
      }
+   evas_hash_free(_e_apps_every_app);
+   _e_apps_every_app = NULL;
    return 1;
 }
 
+
 EAPI void
 e_app_unmonitor_all(void)
 {
@@ -226,23 +269,13 @@
          e_object_ref(E_OBJECT(a));
       }
 
-   if (!a)
+   if ((!a) && (ecore_file_exists(path)))
      {
-       if (ecore_file_exists(path))
-         {
-            a = E_OBJECT_ALLOC(E_App, E_APP_TYPE, _e_app_free);
-            
-            if (a)
-               {
-                  /* no image for now */
-                  a->image = NULL;
-                  a->width = 0;
-                  a->height = 0;
-                  /* record the path */
-                  a->path = evas_stringshare_add(path);
-               }
-          }
-      }
+        /* Create it and add it to the cache. */
+        a = e_app_empty_new(path);
+       if (a)
+           _e_apps_every_app = evas_hash_direct_add(_e_apps_every_app, 
a->path, a);
+     }
 
    if ((a) && (a->path))
       {
@@ -265,9 +298,11 @@
                if ((!stated) && (strcmp(_e_apps_path_all, a->path) != 0))
                  a->monitor = ecore_file_monitor_add(a->path, 
_e_app_cb_monitor, a);
            }
-        else if (_e_app_is_eapp(path))
+        else if (_e_app_is_eapp(a->path))
            {
-               e_app_fields_fill(a, path);
+               if (!a->filled)
+                  e_app_fields_fill(a, a->path);
+//                _e_apps_hash_cb_init(_e_apps_every_app, a->path, a, NULL);
                  
                /* no exe field.. not valid. drop it */
 //               if (!_e_app_exe_valid_get(a->exe))
@@ -308,15 +343,22 @@
    E_App *a;
    
    a = E_OBJECT_ALLOC(E_App, E_APP_TYPE, _e_app_free);
-   a->image = NULL;
-   if (path) a->path = evas_stringshare_add(path);   
-   else if ((_e_apps_all) && (_e_apps_all->path))
+   if (a)
      {
-       char buf[4096];
+        /* no image for now */
+        a->image = NULL;
+       a->width = 0;
+       a->height = 0;
+       /* record the path, or make one up */
+        if (path)
+          a->path = evas_stringshare_add(path);   
+        else if (_e_apps_path_all)
+          {
+            char buf[PATH_MAX];
 
-       snprintf(buf, sizeof(buf), "%s/_new_app_%1.1f.desktop", 
-                _e_apps_all->path, ecore_time_get());
-       a->path = evas_stringshare_add(buf);
+            snprintf(buf, sizeof(buf), "%s/_new_app_%1.1f.desktop", 
_e_apps_path_all, ecore_time_get());
+            a->path = evas_stringshare_add(buf);
+          }
      }
    return a;
 }
@@ -429,7 +471,6 @@
          }
        ecore_list_destroy(files);
      }
-
 }
 
 EAPI int
@@ -695,8 +736,10 @@
        if (ecore_file_exists(buf))
          snprintf(buf, sizeof(buf), "%s/%s", parent->path, 
ecore_file_get_file(add->path));
        ecore_file_mv(add->path, buf);
+        _e_apps_every_app = evas_hash_del(_e_apps_every_app, add->path, add);
        evas_stringshare_del(add->path);
        add->path = evas_stringshare_add(buf);
+        _e_apps_every_app = evas_hash_direct_add(_e_apps_every_app, add->path, 
add);
      }
 
    _e_app_save_order(parent);
@@ -810,8 +853,10 @@
        /* Move to trash */
        snprintf(buf, sizeof(buf), "%s/%s", _e_apps_path_trash, 
ecore_file_get_file(a->path));
        ecore_file_mv(a->path, buf);
+        _e_apps_every_app = evas_hash_del(_e_apps_every_app, a->path, a);
        evas_stringshare_del(a->path);
        a->path = evas_stringshare_add(buf);
+        _e_apps_every_app = evas_hash_direct_add(_e_apps_every_app, a->path, 
a);
      }
    _e_app_save_order(a->parent);
    for (l = a->references; l; l = l->next)
@@ -928,6 +973,8 @@
        a = l->data;
         E_OBJECT_CHECK_RETURN(a, NULL);
         E_OBJECT_TYPE_CHECK_RETURN(a, E_APP_TYPE, NULL);
+        if (!a->filled)
+          e_app_fields_fill(a, a->path);
        ok = 0;
        if ((a->win_name) || (a->win_class) || (a->win_title) || (a->win_role) 
|| (a->exe))
          {
@@ -1023,31 +1070,11 @@
 EAPI E_App *
 e_app_path_find(const char *path)
 {
-   Evas_List *l;
-   
-   if (!path) return NULL;
+   E_App *a = NULL;
 
-   if (_e_apps_list)
-      {
-         for (l = _e_apps_list; l; l = l->next)
-           {
-             E_App *a;
-       
-             a = l->data;
-              E_OBJECT_CHECK_RETURN(a, NULL);
-              E_OBJECT_TYPE_CHECK_RETURN(a, E_APP_TYPE, NULL);
-             if (a->path)
-               {
-                  if (!strcmp(a->path, path))
-                     {
-//                      _e_apps_list = evas_list_remove_list(_e_apps_list, l);
-//                      _e_apps_list = evas_list_prepend(_e_apps_list, a);
-                        return a;
-                     }
-               }
-           }
-      }
-   return NULL;
+   if ((path) && (_e_apps_every_app))
+      a = evas_hash_find(_e_apps_every_app, path);
+   return a;
 }
 
 EAPI E_App *
@@ -1064,6 +1091,8 @@
        a = l->data;
         E_OBJECT_CHECK_RETURN(a, NULL);
         E_OBJECT_TYPE_CHECK_RETURN(a, E_APP_TYPE, NULL);
+        if (!a->filled)
+          e_app_fields_fill(a, a->path);
        if (a->name)
          {
             if (!strcasecmp(a->name, name))
@@ -1091,6 +1120,8 @@
        a = l->data;
         E_OBJECT_CHECK_RETURN(a, NULL);
         E_OBJECT_TYPE_CHECK_RETURN(a, E_APP_TYPE, NULL);
+        if (!a->filled)
+          e_app_fields_fill(a, a->path);
        if (a->generic)
          {
             if (!strcasecmp(a->generic, generic))
@@ -1118,6 +1149,8 @@
        a = l->data;
         E_OBJECT_CHECK_RETURN(a, NULL);
         E_OBJECT_TYPE_CHECK_RETURN(a, E_APP_TYPE, NULL);
+        if (!a->filled)
+          e_app_fields_fill(a, a->path);
        if (a->exe)
          {
             if (!strcmp(a->exe, exe))
@@ -1147,6 +1180,8 @@
        a = l->data;
         E_OBJECT_CHECK_RETURN(a, NULL);
         E_OBJECT_TYPE_CHECK_RETURN(a, E_APP_TYPE, NULL);
+        if (!a->filled)
+          e_app_fields_fill(a, a->path);
        if (a->name)
          {
             if (e_util_glob_case_match(a->name, name))
@@ -1170,6 +1205,8 @@
        a = l->data;
         E_OBJECT_CHECK_RETURN(a, NULL);
         E_OBJECT_TYPE_CHECK_RETURN(a, E_APP_TYPE, NULL);
+        if (!a->filled)
+          e_app_fields_fill(a, a->path);
        if (a->generic)
          {
             if (e_util_glob_case_match(a->generic, generic))
@@ -1193,6 +1230,8 @@
        a = l->data;
         E_OBJECT_CHECK_RETURN(a, NULL);
         E_OBJECT_TYPE_CHECK_RETURN(a, E_APP_TYPE, NULL);
+        if (!a->filled)
+          e_app_fields_fill(a, a->path);
        if (a->exe)
          {
             if (e_util_glob_match(a->exe, exe))
@@ -1216,6 +1255,8 @@
        a = l->data;
         E_OBJECT_CHECK_RETURN(a, NULL);
         E_OBJECT_TYPE_CHECK_RETURN(a, E_APP_TYPE, NULL);
+        if (!a->filled)
+          e_app_fields_fill(a, a->path);
        if (a->comment)
          {
             if (e_util_glob_case_match(a->comment, comment))
@@ -1242,6 +1283,7 @@
        lang = NULL;
      }
    if (!path) path = a->path;
+   if (!path) return;
 
    ext = strrchr(path, '.');
    if ((ext) && (strcmp(ext, ".desktop") == 0))
@@ -1271,6 +1313,7 @@
            a->startup_notify = desktop->startup;
            a->wait_exit = desktop->wait_exit;
            a->dirty_icon = 0;
+          a->filled = 1;
 
 //        if (desktop->type)  a->type = evas_stringshare_add(desktop->type);
 //        if (desktop->categories)  a->categories = 
evas_stringshare_add(desktop->categories);
@@ -1329,6 +1372,7 @@
           free(v);
         }
       eet_close(ef);
+      a->filled = 1;
    }
 }
 
@@ -1358,6 +1402,7 @@
    return eet_read(ef, field, size);
 }
 
+
 EAPI void
 e_app_fields_save(E_App *a)
 {
@@ -1372,7 +1417,7 @@
       ext = ecore_file_get_file(a->path);
    if ( (!a->path) || ((strncmp(ext, "_new_app_", 9) == 0) && 
(!ecore_file_exists(a->path))) )
       {
-         snprintf(buf, sizeof(buf), "%s/%s.desktop", _e_apps_all->path, 
a->name);
+         snprintf(buf, sizeof(buf), "%s/%s.desktop", _e_apps_path_all, 
a->name);
         if (a->path)  evas_stringshare_del(a->path);
         a->path = evas_stringshare_add(buf);
       }
@@ -1381,15 +1426,15 @@
    if (!ecore_file_exists(a->path))
       {
          /* Force it to be in all. */
-         snprintf(buf, sizeof(buf), "%s/%s", _e_apps_all->path, 
ecore_file_get_file(a->path));
+         snprintf(buf, sizeof(buf), "%s/%s", _e_apps_path_all, 
ecore_file_get_file(a->path));
         if (a->path)  evas_stringshare_del(a->path);
         a->path = evas_stringshare_add(buf);
       }
    if (!a->path)  return;
-   if (!ecore_file_exists(a->path))
-      {
-         new_eap = 1;
-      }
+   if (ecore_file_exists(a->path))
+      _e_apps_every_app = evas_hash_del(_e_apps_every_app, a->path, a);
+   else
+      new_eap = 1;
 
    ext = strrchr(a->path, '.');
    if ((ext) && (strcmp(ext, ".desktop") == 0))
@@ -1540,6 +1585,7 @@
          eet_close(ef);
       }
 
+   _e_apps_every_app = evas_hash_direct_add(_e_apps_every_app, a->path, a);
    if (new_eap)
       {
          /* Careful, if this is being created from the border icon, this E_App 
is already part of the border. */
@@ -1550,39 +1596,45 @@
         _e_app_change(a, E_APP_ADD);
       }
    else
-      {
-         Evas_List *l;
+      _e_app_fields_save_others(a);
+}
 
-         for (l = a->references; l; l = l->next)
-            {
-              E_App *a2;
+static void
+_e_app_fields_save_others(E_App *a)
+{
+   Evas_List *l;
+   char buf[PATH_MAX];
+
+   for (l = a->references; l; l = l->next)
+     {
+        E_App *a2;
             
-              a2 = l->data;
-              if (_e_app_copy(a2, a)) _e_app_change(a2, E_APP_CHANGE);
-            }
-         if (a->orig)
-            {
-              E_App *a2;
+       a2 = l->data;
+       if (_e_app_copy(a2, a)) _e_app_change(a2, E_APP_CHANGE);
+     }
+   if (a->orig)
+     {
+       E_App *a2;
             
-              a2 = a->orig;
-              if (_e_app_copy(a2, a)) _e_app_change(a2, E_APP_CHANGE);
-            }
-         _e_app_change(a, E_APP_CHANGE);
-         if (a->parent)
-            {
-              snprintf(buf, sizeof(buf), "%s/.eap.cache.cfg", a->parent->path);
-              ecore_file_unlink(buf);
-              _e_app_change(a->parent, E_APP_CHANGE);
-              /* I don't think we need to rescan.
-               * A) we should be changing all the relevant stuff here.
-               * B) monitoring will catch other changes.
-               * C) it's a waste of time.
-              _e_app_subdir_rescan(a->parent);
-              */
-            }
-      }
+       a2 = a->orig;
+       if (_e_app_copy(a2, a)) _e_app_change(a2, E_APP_CHANGE);
+     }
+   _e_app_change(a, E_APP_CHANGE);
+   if (a->parent)
+     {
+       snprintf(buf, sizeof(buf), "%s/.eap.cache.cfg", a->parent->path);
+       ecore_file_unlink(buf);
+       _e_app_change(a->parent, E_APP_CHANGE);
+       /* I don't think we need to rescan.
+        * A) we should be changing all the relevant stuff here.
+        * B) monitoring will catch other changes.
+        * C) it's a waste of time.
+       _e_app_subdir_rescan(a->parent);
+        */
+     }
 }
 
+
 EAPI void
 e_app_fields_empty(E_App *a)
 {
@@ -1614,6 +1666,7 @@
    a->win_title = NULL;
    a->win_role = NULL;
    a->dirty_icon = 0;
+   a->filled = 0;
 }
 
 EAPI Ecore_List *
@@ -1740,6 +1793,33 @@
       e_menu_item_icon_file_set(mi, a->icon_path);
 }
 
+static void
+_e_app_fdo_icon_search(E_App *a)
+{
+   if ((!a->no_icon) && (a->icon_class))
+     {
+        char *v = NULL;
+                 
+       /* FIXME: Use a real icon size. */
+       v = (char *)ecore_desktop_icon_find(a->icon_class, NULL, 
e_config->icon_theme);
+       if (v)
+         {
+             if (a->icon_path) evas_stringshare_del(a->icon_path);
+            a->icon_path = evas_stringshare_add(v);
+            if (e_config->icon_theme)
+              {
+                  if (a->icon_theme) evas_stringshare_del(a->icon_theme);
+                 a->icon_theme = evas_stringshare_add(e_config->icon_theme);
+              }
+            a->dirty_icon = 1;
+            free(v);
+         }
+        else
+           a->no_icon = 1;
+        /* Copy the new found icon data to the original. */
+        _e_app_fields_save_others(a);
+      }
+}
 
 EAPI Evas_Object *
 e_app_icon_add(Evas *evas, E_App *a)
@@ -1773,25 +1853,8 @@
               {
                  ;  /* It's a bit more obvious this way. */
               }
-            else if (a->icon_class)   /* If that fails, then this might be an 
FDO icon. */
-              {
-                 char *v = NULL;
-                 
-                 /* FIXME: Use a real icon size. */
-                 v = (char *)ecore_desktop_icon_find(a->icon_class, NULL, 
e_config->icon_theme);
-                 if (v)
-                   {
-                       if (a->icon_path) evas_stringshare_del(a->icon_path);
-                      a->icon_path = evas_stringshare_add(v);
-                      if (e_config->icon_theme)
-                        {
-                            if (a->icon_theme) 
evas_stringshare_del(a->icon_theme);
-                           a->icon_theme = 
evas_stringshare_add(e_config->icon_theme);
-                        }
-                      a->dirty_icon = 1;
-                      free(v);
-                   }
-              }
+            else /* If that fails, then this might be an FDO icon. */
+                _e_app_fdo_icon_search(a);
             
             if (a->icon_path)
               {
@@ -1843,28 +1906,9 @@
          if (!e_util_menu_item_edje_icon_list_set(mi, a->icon_class))
            {
                if (edje_file_group_exists(a->path, "icon"))
-                 {
-                     e_menu_item_icon_edje_set(mi, a->path, "icon");
-                 }
-               else if ((a->icon_class))   /* If that fails, then this might 
be an FDO icon. */
-                  {
-                     char *v;
-
-                    /* FIXME: Use a real icon size. */
-                    v = (char *) ecore_desktop_icon_find(a->icon_class, NULL, 
e_config->icon_theme);
-                    if (v)
-                       {
-                           if (a->icon_path) 
evas_stringshare_del(a->icon_path);
-                          a->icon_path = evas_stringshare_add(v);
-                          if (e_config->icon_theme)
-                            {
-                                if (a->icon_theme) 
evas_stringshare_del(a->icon_theme);
-                               a->icon_theme = 
evas_stringshare_add(e_config->icon_theme);
-                            }
-                          a->dirty_icon = 1;
-                          free(v);
-                       }
-                  }
+                  e_menu_item_icon_edje_set(mi, a->path, "icon");
+               else /* If that fails, then this might be an FDO icon. */
+                  _e_app_fdo_icon_search(a);
 
                if (a->icon_path)
                   _e_app_icon_path_add_to_menu_item(mi, a);
@@ -2049,7 +2093,11 @@
        _e_apps_list = evas_list_remove(_e_apps_list, a);
 #endif
        e_app_fields_empty(a);
-       if (a->path) evas_stringshare_del(a->path);
+       if (a->path)
+         {
+             _e_apps_every_app = evas_hash_del(_e_apps_every_app, a->path, a);
+             evas_stringshare_del(a->path);
+         }
        free(a);
      }
 }
@@ -2087,7 +2135,7 @@
    for (l = _e_apps_change_callbacks; l; l = l->next)
      {
        E_App_Callback *cb;
-       
+
        cb = l->data;
        if (!cb->delete_me) cb->func(cb->data, a, ch);
      }
@@ -2458,6 +2506,7 @@
    dst->starting = src->starting;
    dst->scanned = src->scanned;
    dst->dirty_icon = src->dirty_icon;
+   dst->filled = src->filled;
 
    return 1;
 }
@@ -2487,7 +2536,7 @@
      {
        char buf[PATH_MAX];
        
-       snprintf(buf, sizeof(buf), "%s/.eap.cache.cfg", app    ->parent->path);
+       snprintf(buf, sizeof(buf), "%s/.eap.cache.cfg", app->parent->path);
        ecore_file_unlink(buf);
      }
 }
===================================================================
RCS file: /cvs/e/e17/apps/e/src/bin/e_apps.h,v
retrieving revision 1.44
retrieving revision 1.45
diff -u -3 -r1.44 -r1.45
--- e_apps.h    25 Sep 2006 14:17:42 -0000      1.44
+++ e_apps.h    29 Sep 2006 08:55:39 -0000      1.45
@@ -68,6 +68,8 @@
 
    unsigned char       deleted : 1; /* this app's file is deleted from disk */
 
+   unsigned char       filled : 1; /* this app has had its data filled in */
+   unsigned char       no_icon : 1; /* this app's icon has not been found in 
the current theme, future searhes should give up early . */
    unsigned char       dirty_icon : 1; /* this app's icon has been found, and 
the on disk cache needs to be updated. */
 
    /* Actually calling this st_mtime causes compile issues, must be some 
strange macros at work. */



-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys -- and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
enlightenment-cvs mailing list
enlightenment-cvs@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/enlightenment-cvs

Reply via email to