Efl: Add Efl.Part and switch to it
authorJean-Philippe ANDRE <jpeg@videolan.org>
Wed, 18 May 2016 18:20:09 +0000 (03:20 +0900)
committerJean-Philippe Andre <jp.andre@samsung.com>
Tue, 24 May 2016 09:50:58 +0000 (18:50 +0900)
This should now fix the part API usage once and for all.
EFL should have no part name in any of its APIs beyond
the Efl.Part interface.

Part proxy objects (may be real objects) have a lifetime
of only one function call, in a fashion similar to eo_super.

@feature

src/Makefile_Efl.am
src/lib/edje/edje_containers.c
src/lib/edje/edje_load.c
src/lib/edje/edje_object.eo
src/lib/edje/edje_private.h
src/lib/edje/edje_util.c
src/lib/efl/Efl.h
src/lib/efl/interfaces/efl_interfaces_main.c
src/lib/efl/interfaces/efl_part.eo [new file with mode: 0644]

index e3b3248..cddd82a 100644 (file)
@@ -10,6 +10,7 @@ efl_eolian_files = \
       lib/efl/interfaces/efl_control.eo \
       lib/efl/interfaces/efl_file.eo \
       lib/efl/interfaces/efl_image_load.eo \
+      lib/efl/interfaces/efl_part.eo \
       lib/efl/interfaces/efl_player.eo \
       lib/efl/interfaces/efl_text.eo \
       lib/efl/interfaces/efl_text_properties.eo \
index 59a7399..87ad635 100644 (file)
@@ -21,6 +21,7 @@ struct _Edje_Part_Data
    Edje           *ed;
    Edje_Real_Part *rp;
    const char     *part;
+   Eina_Bool       temp;
 };
 
 struct _Part_Item_Iterator
@@ -31,26 +32,12 @@ struct _Part_Item_Iterator
    Eo            *object;
 };
 
-static Eina_Bool
-_del_cb(void *data, const Eo_Event *event EINA_UNUSED)
-{
-   Edje_Real_Part *rp = data;
-   rp->typedata.container->eo_proxy = NULL;
-   return EO_CALLBACK_CONTINUE;
-}
-
 Eo *
 _edje_box_internal_proxy_get(Edje_Object *obj, Edje *ed, Edje_Real_Part *rp)
 {
-   Efl_Canvas_Layout_Internal_Box *eo = rp->typedata.container->eo_proxy;
-
-   if (eo) return eo;
-
-   eo = eo_add(BOX_CLASS, obj, efl_canvas_layout_internal_box_real_part_set(eo_self, ed, rp, rp->part->name));
-   eo_event_callback_add(eo, EO_EVENT_DEL, _del_cb, rp);
-
-   rp->typedata.container->eo_proxy = eo;
-   return eo;
+   // TODO: optimize (cache)
+   return eo_add(BOX_CLASS, obj,
+                 efl_canvas_layout_internal_box_real_part_set(eo_self, ed, rp, rp->part->name));
 }
 
 EOLIAN static void
@@ -59,6 +46,7 @@ _efl_canvas_layout_internal_box_real_part_set(Eo *obj EINA_UNUSED, Edje_Box_Data
    pd->ed = ed;
    pd->rp = rp;
    pd->part = part;
+   pd->temp = EINA_TRUE;
 }
 
 EOLIAN static Eo_Base *
