summaryrefslogtreecommitdiff
path: root/src/lib/eo
diff options
context:
space:
mode:
authorJean-Philippe Andre <jp.andre@samsung.com>2017-04-18 20:41:11 +0900
committerJean-Philippe Andre <jp.andre@samsung.com>2017-04-19 11:15:30 +0900
commit19b9234f23af78daf73784bd37d3458e94e3459f (patch)
tree371ef8cf57847ab29d20b68f2bfc7dec9be6fd42 /src/lib/eo
parent85636658e00de58db1a3c5f8b03e495a5ad1bda8 (diff)
eo: Add new API efl_cast
This is similar to efl_super but the specified class is the one we want to call the function on. This is similar to dynamic_cast<> in C++. Note: both efl_super() and efl_cast() need documentation! This is an experimental feature. Fixes T5311 @feature Maniphest Tasks: T5311 Differential Revision: https://phab.enlightenment.org/D4797
Diffstat (limited to 'src/lib/eo')
-rw-r--r--src/lib/eo/Eo.h1
-rw-r--r--src/lib/eo/eo.c30
2 files changed, 24 insertions, 7 deletions
diff --git a/src/lib/eo/Eo.h b/src/lib/eo/Eo.h
index bbd53ff4a5..9d0cb3bb4e 100644
--- a/src/lib/eo/Eo.h
+++ b/src/lib/eo/Eo.h
@@ -927,6 +927,7 @@ EAPI void _efl_object_call_end(Efl_Object_Op_Call_Data *call);
927EAPI Eo * _efl_add_end(Eo *obj, Eina_Bool is_ref, Eina_Bool is_fallback); 927EAPI Eo * _efl_add_end(Eo *obj, Eina_Bool is_ref, Eina_Bool is_fallback);
928 928
929EAPI Eo *efl_super(const Eo *obj, const Efl_Class *cur_klass); 929EAPI Eo *efl_super(const Eo *obj, const Efl_Class *cur_klass);
930EAPI Eo *efl_cast(const Eo *obj, const Efl_Class *cur_klass);
930 931
931/*****************************************************************************/ 932/*****************************************************************************/
932 933
diff --git a/src/lib/eo/eo.c b/src/lib/eo/eo.c
index 5410696994..bfa950bad7 100644
--- a/src/lib/eo/eo.c
+++ b/src/lib/eo/eo.c
@@ -343,7 +343,8 @@ _eo_op_desc_name_get(const Efl_Op_Description *desc)
343} 343}
344 344
345static inline const op_type_funcs * 345static inline const op_type_funcs *
346_eo_kls_itr_next(const _Efl_Class *orig_kls, const _Efl_Class *cur_klass, Efl_Object_Op op) 346_eo_kls_itr_next(const _Efl_Class *orig_kls, const _Efl_Class *cur_klass,
347 Efl_Object_Op op, Eina_Bool super)
347{ 348{
348 const _Efl_Class **kls_itr = NULL; 349 const _Efl_Class **kls_itr = NULL;
349 350
@@ -354,7 +355,7 @@ _eo_kls_itr_next(const _Efl_Class *orig_kls, const _Efl_Class *cur_klass, Efl_Ob
354 355
355 if (*kls_itr) 356 if (*kls_itr)
356 { 357 {
357 kls_itr++; 358 if (super) kls_itr++;
358 while (*kls_itr) 359 while (*kls_itr)
359 { 360 {
360 const op_type_funcs *fsrc = _vtable_func_get(&(*kls_itr)->vtable, op); 361 const op_type_funcs *fsrc = _vtable_func_get(&(*kls_itr)->vtable, op);
@@ -374,8 +375,8 @@ _eo_kls_itr_next(const _Efl_Class *orig_kls, const _Efl_Class *cur_klass, Efl_Ob
374 375
375static EFL_FUNC_TLS _Efl_Class *_super_klass = NULL; 376static EFL_FUNC_TLS _Efl_Class *_super_klass = NULL;
376 377
377EAPI Eo * 378static Eo *
378efl_super(const Eo *eo_id, const Efl_Class *cur_klass) 379_efl_super_cast(const Eo *eo_id, const Efl_Class *cur_klass, Eina_Bool super)
379{ 380{
380 EO_CLASS_POINTER_GOTO(cur_klass, super_klass, err); 381 EO_CLASS_POINTER_GOTO(cur_klass, super_klass, err);
381 382
@@ -389,13 +390,14 @@ efl_super(const Eo *eo_id, const Efl_Class *cur_klass)
389 390
390 EO_OBJ_POINTER_RETURN_VAL(eo_id, obj, NULL); 391 EO_OBJ_POINTER_RETURN_VAL(eo_id, obj, NULL);
391 obj->cur_klass = super_klass; 392 obj->cur_klass = super_klass;
392 obj->super = EINA_TRUE; 393 obj->super = super;
393 EO_OBJ_DONE(eo_id); 394 EO_OBJ_DONE(eo_id);
394 395
395 return (Eo *) eo_id; 396 return (Eo *) eo_id;
396 397
397do_klass: 398do_klass:
398 // efl_super(Class) is extremely rarely used, so TLS write is fine 399 // efl_super(Class) is extremely rarely used, so TLS write is fine
400 EINA_SAFETY_ON_FALSE_RETURN_VAL(super, NULL);
399 _super_klass = super_klass; 401 _super_klass = super_klass;
400 return (Eo *) eo_id; 402 return (Eo *) eo_id;
401 403
@@ -412,6 +414,18 @@ err_obj_hierarchy:
412#endif 414#endif
413} 415}
414 416
417EAPI Eo *
418efl_super(const Eo *eo_id, const Efl_Class *cur_klass)
419{
420 return _efl_super_cast(eo_id, cur_klass, EINA_TRUE);
421}
422
423EAPI Eo *
424efl_cast(const Eo *eo_id, const Efl_Class *cur_klass)
425{
426 return _efl_super_cast(eo_id, cur_klass, EINA_FALSE);
427}
428
415EAPI Eina_Bool 429EAPI Eina_Bool
416_efl_object_call_resolve(Eo *eo_id, const char *func_name, Efl_Object_Op_Call_Data *call, Efl_Object_Call_Cache *cache, const char *file, int line) 430_efl_object_call_resolve(Eo *eo_id, const char *func_name, Efl_Object_Op_Call_Data *call, Efl_Object_Call_Cache *cache, const char *file, int line)
417{ 431{
@@ -422,6 +436,7 @@ _efl_object_call_resolve(Eo *eo_id, const char *func_name, Efl_Object_Op_Call_Da
422 const op_type_funcs *func; 436 const op_type_funcs *func;
423 Eina_Bool is_obj; 437 Eina_Bool is_obj;
424 Eina_Bool is_override = EINA_FALSE; 438 Eina_Bool is_override = EINA_FALSE;
439 Eina_Bool super = EINA_TRUE;
425 440
426 if (EINA_UNLIKELY(!eo_id)) return EINA_FALSE; 441 if (EINA_UNLIKELY(!eo_id)) return EINA_FALSE;
427 442
@@ -439,10 +454,11 @@ _efl_object_call_resolve(Eo *eo_id, const char *func_name, Efl_Object_Op_Call_Da
439 if (_obj->cur_klass) 454 if (_obj->cur_klass)
440 { 455 {
441 cur_klass = _obj->cur_klass; 456 cur_klass = _obj->cur_klass;
457 super = _obj->super;
442 _obj->cur_klass = NULL; 458 _obj->cur_klass = NULL;
443 } 459 }
444 460
445 if (_obj_is_override(obj) && cur_klass && 461 if (_obj_is_override(obj) && cur_klass && super &&
446 (_eo_class_id_get(cur_klass) == EFL_OBJECT_OVERRIDE_CLASS)) 462 (_eo_class_id_get(cur_klass) == EFL_OBJECT_OVERRIDE_CLASS))
447 { 463 {
448 /* Doing a efl_super(obj, EFL_OBJECT_OVERRIDE_CLASS) should result in calling 464 /* Doing a efl_super(obj, EFL_OBJECT_OVERRIDE_CLASS) should result in calling
@@ -603,7 +619,7 @@ err:
603 // yes - special "move out of hot path" code blobs with goto's for 619 // yes - special "move out of hot path" code blobs with goto's for
604 // speed reasons to have intr prefetches work better and miss less 620 // speed reasons to have intr prefetches work better and miss less
605ok_cur_klass: 621ok_cur_klass:
606 func = _eo_kls_itr_next(klass, cur_klass, cache->op); 622 func = _eo_kls_itr_next(klass, cur_klass, cache->op, super);
607 if (!func) goto end; 623 if (!func) goto end;
608 klass = func->src; 624 klass = func->src;
609 goto ok_cur_klass_back; 625 goto ok_cur_klass_back;