went through some more of the fixme list and fixed 'em
authorCarsten Haitzler <raster@rasterman.com>
Thu, 26 Jun 2003 14:04:31 +0000 (14:04 +0000)
committerCarsten Haitzler <raster@rasterman.com>
Thu, 26 Jun 2003 14:04:31 +0000 (14:04 +0000)
SVN revision: 7098

legacy/edje/src/lib/edje_callbacks.c
legacy/edje/src/lib/edje_load.c
legacy/edje/src/lib/edje_main.c
legacy/edje/src/lib/edje_private.h
legacy/edje/src/lib/edje_program.c
legacy/edje/src/lib/edje_smart.c

index fa0f8622ab17759a57967a3e8cdd6eb45241ec83..3c235b370819e55934a7fb8b08b4b96328524023 100644 (file)
@@ -128,13 +128,17 @@ _edje_timer_cb(void *data)
    double t;
    Evas_List *l;
    Evas_List *animl = NULL;
+   Edje *ed;
    
    t = ecore_time_get();
    for (l = _edje_animators; l; l = l->next)
-     animl = evas_list_append(animl, l->data);
+     {
+       ed = l->data;
+       _edje_ref(ed);
+       animl = evas_list_append(animl, l->data);
+     }
    while (animl)
      {
-       Edje *ed;
        Evas_List *newl = NULL;
        
        ed = animl->data;
@@ -151,6 +155,7 @@ _edje_timer_cb(void *data)
             _edje_program_run_iterate(runp, t);
          }
        _edje_thaw(ed);
+       _edje_unref(ed);
      }
    if (_edje_anim_count > 0) return 1;
    _edje_timer = NULL;
index 3138c40bb3fc497b0eb3c2d11d454f13ccadd38d..17d034651957289de35abc1a4557b92719dfcda3 100644 (file)
@@ -72,6 +72,8 @@ edje_file_set(Evas_Object *obj, const char *file, const char *part)
                                                 ed);
                  evas_object_data_set(rp->object, "real_part", rp);
               }
+            else
+              evas_object_pass_events_set(rp->object, 1);
             evas_object_clip_set(rp->object, ed->clipper);
             evas_object_show(rp->object);
             rp->part = ep;
@@ -89,7 +91,10 @@ edje_file_set(Evas_Object *obj, const char *file, const char *part)
               {
                  rp->clip_to = evas_list_nth(ed->parts, rp->part->clip_to_id);
                  if (rp->clip_to)
-                   evas_object_clip_set(rp->object, rp->clip_to->object);
+                   {
+                      evas_object_pass_events_set(rp->clip_to->object, 1);
+                      evas_object_clip_set(rp->object, rp->clip_to->object);
+                   }
               }
          }
        ed->dirty = 1;
@@ -110,7 +115,6 @@ _edje_file_add(Edje *ed)
    Evas_List *l;
    int id = -1;
 
-   /* FIXME: look in hash table first */   
    ed->file = evas_hash_find(_edje_file_hash, ed->path);
    if (ed->file)
      {
@@ -128,7 +132,7 @@ _edje_file_add(Edje *ed)
        ed->file->path = strdup(ed->path);
        if (!ed->file->collection_dir)
          {
-            /* FIXME: free up ed->file */
+            _edje_file_free(ed->file);
             ed->file = NULL;
             goto out;
          }
@@ -167,6 +171,13 @@ _edje_file_add(Edje *ed)
             ed->collection->references = 1;
             ed->file->collection_hash = evas_hash_add(ed->file->collection_hash, ed->part, ed->collection);
          }
+       else
+         {
+            ed->file->references--;
+            if (ed->file->references <= 0)
+              _edje_file_free(ed->file);
+            ed->file = NULL;
+         }
      }
    out:
    if (ef) eet_close(ef);