@@ -261,15 +249,9 @@ _efl_canvas_layout_internal_box_efl_pack_linear_pack_direction_get(Eo *obj EINA_
 Eo *
 _edje_table_internal_proxy_get(Edje_Object *obj, Edje *ed, Edje_Real_Part *rp)
 {
-   Efl_Canvas_Layout_Internal_Box *eo = rp->typedata.container->eo_proxy;
-
-   if (eo) return eo;
-
-   eo = eo_add(TABLE_CLASS, obj, efl_canvas_layout_internal_table_real_part_set(eo_self, ed, rp, rp->part->name));
-   eo_event_callback_add(eo, EO_EVENT_DEL, _del_cb, rp);
-
-   rp->typedata.container->eo_proxy = eo;
-   return eo;
+   // TODO: optimize (cache)
+   return eo_add(TABLE_CLASS, obj,
+                 efl_canvas_layout_internal_table_real_part_set(eo_self, ed, rp, rp->part->name));
 }
 
 EOLIAN static void
@@ -278,6 +260,7 @@ _efl_canvas_layout_internal_table_real_part_set(Eo *obj EINA_UNUSED, Edje_Table_
    pd->ed = ed;
    pd->rp = rp;
    pd->part = part;
+   pd->temp = EINA_TRUE;
 }
 
 EOLIAN static Eo_Base *
@@ -453,7 +436,7 @@ _efl_canvas_layout_internal_table_efl_pack_grid_grid_position_get(Eo *obj EINA_U
 
 #ifdef DEGUG
 #define PART_BOX_GET(obj, part, ...) ({ \
-   Eo *__box = efl_content_get(obj, part); \
+   Eo *__box = efl_part(obj, part); \
    if (!__box || !eo_isa(__box, EFL_CANVAS_LAYOUT_INTERNAL_BOX_CLASS)) \
      { \
         ERR("No such box part '%s' in layout %p", part, obj); \
@@ -462,7 +445,7 @@ _efl_canvas_layout_internal_table_efl_pack_grid_grid_position_get(Eo *obj EINA_U
    __box; })
 #else
 #define PART_BOX_GET(obj, part, ...) ({ \
-   Eo *__box = efl_content_get(obj, part); \
+   Eo *__box = efl_part(obj, part); \
    if (!__box) return __VA_ARGS__; \
    __box; })
 #endif
@@ -531,7 +514,7 @@ edje_object_part_box_remove_all(Edje_Object *obj, const char *part, Eina_Bool cl
 
 #ifdef DEBUG
 #define PART_TABLE_GET(obj, part, ...) ({ \
-   Eo *__table = efl_content_get(obj, part); \
+   Eo *__table = efl_part(obj, part); \
    if (!__table || !eo_isa(__table, EFL_CANVAS_LAYOUT_INTERNAL_TABLE_CLASS)) \
      { \
         ERR("No such table part '%s' in layout %p", part, obj); \
@@ -540,7 +523,7 @@ edje_object_part_box_remove_all(Edje_Object *obj, const char *part, Eina_Bool cl
    __table; })
 #else
 #define PART_TABLE_GET(obj, part, ...) ({ \
-   Eo *__table = efl_content_get(obj, part); \
+   Eo *__table = efl_part(obj, part); \
    if (!__table) return __VA_ARGS__; \
    __table; })
 #endif
index e6bdeea..1a58003 100644 (file)
@@ -1596,7 +1596,6 @@ _edje_file_del(Edje *ed)
                        _edje_box_layout_free_data(rp->typedata.container->anim);
                        rp->typedata.container->anim = NULL;
                     }
