#include "edje_part_helper.h"
#define MY_CLASS EFL_CANVAS_LAYOUT_INTERNAL_CLASS
-PROXY_IMPLEMENTATION(other, INTERNAL, EINA_FALSE)
+PROXY_IMPLEMENTATION(other, MY_CLASS, EINA_FALSE)
#undef PROXY_IMPLEMENTATION
+void
+_part_reuse_error(Efl_Canvas_Layout_Internal_Data *pd)
+{
+ const char *typestr = "UNKNOWN";
+ Edje *ed;
+
+ // TODO: Enable full debug only for eo_debug?
+ // Don't trust pd->ed as it may be invalid now.
+ ed = efl_data_scope_safe_get(pd->obj, EDJE_OBJECT_CLASS);
+ if (!ed)
+ {
+ ERR("A previous misuse of efl_part has been detected. Handles returned "
+ "by efl_part() are valid for a single function call. Did you call "
+ "a non implemented function? obj: %p has been deleted!", pd->obj);
+ return;
+ }
+
+ switch (pd->rp->part->type)
+ {
+ case EDJE_PART_TYPE_RECTANGLE: typestr = "RECTANGLE"; break;
+ case EDJE_PART_TYPE_TEXT: typestr = "TEXT"; break;
+ case EDJE_PART_TYPE_IMAGE: typestr = "IMAGE"; break;
+ case EDJE_PART_TYPE_SWALLOW: typestr = "SWALLOW"; break;
+ case EDJE_PART_TYPE_TEXTBLOCK: typestr = "TEXTBLOCK"; break;
+ case EDJE_PART_TYPE_GRADIENT: typestr = "GRADIENT"; break;
+ case EDJE_PART_TYPE_GROUP: typestr = "GROUP"; break;
+ case EDJE_PART_TYPE_BOX: typestr = "BOX"; break;
+ case EDJE_PART_TYPE_TABLE: typestr = "TABLE"; break;
+ case EDJE_PART_TYPE_EXTERNAL: typestr = "EXTERNAL"; break;
+ case EDJE_PART_TYPE_PROXY: typestr = "PROXY"; break;
+ case EDJE_PART_TYPE_SPACER: typestr = "SPACER"; break;
+ case EDJE_PART_TYPE_MESH_NODE: typestr = "MESH_NODE"; break;
+ case EDJE_PART_TYPE_LIGHT: typestr = "LIGHT"; break;
+ case EDJE_PART_TYPE_CAMERA: typestr = "CAMERA"; break;
+ case EDJE_PART_TYPE_SNAPSHOT: typestr = "SNAPSHOT"; break;
+ case EDJE_PART_TYPE_VECTOR: typestr = "VECTOR"; break;
+ default: break;
+ }
+
+ ERR("A previous misuse of efl_part has been detected. Handles returned "
+ "by efl_part() are valid for a single function call. Did you call "
+ "a non implemented function? obj: %p group: '%s' part: '%s' type: %s%s",
+ pd->obj, ed->group, pd->part, typestr,
+ ed->delete_me ? ". This object is already deleted." : "");
+}
+
PROXY_INIT(box)
PROXY_INIT(table)
PROXY_INIT(swallow)
}
void
-_edje_real_part_set(Eo *obj, void *ed, void *rp, const char *part)
+_edje_real_part_set(Eo *obj, Edje *ed, Edje_Real_Part *rp, const char *part)
{
- PROXY_DATA_GET(obj, pd);
+ Efl_Canvas_Layout_Internal_Data *pd;
+
+ pd = efl_data_scope_get(obj, EFL_CANVAS_LAYOUT_INTERNAL_CLASS);
+ pd->obj = ed->obj;
pd->ed = ed;
pd->rp = rp;
pd->part = part;
pd->temp = 1;
- efl_parent_set(obj, pd->ed->obj);
+ pd->in_call = 0;
+ efl_parent_set(obj, ed->obj);
}
EOLIAN static Efl_Object *
_efl_canvas_layout_internal_efl_object_finalize(Eo *obj, Efl_Canvas_Layout_Internal_Data *pd)
{
EINA_SAFETY_ON_FALSE_RETURN_VAL(pd->rp && pd->ed && pd->part, NULL);
+ // Do not use RETURN_VAL() here!
return efl_finalize(efl_super(obj, MY_CLASS));
}
_efl_canvas_layout_internal_efl_gfx_geometry_get(Eo *obj, Efl_Canvas_Layout_Internal_Data *pd, int *x, int *y, int *w, int *h)
{
Edje_Real_Part *rp = pd->rp;
+ PROXY_CALL_BEGIN(pd);
_edje_recalc_do(pd->ed);
if (!rp)
if (y) *y = 0;
if (w) *w = 0;
if (h) *h = 0;
+ RETURN_VOID;
}
if (x) *x = rp->x;
_efl_canvas_layout_internal_state_get(Eo *obj, Efl_Canvas_Layout_Internal_Data *pd, const char **name, double *val)
{
const char *str;
+ PROXY_CALL_BEGIN(pd);
- if (!name && !val) return;
+ if (!name && !val)
+ RETURN_VOID;
str = _edje_object_part_state_get(pd->ed, pd->part, val);
if (name) *name = str;
RETURN_VOID;
EOLIAN static Eina_Bool
_efl_canvas_layout_internal_efl_ui_drag_drag_value_set(Eo *obj, Efl_Canvas_Layout_Internal_Data *pd, double dx, double dy)
{
+ PROXY_CALL_BEGIN(pd);
RETURN_VAL(_edje_object_part_drag_value_set(pd->ed, pd->part, dx, dy));
}
EOLIAN static Eina_Bool
_efl_canvas_layout_internal_efl_ui_drag_drag_value_get(Eo *obj, Efl_Canvas_Layout_Internal_Data *pd, double *dx, double *dy)
{
+ PROXY_CALL_BEGIN(pd);
RETURN_VAL(_edje_object_part_drag_value_get(pd->ed, pd->part, dx, dy));
}
EOLIAN static Eina_Bool
_efl_canvas_layout_internal_efl_ui_drag_drag_size_set(Eo *obj, Efl_Canvas_Layout_Internal_Data *pd, double dw, double dh)
{
+ PROXY_CALL_BEGIN(pd);
RETURN_VAL(_edje_object_part_drag_size_set(pd->ed, pd->part, dw, dh));
}
EOLIAN static Eina_Bool
_efl_canvas_layout_internal_efl_ui_drag_drag_size_get(Eo *obj, Efl_Canvas_Layout_Internal_Data *pd, double *dw, double *dh)
{
+ PROXY_CALL_BEGIN(pd);
RETURN_VAL(_edje_object_part_drag_size_get(pd->ed, pd->part, dw, dh));
}
EOLIAN static Efl_Ui_Drag_Dir
_efl_canvas_layout_internal_efl_ui_drag_drag_dir_get(Eo *obj, Efl_Canvas_Layout_Internal_Data *pd)
{
+ PROXY_CALL_BEGIN(pd);
RETURN_VAL(_edje_object_part_drag_dir_get(pd->ed, pd->part));
}
EOLIAN static Eina_Bool
_efl_canvas_layout_internal_efl_ui_drag_drag_step_set(Eo *obj, Efl_Canvas_Layout_Internal_Data *pd, double dx, double dy)
{
+ PROXY_CALL_BEGIN(pd);
RETURN_VAL(_edje_object_part_drag_step_set(pd->ed, pd->part, dx, dy));
}
EOLIAN static Eina_Bool
_efl_canvas_layout_internal_efl_ui_drag_drag_step_get(Eo *obj, Efl_Canvas_Layout_Internal_Data *pd, double *dx, double *dy)
{
+ PROXY_CALL_BEGIN(pd);
RETURN_VAL(_edje_object_part_drag_step_get(pd->ed, pd->part, dx, dy));
}
EOLIAN static Eina_Bool
_efl_canvas_layout_internal_efl_ui_drag_drag_step_move(Eo *obj, Efl_Canvas_Layout_Internal_Data *pd, double dx, double dy)
{
+ PROXY_CALL_BEGIN(pd);
RETURN_VAL(_edje_object_part_drag_step(pd->ed, pd->part, dx, dy));
}
EOLIAN static Eina_Bool
_efl_canvas_layout_internal_efl_ui_drag_drag_page_set(Eo *obj, Efl_Canvas_Layout_Internal_Data *pd, double dx, double dy)
{
+ PROXY_CALL_BEGIN(pd);
RETURN_VAL(_edje_object_part_drag_page_set(pd->ed, pd->part, dx, dy));
}
EOLIAN static Eina_Bool
_efl_canvas_layout_internal_efl_ui_drag_drag_page_get(Eo *obj, Efl_Canvas_Layout_Internal_Data *pd, double *dx, double *dy)
{
+ PROXY_CALL_BEGIN(pd);
RETURN_VAL(_edje_object_part_drag_page_get(pd->ed, pd->part, dx, dy));
}
EOLIAN static Eina_Bool
_efl_canvas_layout_internal_efl_ui_drag_drag_page_move(Eo *obj, Efl_Canvas_Layout_Internal_Data *pd, double dx, double dy)
{
+ PROXY_CALL_BEGIN(pd);
RETURN_VAL(_edje_object_part_drag_page(pd->ed, pd->part, dx, dy));
}
#include "../evas/canvas/evas_box.eo.h"
-PROXY_IMPLEMENTATION(box, INTERNAL_BOX, EINA_FALSE)
+PROXY_IMPLEMENTATION(box, MY_CLASS, EINA_FALSE)
#undef PROXY_IMPLEMENTATION
typedef struct _Part_Item_Iterator Part_Item_Iterator;
static void _external_compose(Eo *obj, Edje *ed, const char *part);
-PROXY_IMPLEMENTATION(external, EXTERNAL, EINA_TRUE, _external_compose(proxy, ed, rp->part->name))
+PROXY_IMPLEMENTATION(external, MY_CLASS, EINA_TRUE, _external_compose(proxy, ed, rp->part->name))
#undef PROXY_IMPLEMENTATION
static void
Edje *ed;
Edje_Real_Part *rp;
const char *part;
- unsigned char temp;
+ Eo *obj;
+ unsigned char temp, in_call;
};
struct _Part_Item_Iterator
Eo *object;
};
+void _part_reuse_error(Efl_Canvas_Layout_Internal_Data *pd);
+
+#define PROXY_CALL_BEGIN(pd) do { pd->in_call = 1; } while (0)
+#define PROXY_CALL_END(pd) do { pd->in_call = 0; } while (0)
#define PROXY_REF(obj, pd) do { if (!(pd->temp++)) efl_ref(obj); } while(0)
#define PROXY_UNREF(obj, pd) do { if (pd->temp) { if (!(--pd->temp)) efl_del(obj); } } while(0)
-#define RETURN_VAL(a) do { typeof(a) _ret = a; PROXY_UNREF(obj, pd); return _ret; } while(0)
-#define RETURN_VOID do { PROXY_UNREF(obj, pd); return; } while(0)
+#define RETURN_VAL(a) do { typeof(a) _ret = a; PROXY_CALL_END(pd); PROXY_UNREF(obj, pd); return _ret; } while(0)
+#define RETURN_VOID do { PROXY_CALL_END(pd); PROXY_UNREF(obj, pd); return; } while(0)
#define PROXY_CALL(a) ({ PROXY_REF(obj, pd); a; })
+#define PROXY_STATIC_VAR(type) _##type##_proxy
#ifndef PROXY_ADD_EXTRA_OP
# define PROXY_ADD_EXTRA_OP
#endif
-void _edje_real_part_set(Eo *obj, void *ed, void *rp, const char *part);
+void _edje_real_part_set(Eo *obj, Edje *ed, Edje_Real_Part *rp, const char *part);
+
+static inline void
+_part_proxy_del_cb(Eo *proxy, Eo **static_var)
+{
+ if (*static_var)
+ {
+ // FIXME: Enable debug checks only in debug mode
+ Efl_Canvas_Layout_Internal_Data *pd = efl_data_scope_get
+ (*static_var, EFL_CANVAS_LAYOUT_INTERNAL_CLASS);
+ if (pd && pd->temp && !pd->in_call)
+ _part_reuse_error(pd);
+ if (*static_var != proxy)
+ efl_del_intercept_set(*static_var, NULL);
+ }
+ if (efl_parent_get(proxy))
+ {
+ efl_ref(proxy);
+ efl_parent_set(proxy, NULL);
+ }
+ efl_reuse(proxy);
+ *static_var = proxy;
+}
/* ugly macros to avoid code duplication */
#define PROXY_RESET(type) \
- do { if (_ ## type ## _proxy) \
+ do { if (PROXY_STATIC_VAR(type)) \
{ \
- efl_del_intercept_set(_ ## type ## _proxy, NULL); \
- efl_del(_ ## type ## _proxy); \
- _ ## type ## _proxy = NULL; \
+ efl_del_intercept_set(PROXY_STATIC_VAR(type), NULL); \
+ efl_del(PROXY_STATIC_VAR(type)); \
+ PROXY_STATIC_VAR(type) = NULL; \
} } while (0)
#define PROXY_INIT(type) \
_ ## type ## _shutdown(void); \
#define PROXY_DATA_GET(obj, pd) \
- Efl_Canvas_Layout_Internal_Data *pd = efl_data_scope_get(obj, EFL_CANVAS_LAYOUT_INTERNAL_CLASS)
+ Efl_Canvas_Layout_Internal_Data *pd = efl_data_scope_get(obj, EFL_CANVAS_LAYOUT_INTERNAL_CLASS); \
+ PROXY_CALL_BEGIN(pd)
-#define PROXY_IMPLEMENTATION(type, TYPE, no_del_cb, ...) \
-static Eo * _ ## type ## _proxy = NULL; \
+#define PROXY_IMPLEMENTATION(type, KLASS, no_del_cb, ...) \
+static Eo * PROXY_STATIC_VAR(type) = NULL; \
\
static void \
_ ## type ## _del_cb(Eo *proxy) \
{ \
- if (_ ## type ## _proxy) \
- { \
- efl_del_intercept_set(proxy, NULL); \
- efl_del(proxy); \
- return; \
- } \
- if (efl_parent_get(proxy)) \
- { \
- efl_ref(proxy); \
- efl_parent_set(proxy, NULL); \
- } \
- efl_reuse(proxy); \
- _ ## type ## _proxy = proxy; \
+ _part_proxy_del_cb(proxy, &(PROXY_STATIC_VAR(type))); \
} \
\
void \
Efl_Canvas_Layout_Internal_Data *pd; \
Eo *proxy; \
\
- pd = efl_data_scope_get(_ ## type ## _proxy, EFL_CANVAS_LAYOUT_INTERNAL_CLASS); \
+ pd = PROXY_STATIC_VAR(type) ? efl_data_scope_get(PROXY_STATIC_VAR(type), EFL_CANVAS_LAYOUT_INTERNAL_CLASS) : NULL; \
if (!pd) \
{ \
- if (_ ## type ## _proxy) \
- { \
- ERR("Found invalid handle for efl_part. Reset."); \
- _ ## type ## _proxy = NULL; \
- } \
- proxy = efl_add(EFL_CANVAS_LAYOUT_##TYPE##_CLASS, ed->obj, \
- _edje_real_part_set(efl_added, ed, rp, rp->part->name)); \
- __VA_ARGS__; \
- if (!no_del_cb) efl_del_intercept_set(proxy, _ ## type ## _del_cb); \
- return proxy; \
+ if (PROXY_STATIC_VAR(type)) \
+ ERR("Found invalid handle for efl_part. Reset."); \
+ PROXY_STATIC_VAR(type) = efl_add(KLASS, ed->obj, _edje_real_part_set(efl_added, ed, rp, rp->part->name)); \
+ goto end ; \
} \
\
if (EINA_UNLIKELY(pd->temp)) \
{ \
- /* warn about misuse, since non-implemented functions may trigger this \
- * misuse by accident. */ \
- ERR("Misuse of efl_part detected. Handles returned by efl_part() are " \
- "valid for a single function call! Did you call a non implemented " \
- "function?"); \
+ /* if (!pd->in_call) _part_reuse_error(pd); */ \
+ PROXY_STATIC_VAR(type) = efl_add(KLASS, ed->obj, _edje_real_part_set(efl_added, ed, rp, rp->part->name)); \
} \
- proxy = _ ## type ## _proxy; \
- _ ## type ## _proxy = NULL; \
- _edje_real_part_set(proxy, ed, rp, rp->part->name); \
+ else \
+ { \
+ _edje_real_part_set(PROXY_STATIC_VAR(type), ed, rp, rp->part->name); \
+ } \
+ \
+end: \
+ proxy = PROXY_STATIC_VAR(type); \
__VA_ARGS__; \
if (!no_del_cb) efl_del_intercept_set(proxy, _ ## type ## _del_cb); \
return proxy; \
#include "efl_canvas_layout_internal_swallow.eo.h"
#define MY_CLASS EFL_CANVAS_LAYOUT_INTERNAL_SWALLOW_CLASS
-PROXY_IMPLEMENTATION(swallow, INTERNAL_SWALLOW, EINA_FALSE)
+PROXY_IMPLEMENTATION(swallow, MY_CLASS, EINA_FALSE)
#undef PROXY_IMPLEMENTATION
/* Swallow parts */
#include "../evas/canvas/evas_table.eo.h"
-PROXY_IMPLEMENTATION(table, INTERNAL_TABLE, EINA_FALSE)
+PROXY_IMPLEMENTATION(table, MY_CLASS, EINA_FALSE)
#undef PROXY_IMPLEMENTATION
typedef struct _Part_Item_Iterator Part_Item_Iterator;
#include "efl_canvas_layout_internal_text.eo.h"
#define MY_CLASS EFL_CANVAS_LAYOUT_INTERNAL_TEXT_CLASS
-PROXY_IMPLEMENTATION(text, INTERNAL_TEXT, EINA_FALSE)
+PROXY_IMPLEMENTATION(text, MY_CLASS, EINA_FALSE)
#undef PROXY_IMPLEMENTATION
EOLIAN static void