@@ -206,8 +217,16 @@ _edje_file_del(Edje *ed)
      }
    if (ed->actions)
      {
-//     printf("FIXME: leak!\n");
-       ed->actions = NULL;
+       while (ed->actions)
+         {
+            Edje_Running_Program *runp;
+            
+            _edje_anim_count--;
+            runp = ed->actions->data;
+            ed->actions = evas_list_remove(ed->actions, runp);
+            free(runp);
+         }
+       _edje_animators = evas_list_remove(_edje_animators, ed);
      }
 }
 
index 0967180312213144479aeae70be2142c36470232..e1fb85f6c355c12a491afa21248bbe7672a54bc7 100644 (file)
@@ -24,6 +24,9 @@ _edje_add(Evas_Object *obj)
    evas_object_color_set(ed->clipper, 255, 255, 255, 255);
    evas_object_move(ed->clipper, 0, 0);
    evas_object_resize(ed->clipper, 0, 0);
+   evas_object_pass_events_set(ed->clipper, 1);
+   ed->have_objects = 1;
+   ed->references = 1;
    return ed;
 }
 
@@ -31,9 +34,60 @@ void
 _edje_del(Edje *ed)
 {
    _edje_file_del(ed);
+   _edje_clean_objects(ed);
    if (ed->path) free(ed->path);
    if (ed->part) free(ed->part);
-   evas_object_del(ed->clipper);
-   printf("FIXME: leak: ed->callbacks\n");
+   while (ed->callbacks)
+     {
+       Edje_Signal_Callback *escb;
+       
+       escb = ed->callbacks->data;
+       ed->callbacks = evas_list_remove(ed->callbacks, escb);
+       free(escb->signal);
+       free(escb->source);
+       free(escb);
+     }
    free(ed);
 }
+
+void
+_edje_clean_part_objects(Edje *ed)
+{
+   Evas_List *l;
+   
+   for (l = ed->parts; l; l = l->next)
+     {
+       Edje_Real_Part *rp;
+       
+       rp = l->data;
+       evas_object_del(rp->object);
+       rp->object = NULL;
+     }   
+}
+
+void
+_edje_clean_objects(Edje *ed)
+{
+   Evas_List *l;
+   
+   ed->have_objects = 0;
+   _edje_clean_part_objects(ed);
+   evas_object_del(ed->clipper);
+   ed->evas = NULL;
+   ed->obj = NULL;
+   ed->clipper = NULL;
+}
+
+void
+_edje_ref(Edje *ed)
+{
+   ed->references++;
+}
+
+void
+_edje_unref(Edje *ed)
+{
+   ed->references--;
+   if (ed->references <= 0)
+     _edje_del(ed);
+}
index 87970175aae8df1ef15b10a359893414badf1035..3a85dd62e35c49d11c3ac45909b3ab49455daac6 100644 (file)
@@ -12,7 +12,6 @@
 
 /* FIXME:
  * add a smooth scale option to fill params
- * reference count programs since the tmp lists can be screwed if a program is ended by another
  * need "random" signals and events for hooking to, and "random" durations
  * free stuff - no more leaks
  * dragables have to work
  * text and color classes need to work
  * reduce linked list walking and list_nth calls
  * named parts need to be able to be "replaced" with new evas objects
+ * part replacement with object callbacks should be possible
  * real part size and "before min/max limit" sizes need to be stored per part
  * need to be able to calculate min & max size of a whole edje
- * add code to list collections in an eet file
+ * need to be able to list collections in an eet file
  * externally sourced images need to be supported in edje_cc and edje
- * part replacement with object callbacks should be possible
  * part queries for geometry etc.
  * need to be able to "pause" edjes from API
  * need to be able to force anim times to 0.0 from API to turn off animation
- * need to detect relative loops
- * need to detect clip_to loops
+ * need to detect relative part loops
+ * need to detect clip_to part loops
  * need to detect anim time 0.0 loops
- * need to check frametime 0.0 works
- * need to check mouse_events flag works
  * edje_cc should be able to force lossy, lossless, min and max quality and compression of encoded images
  * edje_cc needs to prune out unused images
  * edje_cc might need an option for limiting number of tween images
@@ -342,6 +339,10 @@ struct _Edje
    double                x, y, w, h;
    unsigned char         dirty : 1;
    unsigned char         recalc : 1;
+   unsigned char         walking_callbacks : 1;
+   unsigned char         delete_callbacks : 1;
+   unsigned char         just_added_callbacks : 1;
+   unsigned char         have_objects : 1;
    Evas                 *evas; /* the evas this edje belongs to */
    Evas_Object          *obj; /* the smart object */
    Evas_Object          *clipper; /* a big rect to clip this edje to */
