fail_if(ret);
fail_if(pd->cb_count != 0);
+
+ /* Freeze/thaw. */
+ int fcount = 0;
+ cb_count = 0;
+ eo_do(obj, eo_event_callback_priority_add(EV_A_CHANGED, EO_CALLBACK_PRIORITY_BEFORE, _a_changed_cb, (void *) 1));
+ fail_if(pd->cb_count != 1);
+
+ eo_do(obj, eo_event_freeze_get(&fcount));
+ fail_if(fcount != 0);
+
+ eo_do(obj, eo_event_freeze());
+ eo_do(obj, eo_event_freeze_get(&fcount));
+ fail_if(fcount != 1);
+
+ eo_do(obj, eo_event_freeze());
+ eo_do(obj, eo_event_freeze_get(&fcount));
+ fail_if(fcount != 2);
+
+ eo_do(obj, eo_event_callback_priority_add(EV_A_CHANGED, EO_CALLBACK_PRIORITY_BEFORE, _a_changed_cb, (void *) 2));
+ fail_if(pd->cb_count != 1);
+
+ eo_do(obj, simple_a_set(2));
+ fail_if(cb_count != 0);
+ eo_do(obj, eo_event_thaw());
+ eo_do(obj, eo_event_freeze_get(&fcount));
+ fail_if(fcount != 1);
+
+ eo_do(obj, eo_event_thaw());
+ eo_do(obj, eo_event_freeze_get(&fcount));
+ fail_if(fcount != 0);
+
+ eo_do(obj, simple_a_set(3));
+ fail_if(cb_count != 2);
+
+ cb_count = 0;
+ eo_do(obj, eo_event_thaw());
+ eo_do(obj, eo_event_freeze_get(&fcount));
+ fail_if(fcount != 0);
+
+ eo_do(obj, eo_event_freeze());
+ eo_do(obj, eo_event_freeze_get(&fcount));
+ fail_if(fcount != 1);
+
+ eo_do(obj, simple_a_set(2));
+ fail_if(cb_count != 0);
+ eo_do(obj, eo_event_thaw());
+ eo_do(obj, eo_event_freeze_get(&fcount));
+ fail_if(fcount != 0);
+
+ eo_do(obj, eo_event_callback_del_lazy(EV_A_CHANGED, _a_changed_cb, &ret));
+ fail_if(!ret);
+ eo_do(obj, eo_event_callback_del_lazy(EV_A_CHANGED, _a_changed_cb, &ret));
+ fail_if(!ret);
+ eo_do(obj, eo_event_callback_del_lazy(EV_A_CHANGED, _a_changed_cb, &ret));
+ fail_if(ret);
+
+ /* Global Freeze/thaw. */
+ fcount = 0;
+ cb_count = 0;
+ pd->cb_count = 0;
+ eo_do(obj, eo_event_callback_priority_add(EV_A_CHANGED, EO_CALLBACK_PRIORITY_BEFORE, _a_changed_cb, (void *) 1));
+ fail_if(pd->cb_count != 1);
+
+ eo_class_do(EO_BASE_CLASS, eo_event_global_freeze_get(&fcount));
+ fail_if(fcount != 0);
+
+ eo_class_do(EO_BASE_CLASS, eo_event_global_freeze());
+ eo_class_do(EO_BASE_CLASS, eo_event_global_freeze_get(&fcount));
+ fail_if(fcount != 1);
+
+ eo_class_do(EO_BASE_CLASS, eo_event_global_freeze());
+ eo_class_do(EO_BASE_CLASS, eo_event_global_freeze_get(&fcount));
+ fail_if(fcount != 2);
+
+ eo_do(obj, eo_event_callback_priority_add(EV_A_CHANGED, EO_CALLBACK_PRIORITY_BEFORE, _a_changed_cb, (void *) 2));
+ fail_if(pd->cb_count != 1);
+
+ eo_do(obj, simple_a_set(2));
+ fail_if(cb_count != 0);
+ eo_class_do(EO_BASE_CLASS, eo_event_global_thaw());
+ eo_class_do(EO_BASE_CLASS, eo_event_global_freeze_get(&fcount));
+ fail_if(fcount != 1);
+
+ eo_class_do(EO_BASE_CLASS, eo_event_global_thaw());
+ eo_class_do(EO_BASE_CLASS, eo_event_global_freeze_get(&fcount));
+ fail_if(fcount != 0);
+
+ eo_do(obj, simple_a_set(3));
+ fail_if(cb_count != 2);
+
+ cb_count = 0;
+ eo_class_do(EO_BASE_CLASS, eo_event_global_thaw());
+ eo_class_do(EO_BASE_CLASS, eo_event_global_freeze_get(&fcount));
+ fail_if(fcount != 0);
+
+ eo_class_do(EO_BASE_CLASS, eo_event_global_freeze());
+ eo_class_do(EO_BASE_CLASS, eo_event_global_freeze_get(&fcount));
+ fail_if(fcount != 1);
+
+ eo_do(obj, simple_a_set(2));
+ fail_if(cb_count != 0);
+ eo_class_do(EO_BASE_CLASS, eo_event_global_thaw());
+ eo_class_do(EO_BASE_CLASS, eo_event_global_freeze_get(&fcount));
+ fail_if(fcount != 0);
+
+
eo_unref(obj);
eo_shutdown();
return 0;
EO_BASE_SUB_ID_EVENT_CALLBACK_CALL,
EO_BASE_SUB_ID_EVENT_CALLBACK_FORWARDER_ADD,
EO_BASE_SUB_ID_EVENT_CALLBACK_FORWARDER_DEL,
+ EO_BASE_SUB_ID_EVENT_FREEZE,
+ EO_BASE_SUB_ID_EVENT_THAW,
+ EO_BASE_SUB_ID_EVENT_FREEZE_GET,
+ EO_BASE_SUB_ID_EVENT_GLOBAL_FREEZE,
+ EO_BASE_SUB_ID_EVENT_GLOBAL_THAW,
+ EO_BASE_SUB_ID_EVENT_GLOBAL_FREEZE_GET,
EO_BASE_SUB_ID_LAST
};
#define eo_event_callback_forwarder_del(desc, new_obj) EO_BASE_ID(EO_BASE_SUB_ID_EVENT_CALLBACK_FORWARDER_DEL), EO_TYPECHECK(const Eo_Event_Description *, desc), EO_TYPECHECK(Eo *, new_obj)
/**
+ * @def eo_event_freeze
+ * @brief freeze events of object.
+ *
+ * Prevents event callbacks from being called for the object.
+ *
+ * @see #eo_event_thaw
+ */
+#define eo_event_freeze() EO_BASE_ID(EO_BASE_SUB_ID_EVENT_FREEZE)
+
+/**
+ * @def eo_event_thaw
+ * @brief thaw events of object.
+ *
+ * Lets event callbacks be called for the object.
+ *
+ * @see #eo_event_freeze
+ */
+#define eo_event_thaw() EO_BASE_ID(EO_BASE_SUB_ID_EVENT_THAW)
+
+/**
+ * @def eo_event_freeze_get
+ * @brief return freeze events of object.
+ *
+ * @param fcount[out] The event freeze count of the object.
+ *
+ * Return event freeze count.
+ *
+ * @see #eo_event_freeze
+ * @see #eo_event_thaw
+ */
+#define eo_event_freeze_get(fcount) EO_BASE_ID(EO_BASE_SUB_ID_EVENT_FREEZE_GET), EO_TYPECHECK(int *, fcount)
+
+/**
+ * @def eo_event_global_freeze
+ * @brief freeze events of object.
+ *
+ * Prevents event callbacks from being called for the object.
+ *
+ * @see #eo_event_freeze
+ * @see #eo_event_global_thaw
+ */
+#define eo_event_global_freeze() EO_BASE_ID(EO_BASE_SUB_ID_EVENT_GLOBAL_FREEZE)
+
+/**
+ * @def eo_event_global_thaw
+ * @brief thaw events of object.
+ *
+ * Lets event callbacks be called for the object.
+ *
+ * @see #eo_event_thaw
+ * @see #eo_event_global_freeze
+ */
+#define eo_event_global_thaw() EO_BASE_ID(EO_BASE_SUB_ID_EVENT_GLOBAL_THAW)
+
+/**
+ * @def eo_event_global_freeze_get
+ * @brief return freeze events of object.
+ *
+ * @param fcount[out] The event freeze count of the object.
+ *
+ * Return event freeze count.
+ *
+ * @see #eo_event_freeze_get
+ * @see #eo_event_global_freeze
+ * @see #eo_event_global_thaw
+ */
+#define eo_event_global_freeze_get(fcount) EO_BASE_ID(EO_BASE_SUB_ID_EVENT_GLOBAL_FREEZE_GET), EO_TYPECHECK(int *, fcount)
+
+/**
* @def eo_event_callback_add(obj, desc, cb, data)
* Add a callback for an event.
* @param desc[in] The description of the event to listen to.
EAPI Eo_Op EO_BASE_BASE_ID = EO_NOOP;
+static int event_freeze_count = 0;
+
typedef struct
{
Eina_Inlist *generic_data;
Eina_Inlist *callbacks;
int walking_list;
+ int event_freeze_count;
} Private_Data;
typedef struct
if (ret) *ret = EINA_TRUE;
+ if (event_freeze_count || pd->event_freeze_count)
+ return;
+
/* FIXME: Change eo_ref to _eo_ref and unref. */
eo_ref(obj);
pd->walking_list++;
eo_do(obj, eo_event_callback_del(desc, _eo_event_forwarder_callback, new_obj));
}
+static void
+_ev_freeze(Eo *obj EINA_UNUSED, void *class_data, va_list *list EINA_UNUSED)
+{
+ Private_Data *pd = (Private_Data *) class_data;
+ pd->event_freeze_count++;
+}
+
+static void
+_ev_thaw(Eo *obj, void *class_data, va_list *list EINA_UNUSED)
+{
+ Private_Data *pd = (Private_Data *) class_data;
+ if (pd->event_freeze_count > 0)
+ {
+ pd->event_freeze_count--;
+ }
+ else
+ {
+ ERR("Events for object %p have already been thawed.", obj);
+ }
+}
+
+static void
+_ev_freeze_get(const Eo *obj EINA_UNUSED, const void *class_data, va_list *list)
+{
+ Private_Data *pd = (Private_Data *) class_data;
+ int *ret = va_arg(*list, int *);
+ *ret = pd->event_freeze_count;
+}
+
+static void
+_ev_global_freeze(const Eo_Class *klass EINA_UNUSED, va_list *list EINA_UNUSED)
+{
+ event_freeze_count++;
+}
+
+static void
+_ev_global_thaw(const Eo_Class *klass EINA_UNUSED, va_list *list EINA_UNUSED)
+{
+ if (event_freeze_count > 0)
+ {
+ event_freeze_count--;
+ }
+ else
+ {
+ ERR("Global events have already been thawed.");
+ }
+}
+
+static void
+_ev_global_freeze_get(const Eo_Class *klass EINA_UNUSED, va_list *list)
+{
+ int *ret = va_arg(*list, int *);
+ *ret = event_freeze_count;
+}
+
+
/* EOF event callbacks */
static void
_class_constructor(Eo_Class *klass)
{
+ event_freeze_count = 0;
+
const Eo_Op_Func_Description func_desc[] = {
EO_OP_FUNC(EO_BASE_ID(EO_BASE_SUB_ID_DATA_SET), _data_set),
EO_OP_FUNC_CONST(EO_BASE_ID(EO_BASE_SUB_ID_DATA_GET), _data_get),
EO_OP_FUNC_CONST(EO_BASE_ID(EO_BASE_SUB_ID_EVENT_CALLBACK_CALL), _ev_cb_call),
EO_OP_FUNC(EO_BASE_ID(EO_BASE_SUB_ID_EVENT_CALLBACK_FORWARDER_ADD), _ev_cb_forwarder_add),
EO_OP_FUNC(EO_BASE_ID(EO_BASE_SUB_ID_EVENT_CALLBACK_FORWARDER_DEL), _ev_cb_forwarder_del),
+ EO_OP_FUNC(EO_BASE_ID(EO_BASE_SUB_ID_EVENT_FREEZE), _ev_freeze),
+ EO_OP_FUNC(EO_BASE_ID(EO_BASE_SUB_ID_EVENT_THAW), _ev_thaw),
+ EO_OP_FUNC_CONST(EO_BASE_ID(EO_BASE_SUB_ID_EVENT_FREEZE_GET), _ev_freeze_get),
+ EO_OP_FUNC_CLASS(EO_BASE_ID(EO_BASE_SUB_ID_EVENT_GLOBAL_FREEZE), _ev_global_freeze),
+ EO_OP_FUNC_CLASS(EO_BASE_ID(EO_BASE_SUB_ID_EVENT_GLOBAL_THAW), _ev_global_thaw),
+ EO_OP_FUNC_CLASS(EO_BASE_ID(EO_BASE_SUB_ID_EVENT_GLOBAL_FREEZE_GET), _ev_global_freeze_get),
EO_OP_FUNC_SENTINEL
};
EO_OP_DESCRIPTION_CONST(EO_BASE_SUB_ID_EVENT_CALLBACK_CALL, "?", "Call the event callbacks for an event."),
EO_OP_DESCRIPTION(EO_BASE_SUB_ID_EVENT_CALLBACK_FORWARDER_ADD, "?", "Add an event forwarder."),
EO_OP_DESCRIPTION(EO_BASE_SUB_ID_EVENT_CALLBACK_FORWARDER_DEL, "?", "Delete an event forwarder."),
+ EO_OP_DESCRIPTION(EO_BASE_SUB_ID_EVENT_FREEZE, "?", "Freezes events."),
+ EO_OP_DESCRIPTION(EO_BASE_SUB_ID_EVENT_THAW, "?", "Thaws events."),
+ EO_OP_DESCRIPTION_CONST(EO_BASE_SUB_ID_EVENT_FREEZE_GET, "?", "Get event freeze counter."),
+ EO_OP_DESCRIPTION_CLASS(EO_BASE_SUB_ID_EVENT_GLOBAL_FREEZE, "?", "Freezes events globally."),
+ EO_OP_DESCRIPTION_CLASS(EO_BASE_SUB_ID_EVENT_GLOBAL_THAW, "?", "Thaws events globally."),
+ EO_OP_DESCRIPTION_CLASS(EO_BASE_SUB_ID_EVENT_GLOBAL_FREEZE_GET, "?", "Get global event freeze counter."),
EO_OP_DESCRIPTION_SENTINEL
};