Enlightenment CVS committal
Author : moom
Project : e17
Module : proto
Dir : e17/proto/etk/src/lib
Modified Files:
etk_object.c etk_object.h etk_property.h
Log Message:
* We can now safely remove a notification callback, even when it is
being called
* Doc++
===================================================================
RCS file: /cvs/e/e17/proto/etk/src/lib/etk_object.c,v
retrieving revision 1.26
retrieving revision 1.27
diff -u -3 -r1.26 -r1.27
--- etk_object.c 13 Aug 2006 19:20:28 -0000 1.26
+++ etk_object.c 18 Aug 2006 21:59:51 -0000 1.27
@@ -5,8 +5,8 @@
#include "etk_type.h"
#include "etk_signal.h"
#include "etk_signal_callback.h"
-#include "etk_utils.h"
#include "etk_property.h"
+#include "etk_utils.h"
/**
* @addtogroup Etk_Object
@@ -68,6 +68,7 @@
}
/**
+ * @internal
* @brief Gets the type of an Etk_Object
* @return Returns the type of an Etk_Object
*/
@@ -197,12 +198,13 @@
}
/**
+ * @internal
* @brief Adds @a signal_callback to the list of the signal callbacks of the
object
* @param object an object
* @param signal_callback the signal callback to add
- * @param after if @a after == ETK_TRUE, the callback will be called after the
default handler.
+ * @param after if @a after is ETK_TRUE, the callback will be called after the
default handler.
* Otherwise, it will be called before.
- * @note You usually do not need to call this function, use
etk_signal_connect() instead.
+ * @note You do not have to call this function, use etk_signal_connect()
instead
*/
void etk_object_signal_callback_add(Etk_Object *object, Etk_Signal_Callback
*signal_callback, Etk_Bool after)
{
@@ -216,10 +218,11 @@
}
/**
+ * @internal
* @brief Removes @a signal_callback from the list of the signal callbacks of
the object
* @param object an object
* @param signal_callback the signal callback to remove
- * @note You usually do not need to call this function, use
etk_signal_disconnect() instead.
+ * @note You do not have have to call this function, use
etk_signal_disconnect() instead
*/
void etk_object_signal_callback_remove(Etk_Object *object, Etk_Signal_Callback
*signal_callback)
{
@@ -241,10 +244,37 @@
}
/**
- * @brief Adds a weak pointer to the object. A weak pointer is pointer that is
automatically set
+ * @internal
+ * @brief Gets the signal callbacks connected to the signal @a signal of the
object @a object
+ * @param object the object connected to the signal
+ * @param signal the signal of which we want the callbacks
+ * @param callbacks the location of a list where the signal callbacks will be
appended
+ * @param after if @a after == ETK_TRUE, it appends only the callbacks that
have to be called after the
+ * default handler. Otherwise, it appends the callbacks called before the
default handler
+ * @note You usually do not need to call this function manually, it is used by
etk_signal_emit()
+ */
+void etk_object_signal_callbacks_get(Etk_Object *object, Etk_Signal *signal,
Evas_List **callbacks, Etk_Bool after)
+{
+ Evas_List *l;
+ Etk_Signal_Callback *callback;
+
+ if (!object || !signal || !callbacks)
+ return;
+
+ l = after ? object->after_signal_callbacks_list :
object->before_signal_callbacks_list;
+ for ( ; l; l = l->next)
+ {
+ callback = l->data;
+ if (callback->signal == signal)
+ *callbacks = evas_list_append(*callbacks, callback);
+ }
+}
+
+/**
+ * @brief Adds a weak pointer to the object. A weak pointer is a pointer that
will be automatically set
* to NULL when the object is destroyed
* @param object an object
- * @param pointer_location the location of the weak pointer to add
+ * @param pointer_location the location of the weak pointer
* @warning if the @a pointer_location is not accessible when the object is
destroyed, it may segfaults. So you have
* to use etk_object_weak_pointer_remove() when @a pointer_location becomes
inaccessible
* @see etk_object_weak_pointer_remove()
@@ -253,6 +283,9 @@
{
if (!object || !pointer_location || object->destroy_me)
return;
+ if (evas_list_find(object->weak_pointers_list, pointer_location))
+ return;
+
object->weak_pointers_list = evas_list_append(object->weak_pointers_list,
pointer_location);
}
@@ -270,34 +303,10 @@
}
/**
- * @brief Gets the signal callbacks connected to the signal @a signal of the
object @a object
- * @param object the object connected to the signal
- * @param signal the signal of which we want the callbacks
- * @param callbacks the location of a list where the signal callbacks will be
appended
- * @param after if @a after == ETK_TRUE, it appends only the callbacks that
have to be called after the default handler. @n
- * Otherwise, it appends the callbacks called before the default handler
- * @note You usually do not need to call this function manually, it is used by
etk_signal_emit()
- */
-void etk_object_signal_callbacks_get(Etk_Object *object, Etk_Signal *signal,
Evas_List **callbacks, Etk_Bool after)
-{
- Evas_List *l;
- Etk_Signal_Callback *callback;
-
- if (!object || !signal || !callbacks)
- return;
-
- l = after ? object->after_signal_callbacks_list :
object->before_signal_callbacks_list;
- for ( ; l; l = l->next)
- {
- callback = l->data;
- if (callback->signal == signal)
- *callbacks = evas_list_append(*callbacks, callback);
- }
-}
-
-/**
- * @brief Sets the data associated to a key for the object. The data could be
retrieved later with etk_object_data_get()
- * @param object the object to which the data will be added
+ * @brief Associates a data pointer to a key. The pointer will be carried by
the object and could be retrieved
+ * later with etk_object_data_get(). If the object already has an association
for the given key, the old data
+ * will be destroyed
+ * @param object the object which the data will be added to
* @param key the key to associate to the data
* @param value the value of the data
* @note If you want the data to be freed when the object is destroyed or when
the value is changed,
@@ -309,11 +318,13 @@
}
/**
- * @brief Sets the data associated to a key for the object. The data could be
retrieved later with etk_object_data_get()
- * @param object the object to which the data will be added
+ * @brief Associates a data pointer to a key. The pointer will be carried by
the object and could be retrieved
+ * later with etk_object_data_get(). If the object already has an association
for the given key, the old data
+ * will be destroyed
+ * @param object the object which the data will be added to
* @param key the key to associate to the data
- * @param free_cb the function to call on the data when the object is
destroyed or when the value is changed
* @param value the value of the data
+ * @param free_cb the function to call on @a value when the object is
destroyed or when the value is changed
*/
void etk_object_data_set_full(Etk_Object *object, const char *key, void
*value, void (*free_cb)(void *data))
{
@@ -337,10 +348,10 @@
}
/**
- * @brief Gets the data associated to the key
+ * @brief Gets the pointer associated to the given key
* @param object the object which has the data
* @param key the key associated to the data
- * @return Returns the value of the data, NULL on failure
+ * @return Returns the associated pointer, NULL on failure
*/
void *etk_object_data_get(Etk_Object *object, const char *key)
{
@@ -373,7 +384,7 @@
/**
* @brief Sets the values of several properties
- * @param object the object that has the properties to set
+ * @param object the object that has the properties
* @param first_property the name of the first property value
* @param ... the value of the first property, followed by any number of
property-name/property-value pairs,
* terminated with NULL
@@ -392,7 +403,7 @@
/**
* @brief Sets the values of several properties
- * @param object the object that has the properties to set
+ * @param object the object that has the properties
* @param first_property the name of the first property value
* @param args the value of the first property, followed by any number of
property-name/property-value pairs,
* terminated with NULL
@@ -501,23 +512,31 @@
Etk_Object *etk_object_notify(Etk_Object *object, const char *property_name)
{
Evas_List *l;
- Evas_List **notification_callbacks;
+ Evas_List **callbacks, *callbacks_copy;
Etk_Notification_Callback *callback;
void *object_ptr;
if (!object || !property_name)
return object;
- if (!(notification_callbacks =
evas_hash_find(object->notification_callbacks_hash, property_name)))
+ if (!(callbacks = evas_hash_find(object->notification_callbacks_hash,
property_name)))
return object;
+
+ /* We use a copy of the callback list here to avoid potential bugs
+ * if a notification callback is removed while being called */
+ callbacks_copy = NULL;
+ for (l = *callbacks; l; l = l->next)
+ callbacks_copy = evas_list_append(l->data);
object_ptr = object;
etk_object_weak_pointer_add(object, &object_ptr);
- for (l = *notification_callbacks; l && object_ptr; l = l->next)
+ while (callbacks_copy && object_ptr)
{
callback = l->data;
if (callback->callback)
callback->callback(object, property_name, callback->data);
+ callbacks_copy = evas_list_remove_list(callbacks_copy, callbacks_copy);
}
+ evas_list_free(callbacks_copy);
etk_object_weak_pointer_remove(object, &object_ptr);
return object_ptr;
@@ -725,7 +744,7 @@
* You can then destroy the object with etk_object_destroy(): it sets the weak
pointers of the object to NULL
* (see etk_object_weak_pointer_add()), emits the "destroyed" signal and
queues the object for freeing. Thus, the
* destructors will only be called at the beginning of the next main loop
iteration (from the destructor of the more
- * derived class to the destructor of the ultimate base class). So, you should
not assume that etk_object_destroy()
+ * derived class to the destructor of the ultimate base class). You should
then not assume that etk_object_destroy()
* will directly call the destructors. @n @n
*
* <b>Signal concept:</b> @n
@@ -778,7 +797,8 @@
* - Etk_Object
*
* \par Signals:
- * @signal_name "destroyed": Emitted just before all the destructors of the
object are called
+ * @signal_name "destroyed": Emitted when the object is destroyed, before all
the destructors of the object are called.
+ * Since the destructors have not been called yet, the object should still be
usable at this point.
* @signal_cb void callback(Etk_Object *object, void *data)
* @signal_arg object: the object which is about to be destroyed
* @signal_data
===================================================================
RCS file: /cvs/e/e17/proto/etk/src/lib/etk_object.h,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -3 -r1.11 -r1.12
--- etk_object.h 17 Aug 2006 17:18:14 -0000 1.11
+++ etk_object.h 18 Aug 2006 21:59:51 -0000 1.12
@@ -9,16 +9,20 @@
/**
* @defgroup Etk_Object Etk_Object
- * @brief The Etk_Object class is the base class for all the objects and the
widgets of Etk
+ * @brief The Etk_Object class is the base class for all the objects and
widgets of Etk
* @{
*/
#ifndef ETK_DISABLE_CAST_CHECKS
- #define ETK_OBJECT_CAST(obj, etk_type, c_type) ((c_type
*)etk_object_check_cast((Etk_Object *)(obj), (etk_type)))
+ #define ETK_OBJECT_CAST(obj, etk_type, c_type) \
+ ((c_type *)etk_object_check_cast((Etk_Object *)(obj), (etk_type)))
#else
#define ETK_OBJECT_CAST(obj, etk_type, c_type) ((c_type *)(obj))
#endif
-#define ETK_OBJECT_CHECK_TYPE(obj, etk_type)
(etk_type_inherits_from(((Etk_Object *)(obj))->type, (etk_type)))
+
+#define ETK_OBJECT_CHECK_TYPE(obj, etk_type) \
+ (etk_type_inherits_from(((Etk_Object *)(obj))->type, (etk_type)))
+
/** Gets the type of an object */
#define ETK_OBJECT_TYPE (etk_object_type_get())
@@ -60,13 +64,13 @@
void etk_object_shutdown();
void etk_object_purge();
-Etk_Type *etk_object_type_get();
+Etk_Type *etk_object_type_get();
Etk_Object *etk_object_new(Etk_Type *object_type, const char *first_property,
...);
Etk_Object *etk_object_new_valist(Etk_Type *object_type, const char
*first_property, va_list args);
-void etk_object_destroy(Etk_Object *object);
+void etk_object_destroy(Etk_Object *object);
Etk_Object *etk_object_check_cast(Etk_Object *object, Etk_Type *type);
-Etk_Type *etk_object_object_type_get(Etk_Object *object);
+Etk_Type *etk_object_object_type_get(Etk_Object *object);
void etk_object_signal_callback_add(Etk_Object *object, Etk_Signal_Callback
*signal_callback, Etk_Bool after);
void etk_object_signal_callback_remove(Etk_Object *object, Etk_Signal_Callback
*signal_callback);
@@ -75,8 +79,8 @@
void etk_object_weak_pointer_add(Etk_Object *object, void **pointer_location);
void etk_object_weak_pointer_remove(Etk_Object *object, void
**pointer_location);
-void etk_object_data_set(Etk_Object *object, const char *key, void *value);
-void etk_object_data_set_full(Etk_Object *object, const char *key, void
*value, void (*free_cb)(void *data));
+void etk_object_data_set(Etk_Object *object, const char *key, void *value);
+void etk_object_data_set_full(Etk_Object *object, const char *key, void
*value, void (*free_cb)(void *data));
void *etk_object_data_get(Etk_Object *object, const char *key);
void etk_object_property_reset(Etk_Object *object, const char *property_name);
@@ -86,8 +90,8 @@
void etk_object_properties_get_valist(Etk_Object *object, const char
*first_property, va_list args);
Etk_Object *etk_object_notify(Etk_Object *object, const char *property_name);
-void etk_object_notification_callback_add(Etk_Object *object, const char
*property_name, void (*callback)(Etk_Object *object, const char *property_name,
void *data), void *data);
-void etk_object_notification_callback_remove(Etk_Object *object, const char
*property_name, void (*callback)(Etk_Object *object, const char *property_name,
void *data));
+void etk_object_notification_callback_add(Etk_Object *object, const
char *property_name, void (*callback)(Etk_Object *object, const char
*property_name, void *data), void *data);
+void etk_object_notification_callback_remove(Etk_Object *object, const
char *property_name, void (*callback)(Etk_Object *object, const char
*property_name, void *data));
/** @} */
===================================================================
RCS file: /cvs/e/e17/proto/etk/src/lib/etk_property.h,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -3 -r1.6 -r1.7
--- etk_property.h 15 Aug 2006 20:20:43 -0000 1.6
+++ etk_property.h 18 Aug 2006 21:59:51 -0000 1.7
@@ -38,12 +38,12 @@
*/
typedef enum Etk_Property_Flags
{
- ETK_PROPERTY_NO_ACCESS = 0, /**< Used when the property type is
ETK_PROPERTY_OTHER */
- ETK_PROPERTY_READABLE = 1 << 0, /**< The value of the property is
readable */
- ETK_PROPERTY_WRITABLE = 1 << 1, /**< The value of the property is
writable */
+ ETK_PROPERTY_NO_ACCESS = 1 << 0, /**< Used when the property type is
ETK_PROPERTY_OTHER */
+ ETK_PROPERTY_READABLE = 1 << 1, /**< The value of the property is
readable */
+ ETK_PROPERTY_WRITABLE = 1 << 2, /**< The value of the property is
writable */
ETK_PROPERTY_READABLE_WRITABLE = /**< The value of the property is
readable and writable */
ETK_PROPERTY_READABLE | ETK_PROPERTY_WRITABLE,
- ETK_PROPERTY_CONSTRUCT = 1 << 2 /**< Use this flag to force the
default value of the property to be set when
+ ETK_PROPERTY_CONSTRUCT = 1 << 3 /**< Use this flag to force the
default value of the property to be set when
* the object is created */
} Etk_Property_Flags;
-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
_______________________________________________
enlightenment-cvs mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/enlightenment-cvs