@@ -351,6 +352,7 @@ struct _Edje
    Evas_List            *actions; /* currently running actions */   
    Evas_List            *callbacks;
    int                   freeze;
+   int                   references;
 };
 
 struct _Edje_Real_Part
@@ -396,6 +398,8 @@ struct _Edje_Signal_Callback
    char  *source;
    void (*func) (void *data, Evas_Object *o, const char *emission, const char *source);
    void  *data;
+   int    just_added : 1;
+   int    delete_me : 1;
 };
 
 struct _Edje_Calc_Params
@@ -440,7 +444,11 @@ void  _edje_collection_free(Edje_Part_Collection *ec);
 
 Edje *_edje_add(Evas_Object *obj);
 void  _edje_del(Edje *ed);
-
+void  _edje_clean_part_objects(Edje *ed);
+void  _edje_clean_objects(Edje *ed);
+void  _edje_ref(Edje *ed);
+void  _edje_unref(Edje *ed);
+    
 int   _edje_program_run_iterate(Edje_Running_Program *runp, double tim);
 void  _edje_program_end(Edje *ed, Edje_Running_Program *runp);
 void  _edje_program_run(Edje *ed, Edje_Program *pr);
index 22b6f585a57d47f7e2d5f35e66a407a6558132f6..ab2f5fe4e73d5e449219c769718965f3fda4a74a 100644 (file)
@@ -41,6 +41,11 @@ edje_signal_callback_add(Evas_Object *obj, const char *emission, const char *sou
    escb->func = func;
    escb->data = data;
    ed->callbacks = evas_list_append(ed->callbacks, escb);
+   if (ed->walking_callbacks)
+     {
+       escb->just_added = 1;
+       ed->just_added_callbacks = 1;
+     }
 }
 
 void *
@@ -64,9 +69,18 @@ edje_signal_callback_del(Evas_Object *obj, const char *emission, const char *sou
             void *data;
             
             data = escb->data;
-            free(escb->signal);
-            free(escb->source);
-            free(escb);
+            if (ed->walking_callbacks)
+              {
+                 escb->delete_me = 1;
+                 ed->delete_callbacks = 1;
+              }
+            else
+              {
+                 ed->callbacks = evas_list_remove_list(ed->callbacks, l);
+                 free(escb->signal);
+                 free(escb->source);
+                 free(escb);
+              }
             return data;
          }
      }
@@ -92,6 +106,7 @@ _edje_program_run_iterate(Edje_Running_Program *runp, double tim)
    double t, total;
    Evas_List *l;
 
+   _edje_ref(runp->edje);
    _edje_freeze(runp->edje);
    t = tim - runp->start_time;
    total = runp->program->tween.time;
@@ -143,11 +158,13 @@ _edje_program_run_iterate(Edje_Running_Program *runp, double tim)
             if (pr) _edje_program_run(runp->edje, pr);
          }
        _edje_thaw(runp->edje);
+       _edje_unref(runp->edje);
        free(runp);
        return  0;
      }
    _edje_recalc(runp->edje);
    _edje_thaw(runp->edje);
+   _edje_unref(runp->edje);
    return 1;
 }
 
