eo: fix and rework efl_replace()

Summary:
Check if the Eo to be replaced is NULL before calling efl_unref.
The documentation implies that the replaced object can be NULL, so this
check avoids unnecessary function calls and warning logs.

Add an EINA_SAFETY check in order to properly print an error message
when the function is used with an NULL storage pointer.
The documentation specifies that the first parameter can not be NULL.
So printing an error message should be better than silently returning.

Add a boolean return to the function that signalizes if the content of
the storage was changed. It is NOT an success/error flag, it is just a
simple helper to quickly test for a change in content.
This feature was inspired by eina_stringshare_replace that is used in
similar ways around the code.

Change the documentation to match the changes and to be more specific
about what is expected and how the arguments are treated.

Reviewers: raster, bu5hm4n, cedric, felipealmeida

Reviewed By: bu5hm4n

Subscribers: #reviewers, #committers, larryolj

Tags: #efl

Differential Revision: https://phab.enlightenment.org/D7256
This commit is contained in:
Vitor Sousa 2018-11-12 18:10:20 -02:00
parent 96228d3c22
commit 08357cd153
1 changed files with 15 additions and 7 deletions

View File

@ -2059,23 +2059,31 @@ EAPI int efl_callbacks_cmp(const Efl_Callback_Array_Item *a, const Efl_Callback_
/**
* @def Replace the previous Eo pointer with new content.
*
* @param storage The object to replace the old reference. It can not be @c NULL.
* @param storage Pointer to the space holding the object to be replaced.
* It can not be @c NULL.
* @param new_obj The new object. It may be @c NULL.
* @return @c true if objects were different and thus replaced, @c false
* if nothing happened, i.e. either the objects were the same or a @c NULL
* pointer was wrongly given as @a storage.
*
* The object pointed by @a storage must be previously an Eo or
* @c NULL and it will be efl_unref(). The @a new_obj will be passed
* to efl_ref() and then assigned to @c *storage.
* The object pointed by @c *storage must be previously an Eo or
* @c NULL; if it is an Eo then it will be efl_unref(). The @a new_obj
* will be passed to efl_ref() if not @c NULL, and then assigned to @c *storage.
*
* @note The return is NOT a success/error flag, it just signalizes if
* the value has changed.
* @see efl_ref()
* @see efl_unref()
*/
static inline void
static inline Eina_Bool
efl_replace(Eo **storage, Eo *new_obj)
{
if (!storage || *storage == new_obj) return;
EINA_SAFETY_ON_NULL_RETURN_VAL(storage, EINA_FALSE);
if (*storage == new_obj) return EINA_FALSE;
if (new_obj) efl_ref(new_obj);
efl_unref(*storage);
if (*storage) efl_unref(*storage);
*storage = new_obj;
return EINA_TRUE;
}
EOAPI extern const Eina_Value_Type *EINA_VALUE_TYPE_OBJECT;