-                  eo_unref(rp->typedata.container->eo_proxy);
                   free(rp->typedata.container);
                }
              else if ((rp->type == EDJE_RP_TYPE_TEXT) &&
index 2ed2d88..d79cd93 100644 (file)
@@ -1,6 +1,6 @@
 import edje_types;
 
-class Edje.Object (Evas.Smart.Clipped, Efl.File, Efl.Container)
+class Edje.Object (Evas.Smart.Clipped, Efl.File, Efl.Container, Efl.Part)
 {
    legacy_prefix: edje_object;
    eo_prefix: edje_obj;
@@ -2005,6 +2005,7 @@ class Edje.Object (Evas.Smart.Clipped, Efl.File, Efl.Container)
       Efl.Container.content_unset;
       Efl.Container.content_remove;
       Efl.Container.content_part_name.get;
+      Efl.Part.part;
    }
    events {
       recalc; [[Edje re-calculated the object.]]
index 5bfecbc..604e7a4 100644 (file)
@@ -1897,7 +1897,6 @@ struct _Edje_Real_Part_Container
 {
    Eina_List                *items; // 4 //FIXME: only if table/box
    Edje_Part_Box_Animation  *anim; // 4 //FIXME: Used only if box
-   Eo                       *eo_proxy;
 };
 
 struct _Edje_Real_Part_Swallow
index 7009fda..b8e4923 100644 (file)
@@ -3897,23 +3897,15 @@ _edje_object_efl_container_content_get(Eo *obj, Edje *ed, const char *part)
    rp = _edje_real_part_recursive_get(&ed, part);
    if (!rp) return NULL;
 
-   switch (rp->type)
-     {
-      case EDJE_RP_TYPE_SWALLOW:
-       if (!rp->typedata.swallow) return NULL;
-       return rp->typedata.swallow->swallowed_object;
-      case EDJE_RP_TYPE_CONTAINER:
-        if (rp->part->type == EDJE_PART_TYPE_BOX)
-          return _edje_box_internal_proxy_get(obj, ed, rp);
-        else if (rp->part->type == EDJE_PART_TYPE_TABLE)
-          return _edje_table_internal_proxy_get(obj, ed, rp);
-        else return NULL;
-      case EDJE_RP_TYPE_TEXT:
-        WRN("not implemented yet");
-        return NULL;
-      default:
+   if (rp->type != EDJE_RP_TYPE_SWALLOW)
+     {
+        ERR("Edje group '%s' part '%s' is not a swallow. Did "
+            "you mean to call efl_part() instead?", ed->group, part);
         return NULL;
      }
+
+   if (!rp->typedata.swallow) return NULL;
+   return rp->typedata.swallow->swallowed_object;
 }
 
 /* new in eo */
@@ -3943,6 +3935,26 @@ _edje_object_efl_container_content_part_name_get(Eo *obj EINA_UNUSED, Edje *ed E
    return rp->part->name;
 }
 
+EOLIAN Eo *
+_edje_object_efl_part_part(Eo *obj, Edje *ed, const char *part)
+{
+   Edje_Real_Part *rp;
+
+   if ((!ed) || (!part)) return NULL;
+
+   /* Need to recalc before providing the object. */
+   _edje_recalc_do(ed);
+
+   rp = _edje_real_part_recursive_get(&ed, part);
+   if (!rp) return NULL;
+
+   if (rp->part->type == EDJE_PART_TYPE_BOX)
+     return _edje_box_internal_proxy_get(obj, ed, rp);
+   else if (rp->part->type == EDJE_PART_TYPE_TABLE)
+     return _edje_table_internal_proxy_get(obj, ed, rp);
+   else return NULL; /* FIXME/TODO: text & others (color, ...) */
+}
+
 EOLIAN void
 _edje_object_size_min_get(Eo *obj EINA_UNUSED, Edje *ed, Evas_Coord *minw, Evas_Coord *minh)
 {
index 479f7ef..6962c8f 100644 (file)
@@ -71,6 +71,7 @@ typedef Efl_Gfx_Path_Command_Type Efl_Gfx_Path_Command;
 #include "interfaces/efl_image.eo.h"
 #include "interfaces/efl_image_animated.eo.h"
 #include "interfaces/efl_image_load.eo.h"
+#include "interfaces/efl_part.eo.h"
 #include "interfaces/efl_player.eo.h"
 #include "interfaces/efl_text.eo.h"
 #include "interfaces/efl_text_properties.eo.h"
index 98d5096..3b5ce16 100644 (file)
@@ -9,6 +9,7 @@
 #include "interfaces/efl_image.eo.c"
 #include "interfaces/efl_image_animated.eo.c"
 #include "interfaces/efl_image_load.eo.c"
+#include "interfaces/efl_part.eo.c"
 #include "interfaces/efl_player.eo.c"
 #include "interfaces/efl_text.eo.c"
 #include "interfaces/efl_text_properties.eo.c"
diff --git a/src/lib/efl/interfaces/efl_part.eo b/src/lib/efl/interfaces/efl_part.eo
new file mode 100644 (file)
index 0000000..76ef170
--- /dev/null
@@ -0,0 +1,46 @@
+import eo_base;
+
+interface Efl.Part
+{
+   [[Interface for objects supporting named parts.
+
+     An object implementing this interface will be able to
+     provide access to some of its sub-objects by name.
+     This gives access to parts as defined in a widget's
+     theme.
+
+     Part proxy objects have a special lifetime that
+     is limited to one and only one function call.
+
+     In other words, the caller does not hold a reference
+     to this proxy object. It may be possible, in languages
+     that allow it, to get an extra reference to this part
+     object and extend its lifetime to more than a single
+     function call.
+
+     In pseudo-code, this means only the following two
+     use cases are supported:
+
+       obj.func(part(obj, "part"), args)
+
+     And:
+
+       part = ref(part(obj, "part"))
+       func1(part, args)
+       func2(part, args)
+       func3(part, args)
+       unref(part)
+   ]]
+   methods {
+      part @const {
+         [[Get a proxy object referring to a part of an object.
+
+           The returned object is valid for only a single function call.
+         ]]
+         params {
+            name: const(char)*; [[The part name.]]
+         }
+         return: Eo.Base; [[A (proxy) object, valid for a single call.]]
+      }
+   }
+}