@@ -156,6 +173,7 @@ _edje_program_end(Edje *ed, Edje_Running_Program *runp)
 {
    Evas_List *l;
 
+   _edje_ref(runp->edje);
    _edje_freeze(runp->edje);
    for (l = runp->program->targets; l; l = l->next)
      {
@@ -183,6 +201,7 @@ _edje_program_end(Edje *ed, Edje_Running_Program *runp)
      _edje_animators = evas_list_remove(_edje_animators, runp->edje);
    _edje_emit(runp->edje, "program,stop", runp->program->name);
    _edje_thaw(runp->edje);
+   _edje_unref(runp->edje);   
    free(runp);
 }
    
@@ -192,6 +211,7 @@ _edje_program_run(Edje *ed, Edje_Program *pr)
    Evas_List *l;
 
    _edje_freeze(ed);
+   _edje_ref(ed);
    _edje_emit(ed, "program,start", pr->name);
    if (pr->action == EDJE_ACTION_TYPE_STATE_SET)
      {
@@ -280,6 +300,7 @@ _edje_program_run(Edje *ed, Edje_Program *pr)
      {
        _edje_emit(ed, pr->state, pr->state2);
      }
+   _edje_unref(ed);
    _edje_thaw(ed);
 }
 
@@ -290,6 +311,7 @@ _edje_emit(Edje *ed, char *sig, char *src)
    static Evas_List *emissions = NULL;
    Edje_Emission *ee;
 
+   _edje_ref(ed);
    _edje_freeze(ed);
    printf("EMIT \"%s\" \"%s\"\n", sig, src);
    ee = calloc(1, sizeof(Edje_Emission));
@@ -300,6 +322,7 @@ _edje_emit(Edje *ed, char *sig, char *src)
      {
        emissions = evas_list_append(emissions, ee);
        _edje_thaw(ed);
+       _edje_unref(ed);
        return;
      }
    else
@@ -319,14 +342,41 @@ _edje_emit(Edje *ed, char *sig, char *src)
                      (_edje_glob_match(ee->source, pr->source)))
                    _edje_program_run(ed, pr);
               }
+            ed->walking_callbacks = 1;
             for (l = ed->callbacks; l; l = l->next)
               {
                  Edje_Signal_Callback *escb;
                  
                  escb = l->data;
-                 if ((_edje_glob_match(ee->signal, escb->signal)) &&
+                 if ((!escb->just_added) &&
+                     (!escb->delete_me) &&
+                     (_edje_glob_match(ee->signal, escb->signal)) &&
                      (_edje_glob_match(ee->source, escb->source)))
-              escb->func(escb->data, ed->obj, ee->signal, ee->source);
+                   escb->func(escb->data, ed->obj, ee->signal, ee->source);
+              }
+            ed->walking_callbacks = 0;
+            if ((ed->delete_callbacks) || (ed->just_added_callbacks))
+              {
+                 ed->delete_callbacks = 0;
+                 ed->just_added_callbacks = 0;
+                 for (l = ed->callbacks; l;)
+                   {
+                      Edje_Signal_Callback *escb;
+                      Evas_List *next_l;
+                      
+                      escb = l->data;                 
+                      next_l = l->next;
+                      if (escb->just_added)
+                        escb->just_added = 0;
+                      if (escb->delete_me)
+                        {
+                           ed->callbacks = evas_list_remove_list(ed->callbacks, l);
+                           free(escb->signal);
+                           free(escb->source);
+                           free(escb);
+                        }
+                      l = next_l;
+                   }
               }
          }
        free(ee->signal);
@@ -334,4 +384,5 @@ _edje_emit(Edje *ed, char *sig, char *src)
        free(ee);
      }
    _edje_thaw(ed);
+   _edje_unref(ed);
 }
index 15b5d96a2471347c55f3a3247ac3eb870ff2eda3..e6675b7d0af72b81219adcd57eeba8d64e21fd3d 100644 (file)
@@ -65,7 +65,8 @@ _edje_smart_del(Evas_Object * obj)
 
    ed = evas_object_smart_data_get(obj);
    if (!ed) return;
-   _edje_del(ed);
+   _edje_clean_objects(ed);
+   _edje_unref(ed);
 }
 
 static void